ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UI自动化框架搭建(五): selenium封装类解析

2020-12-17 14:03:30  阅读:277  来源: 互联网

标签:loc 封装 selenium self driver element UI text method


上面4个小节就是基本UI自动化框架了

后续小节围绕框架做细节分析

UI自动化最重要的一点就是定位元素,所以第一个分析的是selenium封装类,也就是上文中提到的webdriver_base.py。

元素定位方法参考 https://www.cnblogs.com/eastonliu/p/9088301.html

接下来根据selenium源码来看下定位元素实现原理

一、selenium定位元素源码

主要讲下面5种常见的定位方法

1、id定位: find_element_by_id()

2、name定位: find_element_by_name()

3、class定位:find_element_by_class_name()

4、xpath定位:find_element_by_xpath()

5、CSS定位:find_element_by_css_selector()

 

首先大家可以在点击进去看看他们调用的会是同一个方法(下图展示了id和xpath)

 

 

 

接着点击find_element方法看看具体实现(实现代码见下图)

当使用id、name、class定位时,实际上selenium只是对value做了处理,还是通过css来定位(所以实际上selenium页面元素定位分xpath和css定位两块)

 

 

 

最后看看我们封装类具体实现元素定位

(1)、封装类find_element方法是调用selenium的find_element方法,并且在调用基础上多了一些验证

lambda driver: driver.find_element(*loc).is_displayed() 页面存在一些隐藏属性,可以通过该条语句获取
WebDriverWait(self.driver, 10).until 页面隐形等待10s,10s内查找不到则抛元素查找超时异常

 

 

 

(2)、定位完后主要的操作是输入文本和点击

输入文本:封装类send_keys方法是调用selenium的send_keys方法,并且在调用基础上多了输入框文本情况和异常捕获并截图

点击:封装类click方法是调用selenium的click方法,并且在调用基础上多了异常捕获并截图

 

 

 (3)、为了方便元素定位,封装类定位元素设置统一入口loc_method方法,只需要调用loc_method,上面的元素定位方法都可以间接调用到

该方法4个参数

param eleLoc: 定位的元素路径 也就是id,xpath,css定位元素对应的路径
param action: 页面动作(输入文本,点击等等,可以自己扩展)
param method: 定位方式 目前支持CSS、XPATH、ID、NAME、CLASS(可以自己扩展),默认为CSS
param text: 如果是需要文本信息输入校验,才需要用到

 举例:

百度输入框原先        driver.find_element_by_id("kw").send_keys("懒勺")

封装类后                   loc_method("kw", "send_keys", method='id', text="懒勺")

百度点击搜索原先    driver.find_element_by_id("su").click()

封装类后                  loc_method("su", "click", method='id')

    def loc_method(self, eleLoc, action, method='CSS', text=None):
        """
        通用元素定位方法主入口
        :param eleLoc: 定位的元素路径
        :param action: 页面动作(输入文本,点击等等)
        :param method: 定位方式(css, path)提示:id、name、class属性都可以用css定位到,默认为CSS
        :param text: 如果是需要文本信息输入校验,才需要用到
        :return:
        """

        #loc放到selenium的driver.find_element方法就会自动识别元素
        if str(method).upper() == 'CSS':
            loc = (By.CSS_SELECTOR, eleLoc)
        elif str(method).upper() == 'XPATH':
            loc = (By.XPATH, eleLoc)
        elif str(method).upper() == 'ID':
            loc = (By.ID, eleLoc)
        elif str(method).upper() == 'NAME':
            loc = (By.NAME, eleLoc)
        elif str(method).upper() == 'CLASS':
            loc = (By.CLASS_NAME, eleLoc)
        else:
            loc = None

        try:
            if loc != None:
                if action == 'click':
                    self.click(loc)
                elif action == 'send_keys':
                    self.send_keys(text, loc)
                elif action == 'select_by_text':
                    self.select_by_text(text, loc)
                elif action == 'select_by_index':
                    self.select_by_index(text, loc)
                elif action == 'select_by_value':
                    self.select_by_value(text, loc)
                elif action == 'get_element_text':
                    return self.get_element_text(loc)
                elif action == 'get_element_attribute':
                    return self.get_element_attribute(text, loc)
                elif action == 'text_in_element':
                    return self.text_in_element(text, loc)
                elif action == 'value_in_element':
                    return self.value_in_element(text, loc)
                else:
                    logger.error("action错误:请确认action值:%s" % action)
            else:
                logger.error("method错误:请确认method值:%s" % method)
        except Exception as e:
            logger.error(e)

 

二、封装类初始化方法:

1、判断获取是否已经打开浏览器驱动,已经存在则不在创建新浏览器驱动,防止打开多个浏览器界面

2、获取驱动目前只写了谷歌,可在else里面扩展火狐,IE

    def __init__(self):
        global driver
        # 如果driver不为空,直接使用原来的driver
        if driver !=  None:
            self.driver = driver
            return

        # 获取驱动
        chromeDriverPath = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'driver',
                                             'chromedriver.exe')
        option = webdriver.ChromeOptions()
        option.add_argument("disable-infobars")
        # 获取配置文件
        sysConfig = YamlUtil('sysconfig.yaml').read_yaml()
        # 找浏览器的名字
        browserName = sysConfig['browser']['browserName']
        if str(browserName).lower() == 'chrome':
            # 获取谷歌的驱动
            driver = webdriver.Chrome(executable_path=chromeDriverPath, chrome_options=option)
            self.driver = driver
        else:
            logger.error("暂不支持谷歌以外的驱动")
            raise Exception("暂不支持谷歌以外的驱动")

        if self.driver == None:
            logger.error("打开浏览器驱动失败")
            raise Exception("打开浏览器驱动失败")

        self.maximize_window()

三、封装类其他页面操作方法

主要列几个常用的(其他方法也都以注释)

1、下拉框操作     select_by_index、select_by_value

2、切换窗口      switch_to_next_window、switch_to_next_frame

3、执行js脚本    execute_script

4、退出浏览器    quit_browser

    def select_by_index(self, index, *loc):
        # 通过index 下标取select
        ele = self.find_element(*loc)
        Select(ele).select_by_index(index)
        sleep(1)

    def select_by_value(self, value, *loc):
        # 通过value值取select
        ele = self.find_element(*loc)
        Select(ele).select_by_value(value)
        sleep(1)

    def switch_to_next_window(self, currentHandle):
        # 当打开的窗口不是当前窗口,就切换
        allHandles = self.driver.window_handles
        for handle in allHandles:
            if handle != currentHandle:
                self.driver.switch_to.window(handle)
                break

    def switch_to_next_frame(self, iframe):
        # 表单切换到iframe,其中iframe是id
        self.driver.switch_to.frame(iframe)

    def execute_script(self, js):
        #执行js命令
        self.driver.execute_script(js)
        
    def quit_browser(self):
        # 退出浏览器,关闭所有窗口
        self.driver.quit()

标签:loc,封装,selenium,self,driver,element,UI,text,method
来源: https://www.cnblogs.com/heng-xin/p/14147844.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有