首页 > 其他分享 >web自动化框架basepage

web自动化框架basepage

时间:2024-04-29 13:46:07浏览次数:16  
标签:web self 元素 param element locator 自动化 basepage model

# -*- coding: utf-8 -*-
# @Author  : caiweichao
# @explain : 基类封装webdriver方法,方便调用,减少代码重复
import random
import time

import allure
from selenium import webdriver
from selenium.common.exceptions import *
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait

from Commons.util.log_process import LogProcess
from Commons.util.logs import Log
from Commons.operation_file.operation_ymal import ReadYaml
from Commons.util.return_time import ReturnTime


class BasicPage:
    # 图片文件夹路径
    __img_dir = LogProcess().get_log_dir()[1]
    conf: dict = ReadYaml().get_every_config("Config")

    def __init__(self, driver):
        self.driver: webdriver.Chrome = driver
        self.wait: WebDriverWait = WebDriverWait(self.driver, timeout=self.conf.get("WAIT_ELEMENT"),
                                                 poll_frequency=self.conf.get("POLL_ELEMENT"))

    def get_url(self, url: str) -> None:
        """
        进入指定连接
        :param url: 链接地址
        :return: None
        """
        self.driver.get(url=url)

    def get_current_url_path(self) -> str:
        """
        获取当前页面的url的路径
        :return: url路径
        """
        current_url = self.driver.current_url
        return current_url

    def set_img_error(self) -> None:
        """
        用例执行失败截图,并且加入allure测试报告中
        :return: 无返回值
        """
        # 获取图片存储的文件夹
        __time_tag = ReturnTime.get_Timestamp()
        __img_path = self.__img_dir + f"/{__time_tag}.png"
        try:
            # 进行截图
            self.driver.save_screenshot(filename=__img_path)
            Log.error(f"截图成功文件名称为:{__time_tag}.png")
            __file = open(__img_path, "rb").read()
            allure.attach(__file, "用例执行失败截图", allure.attachment_type.PNG)
        except Exception as e:
            Log.error(f"执行失败截图未能正确添加进入测试报告:{e}")
            raise e

    def set_img_case(self) -> None:
        """
        用例执行完毕截图,并且将截图加入allure测试报告中
        :return: 无返回值
        """
        with allure.step("关键步骤截图"):
            __img_name = ReturnTime.get_Timestamp()
            __img_path = self.__img_dir + f"/{__img_name}.png"
            try:
                # 截图前等待1秒防止图片没有正常加载
                time.sleep(1)
                self.driver.save_screenshot(filename=__img_path)
                Log.debug(f"用例执行完成,截图成功,文件名称为{__img_name}.png")
                # 读取图片信息
                __file = open(file=__img_path, mode="rb").read()
                allure.attach(__file, "关键步骤截图", allure.attachment_type.PNG)
            except Exception as e:
                Log.error(f"测试结果截图,未能正确添加进入测试报告:{e}")
                raise e

    def element_dyeing(self, element) -> None:
        """
        将被操作的元素染色
        :rollback: 是否将元素回滚
        :return: None
        """
        try:
            self.driver.execute_script(
                "arguments[0].setAttribute('style', 'background: yellow; border: 2px solid red;');",
                element)
        except Exception as e:
            Log.info(f"无法染色染色失效:{e}")
            pass

    def __wait_element_visible(self, model: str, locator: tuple) -> None:
        """
        等待元素可见
        :param model: 元素所处的页面
        :param locator: 元素定位表达式
        :return: 无返回值
        """
        Log.debug(f"-开始-等待页面{model}的元素:{locator}可见")
        try:
            # 获取等待开始时间的时间戳
            __start_time = ReturnTime.get_Timestamp()
            self.wait.until(ec.visibility_of_element_located(locator))
            # 计算元素等待的时间
            __wait_time = ReturnTime.get_Timestamp() - __start_time
            Log.debug(f"页面:{model}上的元素{locator}已可见,共计等待{__wait_time:0.2f}秒")
        except TimeoutException:
            Log.error(f"页面:{model},等待元素{locator}超时")
            self.set_img_error()
            raise TimeoutException('元素等待超时')
        except InvalidSelectorException as e:
            Log.error(f"页面:{model},元素不可见或定位表达式:{locator}异常\n {e}")
            raise InvalidSelectorException('元素定位异常')

    def __wait_element_clickable(self, model: str, locator: tuple) -> None:
        """
        等待元素点击
        :param model: 元素所处的页面
        :param locator: 元素定位表达式
        :return: 无返回值
        """
        Log.debug(f"-开始-等待页面{model}的元素:{locator}可点击")
        try:
            # 获取等待开始时间的时间戳
            __start_time = ReturnTime.get_Timestamp()
            self.wait.until(ec.element_to_be_clickable(locator))
            # 计算元素等待的时间
            __wait_time = ReturnTime.get_Timestamp() - __start_time
            Log.debug(f"页面:{model}上的元素{locator}已可点击,共计等待{__wait_time:0.2f}秒")
        except TimeoutException as e:
            Log.error(f"页面:{model},等待元素{locator}超时")
            self.set_img_error()
            raise e
        except InvalidSelectorException as e:
            Log.error(f"页面:{model},元素不可点击或定位表达式:{locator}异常\n {e}")
            raise e

    def __wait_element_exit(self, model: str, locator: tuple) -> None:
        """
        等待元素存在
        :param model: 元素所处的页面
        :param locator: 元素定位表达式
        :return: 无返回值
        """
        Log.debug(f"-开始-等待页面{model}的元素:{locator}存在")
        try:
            # 获取等待开始时间的时间戳
            __start_time = ReturnTime.get_Timestamp()
            self.wait.until(ec.presence_of_element_located(locator))
            # 计算元素等待的时间
            __wait_time = ReturnTime.get_Timestamp() - __start_time
            Log.debug(f"页面:{model}上的元素{locator}已存在,共计等待{__wait_time:0.2f}秒")
        except TimeoutException as e:
            Log.error(f"页面:{model},等待元素{locator}超时")
            self.set_img_error()
            raise e
        except InvalidSelectorException as e:
            Log.error(f"页面:{model},元素不存在或定位表达式:{locator}异常\n {e}")
            raise e

    def wait_element_not_visible(self, model: str, locator: tuple) -> None:
        """
        等待元素不可见
        :param model: 元素所处的页面
        :param locator: 元素定位表达式
        :return: 无返回值
        """
        Log.debug(f"-开始-等待页面{model}的元素:{locator}存在")
        try:
            # 获取等待开始时间的时间戳
            __start_time = ReturnTime.get_Timestamp()
            time.sleep(1)
            self.wait.until(ec.invisibility_of_element_located(locator))
            # 计算元素等待的时间
            __wait_time = ReturnTime.get_Timestamp() - __start_time
            Log.debug(f"页面:{model}上的元素{locator}已经不可见,共计等待{__wait_time:0.2f}秒")
        except TimeoutException as e:
            Log.error(f"页面:{model},等待元素{locator}不可见超时")
            self.set_img_error()
            raise e
        except InvalidSelectorException as e:
            Log.error(f"页面:{model},元素不存在或定位表达式:{locator}异常\n {e}")
            raise e

    def __select_wait_method(self, model: str, locator: tuple, mode: str = "visible") -> None:
        """
        选择元素定位的等待方式
        :param model: 传参定位的是哪个页面 字符串形式
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param mode: visible(元素可见), exist(元素存在),click(元素可点击)
        :return: 无返回值
        """
        if mode == "visible":
            self.__wait_element_visible(model=model, locator=locator)
        elif mode == "exist":
            self.__wait_element_exit(model=model, locator=locator)
        elif mode == "click":
            self.__wait_element_clickable(model=model, locator=locator)
        else:
            Log.error(f"定位{model}页面的元素:{locator},mode参数传值异常,入参值为:{mode}")

    def find_element(self, locator: tuple, mode: str = "visible", model: str = None) -> WebElement:
        """
        定位元素,支持所有定位单个元素的定位表达式
        :param model: 传参定位的是哪个页面 字符串形式
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param mode: visible(元素可见), exist(元素存在)
        :return: 定位到的元素对象
        """
        self.__select_wait_method(model=model, locator=locator, mode=mode)
        try:
            Log.debug(f"正在定位{model}页面的: {locator} 的元素")
            element = self.driver.find_element(*locator)
            self.element_dyeing(element=element)
            return element
        except TimeoutException:
            Log.error(f"页面:{model},定位元素:{locator}定位超时")
            self.set_img_error()
            raise TimeoutException("元素定位超时请检查")
        except Exception:
            Log.error(f"页面:{model},定位元素:{locator}定位失败")
            self.set_img_error()
            raise Exception("元素定位失败请检查")

    def find_elements(self, locator: tuple, mode: str = "visible") -> list:
        """
        定位一组元素,返回一个列表
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param mode: visible(元素可见),notvisible(元素消失不可见), exist(元素存在)
        :return: 返回一组元素是一个列表
        """
        model = self.get_current_url_path()
        self.__select_wait_method(model=model, locator=locator, mode=mode)
        try:
            Log.debug(f"正在定位{model}页面的: {locator} 的元素")
            element_list = self.driver.find_elements(*locator)
            return element_list
        except Exception as e:
            Log.error(f"页面:{model},定位元素:{locator}定位失败")
            self.set_img_error()
            raise e

    def __move_element_visible(self, model: str, locator: tuple, element: WebElement, alignment: bool = False) -> None:
        """
         将元素移动到页面可见区域
        :param model: 传参定位的是哪个页面 字符串形式
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param alignment 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param element 需要可见的元素
        :return: 无返回值
        """
        Log.debug(f'将{model}页面的元素:{locator}移动至浏览器可见区域')
        try:
            # 代码执行比页面渲染速度快 这里放0.5秒等待页面渲染
            time.sleep(0.5)
            self.driver.execute_script('arguments[0].scrollIntoView({0});'.format(alignment), element)
            # 休眠1秒让页面可以正常滚动到对应的位置再执行下去
            time.sleep(1)
        except Exception as e:
            Log.error(f"{model}页面的元素:{locator}移动失败\n{e}")
            self.set_img_error()
            raise e

    def click_element(self, locator: tuple, mode: str = "click", alignment: bool = False, move_elemnet: bool = False,
                      is_double_click: bool = False) -> None:
        """
        点击元素
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param mode: visible(元素可见),notvisible(元素消失不可见), exist(元素存在),click(元素可点击)
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :param is_double_click: False单击元素,传入True 双击元素
        :return: 无返回值
        """
        model = self.get_current_url_path()
        element = self.find_element(model=model, locator=locator, mode=mode)
        if move_elemnet is True:
            self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
        try:
            Log.debug(f"点击:{model}页面,属性为{locator}的元素")
            if is_double_click:
                ActionChains(self.driver).double_click(element).perform()
            else:
                element.click()
        except Exception as e:
            Log.error(f"页面{model}的元素: {locator} 点击失败")
            self.set_img_error()
            raise e

    def click_elements(self, locator: tuple, mode: str = "click", alignment: bool = False, move_elemnet: bool = False,
                       is_double_click: bool = False) -> None:
        """
        点击一组元素
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param mode: visible(元素可见),notvisible(元素消失不可见), exist(元素存在),click(元素可点击)
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :param is_double_click: False单击元素,传入True 双击元素
        :return: 无返回值
        """
        model = self.get_current_url_path()
        elements = self.find_elements(locator=locator, mode=mode)
        if move_elemnet is True:
            self.__move_element_visible(model=model, locator=locator, element=elements[0], alignment=alignment)
        try:
            Log.debug(f"点击:{model}页面,属性为{locator}的元素")
            for element in elements:
                if is_double_click:
                    ActionChains(self.driver).double_click(element).perform()
                else:
                    element.click()
        except Exception as e:
            Log.error(f"页面{model}的元素: {locator} 点击失败")
            self.set_img_error()
            raise e

    def random_click_element(self, locator: tuple, num: int, mode: str = "click", alignment: bool = False,
                             move_elemnet: bool = False) -> str:
        """
        随机点击一个元素
        :param locator: 元素的定位表达式 例:(By.xx,'定位表达式')
        :param num: 从第几位元素开始点击
        :param mode: visible(元素可见), exist(元素存在),click(元素可点击)
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :return: 点击的元素的文本
        """
        model = self.get_current_url_path()
        elements = self.find_elements(locator=locator, mode=mode)
        click_num: int = random.randint(num, len(elements) - 1)
        try:
            element = elements[click_num]
            if move_elemnet is True:
                self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
            self.element_dyeing(element)
            Log.debug(f"点击:{model}页面,属性为{locator}的元素中的{click_num}位")
            element.click()
        except Exception as e:
            Log.error(f"页面{model}的元素: {locator} 中的第{click_num}位元素点击失败")
            self.set_img_error()
            raise e
        return element.text

    def input_text(self, locator: tuple, content: str or int, mode: str = "visible", alignment: bool = False,
                   move_elemnet: bool = False) -> WebElement:
        """
        输入文本内容
        :param locator: 传入元素定位表达式
        :param content: 传入输入的文本内容
        :param mode:  visible(元素可见), exist(元素存在)
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :return: 无返回值
        """
        model = self.get_current_url_path()
        element = self.find_element(model=model, locator=locator, mode=mode)
        if move_elemnet is True:
            self.__move_element_visible(model=model, locator=locator,
                                        element=element, alignment=alignment)
        try:
            Log.debug(f"输入操作:{model}页面下的属性为:{locator}的元素,输入内容为{content}")
            element.send_keys(content)
            self.driver.execute_script(
                "arguments[0].setAttribute('style', 'background: write; border: 1px solid black;');", element)
        except Exception as e:
            self.set_img_error()
            Log.error(f"页面{model}的属性: {locator} 输入操作失败")
            raise e
        return element

    def clear_contents(self, locator: tuple, mode: str = "visible", alignment: bool = False,
                       move_elemnet: bool = False) -> None:
        """
        清除文本内容
        :param locator: 传入元素定位表达式
        :param mode:  visible(元素可见), exist(元素存在)
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :return: 无返回值
        """
        model = self.get_current_url_path()
        element = self.find_element(model=model, locator=locator, mode=mode)
        if move_elemnet is True:
            self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
        try:
            Log.debug(f"输入操作:{model}页面下的属性为:{locator}的元素,清除内容")
            # 保证正常清除
            time.sleep(0.2)
            element.clear()
        except Exception as e:
            self.set_img_error()
            Log.error(f"页面{model}的属性: {locator} 清除操作失败")
            raise e

    def get_element_text(self, locator: tuple, mode: str = 'visible', alignment: bool = False,
                         move_elemnet: bool = False) -> str:
        """
        获取元素的文本内容
        :param locator:  传入元素定位表达式
        :param mode: visible(元素可见), exist(元素存在)
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :return: 返回获取到的元素文本内容
        """
        model = self.get_current_url_path()
        element = self.find_element(model=model, locator=locator, mode=mode)
        if move_elemnet is True:
            self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
        try:
            Log.debug(f"文本获取操作:获取{model}页面下的属性为:{locator}的元素的文本内容")
            return element.text
        except Exception as e:
            Log.error(f"页面{model}的元素:{locator}获取文本操作失败")
            self.set_img_error()
            raise e

    def click_radios(self, locator: tuple, method: str, amount: int = None, mode: str = 'visible',
                     alignment: bool = False, move_elemnet: bool = False) -> WebElement:
        """
        复选框内容点击
        :param locator: 传入元素定位表达式
        :param mode:  visible(元素可见), exist(元素存在)
        :param amount: 传入复选项的数量 例子如果是3个选项就传入3
        :param method: 选择对应的内容选择方式 all 点击复选框的全部内容 random 随机点击复选框的中的某一个选项 assign点击指定的某个复选项
        :param alignment: 默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        :return: 全部点击时无返回,其他返回被点击的元素
        """
        # 定位到复选框一定是一组元素
        model = self.get_current_url_path()
        elements: list[WebElement] = self.find_elements(locator=locator, mode=mode)
        try:
            Log.debug('点击方式为:{}'.format(method))
            if method == 'all':
                # 点击复选项中每一个元素
                for ele in elements:
                    if move_elemnet is True:
                        self.__move_element_visible(model=model, locator=locator, element=ele, alignment=alignment)
                    ele.click()
            # 随机点击复选项中的某一个内容
            elif method == 'random':
                # 导入随机数包
                import random
                # 生成指定范围之内的随机数作为需要点击的radio
                num = random.randint(0, amount - 1)
                element = elements[num]
                if move_elemnet is True:
                    self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
                element.click()
                # 返回被点击的元素
                return element
            # 点击复选框中指定位置的选项
            elif method == 'assign':
                # 因为从0开始计数,所以传入的 amount-1
                element = elements[amount - 1]
                if move_elemnet is True:
                    self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
                element.click()
                return element
            else:
                Log.error('点击方式输入错误,请检查')
        except Exception as e:
            Log.error(f"页面{model}的元素:{locator}复选框点击操作失败")
            self.set_img_error()
            raise e

    @staticmethod
    def element_is_selected(elenmet: WebElement):
        """
        判断元素是否勾选
        :param elenmet: 需要校验是否勾选的元素
        :return: 选中是Ture 没有选择是False
        """
        return elenmet.is_selected()

    def select_contents_menu(self, locator: tuple, text: str, mode: str = 'visible', alignment: bool = False,
                             move_elemnet: bool = False) -> None:

        """
        选择下拉菜单中的内容
        :param locator: 传入元素定位表达式
        :param text: 出入下拉列表需要选择的内容
        :param mode: visible(元素可见), exist(元素存在)
        :param alignment:  默认对其方式是元素和当前页面的底部对齐,可以传 alignment=''表示和顶部对齐
        :param move_elemnet: 这里是布尔值 传入True 表示需要让元素滚动到页面可见区域 False 表示不用
        """
        model = self.get_current_url_path()
        element = self.find_element(model=model, locator=locator, mode=mode)
        # 定义一个存储菜单内容的空列表
        option = []
        if move_elemnet is True:
            self.__move_element_visible(model=model, locator=locator, element=element, alignment=alignment)
        try:
            # 获取下拉列表的内容
            options = element.find_elements_by_tag_name("option")
            for value in options:
                option.append(value)
            if text in option:
                Select(element).select_by_visible_text(text)
            else:
                Log.error(f"选项:{text}不在下拉列表之中请检查")
        except Exception as e:
            self.set_img_error()
            Log.error(f"页面{model}的元素:{locator}下拉框操作失败请检查")
            raise e

    def dispose_alert(self, action: str) -> str:
        """
        处理页面alert
        :param action: 参数为 accept 点击alert的确定 dismiss点击alert的取消
        :return: 返回alert的文本内容 可能有些用例需要用这个参数去校验
        """
        # 等待alert出现再去操作
        self.wait.until(ec.alert_is_present())
        alert: Alert = self.driver.switch_to.alert
        # 尝试点击alert
        try:
            if action == 'accept':
                alert.accept()
            elif action == 'dismiss':
                alert.dismiss()
            else:
                Log.error('alert 处理参数错误请检查')
            return alert.text
        except Exception as e:
            Log.error('alert处理异常')
            raise e

    def get_handles(self):
        """
        获取当前页面的句柄
        :return: 方法返回值当前获取到的句柄值
        """
        # 获取当前页面的句柄
        handles = self.driver.window_handles
        return handles

    def swich_window(self, old_handle) -> None:
        """
        浏览器页面切换--通过切换句柄实现切换到正在使用的页面上
        :param old_handle: 传入之前获取的句柄的值
        :return: None
        """
        # 等待最新的窗口出现
        self.wait.until(ec.new_window_is_opened(old_handle))
        # 调用获取句柄的方法拿到最新打开的标签页的句柄
        new_handle = self.get_handles()
        # 切换到最新页面因为时最新所以直接使用下标 -1 就行
        self.driver.switch_to.window(new_handle[-1])

    def is_element_exist(self, locator: tuple, timeout: int = 10) -> bool:
        """
        判断单元素是否存在
        :param timeout: 默认超时时间
        :param locator: 传入元素定位表达式
        :return: 返回布尔值 true表示元素存在 false表示元素不存在
        """
        model = self.get_current_url_path()
        try:
            Log.debug(f'判断{model}页面的元素{locator}是否存在')
            WebDriverWait(self.driver, timeout=timeout, poll_frequency=0.1).until(
                ec.visibility_of_element_located(locator))
            return True
        except Exception:
            return False

    # 判断元素是否已经消失不见了
    def element_whether_invisibility(self, locator: tuple) -> bool:
        """
        判断元素是否已经消失不见了
        :param locator: 传入元素定位表达式
        :return:
        """
        model = self.get_current_url_path()
        try:
            # 主要用于处理loading页面加载完成后1秒再去判断保证被判断的元素正常展示
            # time.sleep(1)
            # 获取等待开始时间的时间戳
            __start_time = ReturnTime.get_Timestamp()
            Log.debug(f'判断{model}页面的元素{locator}是否消失了')
            WebDriverWait(self.driver, timeout=60, poll_frequency=0.1).until(
                ec.invisibility_of_element_located(locator))
            # 计算元素等待的时间
            __wait_time = ReturnTime.get_Timestamp() - __start_time
            Log.debug(f"页面:{model}上的元素{locator}已消失,共计等待{__wait_time:0.2f}秒")
            return True
        except Exception:
            return False

    def switch_ifram(self, locator: tuple) -> None:
        """
        判切换ifram,部分页面的元素在ifram里需要切换后定位
        :param locator: 传入元素定位表达式
        """
        model = self.get_current_url_path()
        try:
            Log.debug(f'切换{model}页面的ifram{locator}')
            self.driver.switch_to.frame(frame_reference=self.find_element(model=model, locator=locator))
        except Exception:
            Log.error(f'{model}页面的ifram切换失败')

    def mouse_over(self, locator: tuple, times: int) -> None:
        """
        鼠标悬停功能
        :param locator: 元素定位表达式
        :param times: 悬停N秒
        :return: None
        """
        model = self.get_current_url_path()
        element = self.find_element(model=model, locator=locator)
        ActionChains(self.driver).move_to_element(to_element=element).perform()
        time.sleep(times)

    def refresh_page(self) -> None:
        """
        刷新当前页面
        :return: None
        """
        Log.info(f"刷新页面: {self.get_current_url_path()}")
        self.driver.refresh()

  

标签:web,self,元素,param,element,locator,自动化,basepage,model
From: https://www.cnblogs.com/zwldyt/p/18165479

相关文章

  • ABAP 调用外部WEBAPI
    ABAP代码如下,仅在内部测试通过,未涉及外部网络WEBAPI及跨域调用。*&---------------------------------------------------------------------**&ReportZYC_WEBAPI*&Restfulapi测试REPORTZYC_WEBAPI.DATA:LENTYPEI,"发送报文长度LEN_STRING......
  • 《最新出炉》系列入门篇-Python+Playwright自动化测试-40-录制生成脚本
    https://www.cnblogs.com/du-hong/p/17835463.html 1.简介各种自动化框架都会有脚本录制功能,playwright这么牛叉当然也不例外。很早之前的selenium、Jmeter工具,发展到每种浏览器都有对应的录制插件。今天我们就来看下微软自动化框架playwright是如何录制脚本的。很多小伙伴或......
  • 爬虫自动化之drissionpage实现随时切换代理ip
    爬虫自动化之drissionpage实现随时切换代理iphttps://blog.csdn.net/qq_32334103/article/details/126133862下载SwitchyOmega地址:https://github.com/FelisCatus/SwitchyOmega/releases  importplatformfromDrissionPageimportChromiumPage,ChromiumOptions......
  • [转载]自述WebPPD两年半的运营经历 [2012.11.9 sina blog]
    原文地址:自述WebPPD两年半的运营经历作者:尹广磊我在07年10月接触到了AxureRP,当时还是4.6英文版,学习门槛比现在的同学可是高多了。跟所有有过一定产品设计经验的人一样,我一开始是排斥这东西的。自认为过去的Visio用得不错。但是应公司要求,原型务必反映出页面间的链接关系。仅这一......
  • FETCH JSON ERROR IN MIK-SSR-WEB
    背景在日常巡检时发现,MIK-SSR-WEB的Grafana监控中出现500的异常响应。原因分析1.Grafana监控在监控面板中发现,503响应不为0  2.Skywalkingl链路在Skywalking中过滤错误响应,发现所以异常的URL均为/mik-web-static/map/2c-prd/released-menu/michaels_menu......
  • webapi动态创建后台任务(使用排队的后台任务)
    很多时候我们都会使用后台定时任务,但有些任务不需要定时执行,只需要请求到来时执行一次,比如请求服务器到某个地方同步数据,但请求不需要等数据同步完成再响应。这时候就可以使用排队的后台任务。基本原理是用一个队列保存任务委托,然后用一个后台定时任务依次执行队列中的委托。MSD......
  • Offline web technology for Mobile devices
    一、当前问题1、弱网或断网,当用户进入电梯或无网区,长时间白屏或无法显示页面2、正常网络,从点击app到显示首页文字图片,白屏时间大约7-9秒 二、原因分析1、从技术视角,分析一下网页启动的几个关键耗时阶段 2、没有做离线化技术,而手机端用户进入弱网与无网区......
  • WEBAPI传参及默认首页设置
    开发工具:VS2017创建WEBAPI,1.选择ASP.NETCoreWeb应用程序2.选择如下,HTTPS配置勾选去掉,暂不配置3.“属性”中调试默认界面及launchsettings.json 4.调试以后默认页面 5. ......
  • 自动化测试数据生成:Asp.Net Core单元测试利器AutoFixture详解
    引言在我们之前的文章中介绍过使用Bogus生成模拟测试数据,今天来讲解一下功能更加强大自动生成测试数据的工具的库"AutoFixture"。什么是AutoFixture?AutoFixture是一个针对.NET的开源库,旨在最大程度地减少单元测试中的“安排(Arrange)”阶段,以提高可维护性。它的主要目标是让......
  • 帕鲁杯web mylove复现
    题目给了源码和phpinfo()<?phpclassa{publicfunction__get($a){$this->b->love();}}classb{publicfunction__destruct(){$tmp=$this->c->name;}publicfunction__wakeup(){$this->c="......