UI自動化框架搭建(五): selenium封裝類解析


上面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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM