栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【webui自动化】page object 设计模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【webui自动化】page object 设计模式

page object 设计模式 基类设计

遵循面对对象设计模式
base.py

from selenium import webdriver

from plugins import Single, read_yaml


class BasePage:

    def __init__(self):
        # 确保浏览器同一时间只开启一个
        self._driver = WebdriverCreator().get_browser()
        # 根据继承树读取元素配置信息--排除BasePage和object
        cls_list = [cls.__name__ for cls in self.__class__.mro()][:-2]
        print(cls_list)
        for cls in cls_list:
            locators = read_yaml('conf/ui_locators.yml')[cls]
            for k, v in locators.items():
                setattr(self, k, v)  # 批量赋值

    def click(self, locator):  # locator ['id','#email']
        self._driver.find_element(*locator).click()

    def input_text(self, locator, text):
        self._driver.find_element(*locator).send_keys(text)

    # 返回元素文本
    def ele_text(self, locator):
        return self._driver.find_element(*locator).text

    # 点击多个元素
    def click_multi(self, locators):
        eles = self._driver.find_elements(*locators)
        for ele in eles:
            ele.click()

    # 根据目标元素文本点击
    def click_by_text(self, locators, target_text):
        # 筛选出一堆元素
        eles = self._driver.find_elements(*locators)
        # 遍历元素列表判断元素的文本是否等于target_text
        for ele in eles:
            if ele.text == target_text:
                ele.click()
                break  # 点击一个就退出

    # 获取多个元素文本列表
    def eles_text(self, locators):
        eles = self._driver.find_elements(*locators)
        return [ele.text for ele in eles]

    def close_browser(self):
        self._driver.quit()

    # 当元素存在就点击
    def click_ele_exist(self, *locator):
        btns = self.driver.find_elements(*locator)
        # 假如出现用户协议弹出按钮
        if btns:
            btns[0].click()

    # 输入文本
    def input_text(self, text, *locator):
        self.driver.find_element(*locator).send_keys(text)

    # js方式点击元素
    def click_by_js(self, css):
        self.driver.execute_script(f"document.querySelector('{css}').click()")

    # 切换目标窗口
    def switch_window(self, target_title):
        for handle in self.driver.window_handles:
            self.driver.switch_to.window(handle)
            # 判断切换到目标窗口-判断当前窗口标题是否为:小米10系列立即购买-小米商城
            if target_title == self.driver.title:
                print('切换到目标窗口')
                # 进入到商品详情页
                return True

    # 获取目标元素文本
    def get_text(self, *locator):
        return self.driver.find_element(*locator).text


class WebdriverCreator(Single):
    def get_browser(self):  # 获取浏览器
        if not hasattr(self, '_driver'):
            self._driver = webdriver.Chrome()  # 会打开浏览器
            self._driver.implicitly_wait(10)
            # 设置页面加载超时时间
            self._driver.set_page_load_timeout(60)
            # 设置js执行超时时间
            self._driver.set_script_timeout(60)
        return self._driver

其他工具类

plugins.py

import functools
import os

from logging.handlers import RotatingFileHandler
from logging import Formatter
import logging


def get_logger(name,out_level,file_name):
    LOG_FORMAT = '%(asctime)s-%(levelname)s-%(message)s' #日志格式
    DATA_FORMAT = '%m/%d/%Y %H:%M:%S %p'     # 时间格式化 需要日志格式化中定义%(asctime)s
    # logger日志器同名时为单例模式
    logger = logging.getLogger(name)  # 获取日志器
    logger.setLevel(level=out_level)  #设置输出级别为debug
    # 日志模块的高级用法
    # 1.需要有个日志处理器---控制输出方向--(可以输出到文本,可以输出到控制台)
    log_handler = RotatingFileHandler(file_name,encoding='utf-8',maxBytes=1024*20) #文件名,编码,最大字节数20kb,
    # 2.需要给日志器配置输出格式,需要有个格式化对象
    formatter = Formatter(fmt=LOG_FORMAT,datefmt=DATA_FORMAT)
    log_handler.setFormatter(formatter) # 给日志处理器配置输出格式
    # 3.装配日志处理器
    if logger.handlers == []:  # 如果没有日志器再装配
        logger.addHandler(log_handler)
    return logger


# 封装日志装饰器,提供以下功能
# 1.可以自定义日志级别(定义输出和输出级别)
# 2.可以自动写日志

def logged(in_level=10,out_level=10,msg=None): #日志输入输出级别
    def decorate(func):
        @functools.wraps(func)
        def inner(*args,**kwargs):
            # 判断是否由logs目录,没有就自动创建
            if not os.path.exists('logs'):
                os.mkdir('logs')
            # 记录日志的地方
            logger = get_logger('haiwen',out_level,'logs/testdemo.log')
            # 如果输入级别小于输出级别--不会输出数据--可以给出警告
            if in_level < out_level:
                logger.warning('输入级别小于输出级别')
            # 根据msg判断是否要自动写日志
            log_msg=''
            if msg:
                #使用传递的参数作为日志信息
                log_msg=msg
            else:
                # 自动写日志信息--xxx函数 执行了
                log_msg=f'{func.__name__} 用例 执f行了'
            # 用例运行
            try:
                res = func(*args,**kwargs)
                logger.log(level=in_level,msg=log_msg) #记录正常信息
                return res
            except:
                logger.error(msg='异常信息: ',exc_info=True)     #记录异常信息-堆栈信息
        return inner
    return decorate




class Single:
    # 产生对象的是new方法
    def __new__(cls, *args, **kwargs):
        # 判断当前类有没有对象,有就直接返回,没有就创建一个再返回
        if not hasattr(cls,'_instance'):
            cls._instance = object.__new__(cls)  # 产生当前类的对象
        return cls._instance

import yaml

def read_yaml(path):
    # 读取文件
    with open(path,encoding='utf8') as f:
        content = f.read()
    # 将文件内容转成python数据格式
    return yaml.safe_load(content)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/988088.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号