unittest 運行slenium(二)---打開瀏覽器及元素操做

一: 打開win10中安裝的瀏覽器css

1. 打開的瀏覽器有:谷歌/火狐/ie/edgehtml

2. 當瀏覽器的driver沒有配置在path環境下時,在啓動瀏覽器時須要傳入driver的所在位置git

3. 其中火狐瀏覽器安裝不爲默認路徑時也須要配置說明github

4. 具體代碼以下:web

import os

from selenium import webdriver

from util_tools.storage.read_model_file import ReadModelIni

argument = ReadModelIni("system_settings.ini")
driver_path = argument.get_value("driver_browser", "driver_path")
chrome_driver = argument.get_value("driver_browser", "chrome_driver")
ie_driver = argument.get_value("driver_browser", "ie_driver")
firefox_driver = argument.get_value("driver_browser", "firefox_driver")
microsoft_driver = argument.get_value("driver_browser", "microsoft_driver")
del argument


# https://www.cnblogs.com/ppppying/p/6143658.html IE瀏覽器配置方法文章說明

class BrowserPrepare(object):
    """
    工做內容:
    1. 打開瀏覽器
    """

    def run_web_browser(self, url: str, driver_browser: str = 'chrome', wait_time: int = 5):
        """
        打開瀏覽器並進入相應的網址
        :param wait_time:
        :param url:
        :param driver_browser:
        :return:
        """
        self.open_driver_browser(driver_browser, wait_time)
        self.input_browser_url(url)

    def open_driver_browser(self, driver_browser: str = 'chrome', wait_time: int = 5):

        # 建立瀏覽器對象
        if driver_browser.capitalize() in 'Chrome':
            self.chrome_browser()
        elif driver_browser.capitalize() in 'Firefox':
            self.firefox_browser()
        elif driver_browser.capitalize() in 'Edge':
            self.edge_browser()
        else:
            self.ie_browser()
        # 瀏覽器窗口最大化,程序運行過程當中有些問題就是由於窗口沒有最大化致使的.
        self.driver.maximize_window()
        # 等待網頁加載,加載時間爲10s,加載完就跳過
        # 隱形等待時間和顯性等待時間不一樣時,默認使用二者之間最大的那個
        self.driver.implicitly_wait(wait_time)
        pass

    def input_browser_url(self, url: str):
        # 輸入網址
        self.driver.get(url)
        pass

    def close_driver_browser(self, _quit=None):
        # 關閉並退出瀏覽器
        self.driver.quit()
        pass

    def chrome_browser(self):
        """
        調用函數,實現打開谷歌瀏覽器的步驟
        :return:
        """
        self.driver = webdriver.Chrome(executable_path=os.path.join(driver_path, chrome_driver))

    def ie_browser(self):
        """
        調用函數,實現打開ie瀏覽器的步驟
        :return:
        """
        # 實現全局變量的引用
        self.driver = webdriver.Ie(executable_path=os.path.join(driver_path, ie_driver))

    def edge_browser(self):
        """
        調用函數,實現打開edge瀏覽器的步驟
        :return:
        """
        # 實現全局變量的引用
        self.driver = webdriver.Edge(executable_path=os.path.join(driver_path, microsoft_driver))

    def firefox_browser(self, options=None):
        """
        調用函數,實現打開火狐瀏覽器的步驟
        :return:
        """

        # 實現全局變量的引用,當火狐安裝路徑不爲默認路徑時(即C盤)才須要填寫firefox_bin
        firefox_bin = os.path.abspath(r"E:\Program Files\Mozilla Firefox\firefox.exe")
        os.environ["webdriver.firefox.bin"] = firefox_bin

        # 代碼加載火狐驅動
        firefox_driver_path = os.path.abspath(os.path.join(driver_path, firefox_driver))
        self.driver = webdriver.Firefox(options, executable_path=firefox_driver_path)

    def mobile_phone_mode(self):
        '''
        將谷歌瀏覽器設置爲手機模式
        :return:
        '''
        from selenium.webdriver.chrome.options import Options
        # 有效的移動設備Galaxy S5.Nexus 5X.Nexus 6P
        # mobile_emulation = {"deviceName": "iPhone 7"}

        mobile_emulation = {
            "deviceMetrics": {"width": 360, "height": 640, "pixelRatio": 3.0},
            "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1"}

        # mobile_emulation = {"browserName": "IE"}
        options = Options()
        options.add_experimental_option("mobileEmulation", mobile_emulation)
        return options

    def chrome_prefs_flash(self):
        '''
        當谷歌瀏覽器運行時,不會加載flash
        :return:
        '''
        from selenium.webdriver.chrome.options import Options

        prefs = {
            "profile.managed_default_content_settings.images": 1,
            "profile.content_settings.plugin_whitelist.adobe-flash-player": 1,
            "profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1
        }

        options = Options()
        options.add_experimental_option("prefs", prefs)
        return options

    def firefox_prefs_flash(self):
        '''
        當firefox運行時,flash不會加載
        :return:
        '''
        options = webdriver.FirefoxProfile()
        # 其中plugin.state.flash後的數值能夠爲0,1,2; 0:禁止,1:詢問,2:容許。
        options.set_preference("plugin.state.flash", 2)
        return options

 

5. 思路爲:chrome

  當須要打開瀏覽器時,須要傳入url,瀏覽器對象默認爲谷歌瀏覽器,瀏覽器元素默認加載時間爲5s。api

  而瀏覽器驅動的所在位置存儲在ini文件中,文件運行時去讀取指定的驅動位置。瀏覽器

 

二: 建立元素識別類函數

1. 該類主要識別元素是否存在或者元素是否消失,而且繼承瀏覽器操做類ui

2. 對傳入的元素類型及路徑組合體進行切割,並識別出相應的by對象。由隱形等待對象WebDriverWait來判斷元素存在性

切割元素路徑

way, locator = ele_para.split(">>")
ele_by = self.is_visible_driver(locator, way)

by對象判斷

        by_ele = {"Css": 'CSS_SELECTOR', "Id": 'ID', "Xpath": 'XPATH', "Name": 'NAME'}
        # capitalize不區分大小寫
        if way.capitalize() in by_ele.keys():
            ele_by = by_ele.get(way.capitalize())
            ele_by = getattr(By, ele_by)
            ele_by = (ele_by, locator)
        else:
            ele_by = None
        del by_ele
        return ele_by

3. 具體代碼:

class ActionVisible(BrowserPrepare):
    """
    工做內容:
    1.執行元素校驗動做 = [click,input,visible]
    """

    def __init__(self):
        self.log = Logger('ActionVisible')
        pass

    def is_visible_driver(self, locator: str, way: str) -> ():
        """
        根據類型定義相應的by元素對象
        :param locator:     元素路徑
        :param way:     元素類路徑類型
        :return:
        """
        by_ele = {"Css": 'CSS_SELECTOR', "Id": 'ID', "Xpath": 'XPATH', "Name": 'NAME'}
        # capitalize不區分大小寫
        if way.capitalize() in by_ele.keys():
            ele_by = by_ele.get(way.capitalize())
            ele_by = getattr(By, ele_by)
            ele_by = (ele_by, locator)
        else:
            ele_by = None
        del by_ele
        return ele_by

    def differentiate_all_exist(self, ele_by, timeout=10):
        """
        根據某個元素路徑,返回符合該路徑的所有元素
        :param ele_by: 在is_visible_driver中返回的元素by屬性
        :param timeout: 元素查找時間,默認爲5s
        :return:
        """
        try:
            ele = ui.WebDriverWait(self.driver, timeout).until(
                EC.visibility_of_all_elements_located(ele_by))
            return ele
        except Exception as e:
            fun_name = inspect.stack()[0][3]
            print("%s發生錯誤%s,元素對象爲%s" % (fun_name, e, ele_by))
            return False

    def prompt_all_exist(self, prompt, ele_by, timeout=5):
        try:
            ele = ui.WebDriverWait(prompt, timeout).until(
                EC.visibility_of_all_elements_located(ele_by))
            return ele
        except Exception as e:
            fun_name = inspect.stack()[0][3]
            print("%s發生錯誤%s,元素對象爲%s" % (fun_name, e, ele_by))
            return False

    def differentiate_single_exist(self, ele_by, timeout=5):
        """
        根據某個元素路徑,第一個符合該路徑的元素
        :param ele_by: 在is_visible_driver中返回的元素by屬性
        :param timeout: 元素查找時間,默認爲5s
        :return:
        """
        try:
            ele = ui.WebDriverWait(self.driver, timeout).until(
                EC.visibility_of_element_located(ele_by))
            return ele
        except Exception as e:
            fun_name = inspect.stack()[0][3]
            print("%s發生錯誤%s,元素對象爲%s" % (fun_name, e, ele_by))
            return False

    def differentiate_not_exist(self, ele_by, timeout=5):
        """
        識別某個元素是否從界面上消失
        :param ele_by:在is_visible_driver中返回的元素by屬性
        :param timeout:
        :return:
        """
        try:
            ui.WebDriverWait(self.driver, timeout).until_not(EC.element_to_be_clickable(ele_by))
            return True
        except Exception as e:
            fun_name = inspect.stack()[0][3]
            print("%s發生錯誤%s,元素對象爲%s" % (fun_name, e, ele_by))
            return False

    def is_visible_single_driver(self, ele_para, timeout=5):
        """
        識別某個元素是否加載完畢
        :param ele_para: 元素路徑 和 元素類型 的組合
        :param timeout: 查找元素的超時時間
        :return:
        """
        way, locator = ele_para.split(">>")
        ele_by = self.is_visible_driver(locator, way)
        return self.differentiate_single_exist(ele_by, timeout)

    def is_visible_all_driver(self, ele_para, timeout=5):
        """
        識別元素路徑相同的所有元素
        :param ele_para:
        :param timeout:
        :return:
        """
        way, locator = ele_para.split(">>")
        ele_by = self.is_visible_driver(locator, way)
        return self.differentiate_all_exist(ele_by, timeout)

    def is_visible_all_prompt(self, prompt, locator, way, timeout=5):
        """
        識別元素路徑相同的所有元素
        :param prompt:
        :param locator:
        :param way:
        :param timeout:
        :return:
        """
        ele_by = self.is_visible_driver(locator, way)
        return self.prompt_all_exist(prompt, ele_by, timeout)

    def is_visible_not_driver(self, locator, way, timeout=5):
        """
        判斷某個元素是否消失
        :param locator:
        :param way:
        :param timeout:
        :return:
        """

        ele_by = self.is_visible_driver(locator, way)
        return self.differentiate_not_exist(ele_by, timeout)

    def is_visible_click(self, prompt):
        """
        執行點擊操做
        :param prompt:
        :return:
        """
        prompt.click()
        sleep(1)

    def is_visible_input(self, attribute, parameter):
        """
        統一封裝元素輸入操做
        :param attribute: 元素對象
        :param parameter: 輸入內容
        :return:
        """
        self.set_action_funname(inspect.stack()[0][3])
        attribute.click()
        attribute.clear()
        attribute.send_keys(parameter)
        self.log.info("輸入的信息(%s)" % parameter)
        sleep(1)

    def set_action_funname(self, fun_name):
        self.log.fun_name = fun_name

 

三: 元素操做類

1. 該類繼承元素識別類

2. 主要用於元素點擊、輸入、返回元素text或者value

3. 代碼以下

class ActionParsing(ActionVisible):
    """
    主要實現selenium一些內置的動做封裝
    例如:
        元素輸入
        元素點擊
        返回元素值
    """

    def is_input_execute(self, ele_para, parameter, timeout=5):
        """
        經過元素類型來找到元素,並輸入內容
        :param ele_para:  元素路徑
        :param parameter:  須要輸入的內容
        :param timeout: 元素查找時間
        :return:
        """
        attribute = self.is_visible_single_driver(ele_para, timeout)
        self.is_visible_input(attribute, parameter)
        self.log.info("%s元素輸入內容爲%s" % (ele_para, parameter))

    def is_click_execute(self, ele_para, timeout=5):
        """
        經過元素類型來找到元素並執行點擊操做
        :param ele_para:  元素路徑
        :param timeout: 元素查找時間
        :return:
        """
        attribute = self.is_visible_single_driver(ele_para, timeout)
        self.is_visible_click(attribute)
        self.log.info("%s元素進行點擊操做" % ele_para)

    def get_text_value(self, ele_para: str, attr: str = None, timeout: int = 5) -> str:
        """
        獲取元素的text或者attribute
        :param ele_para:  元素路徑
        :param attr:  爲none時獲取元素text,不爲空時獲取元素的attribute屬性值
        :param timeout: 元素可見超時時間
        :return:
        """
        attribute = self.is_visible_single_driver(ele_para, timeout)
        if type(attribute) is bool:
            return attribute
        else:
            if attr:
                attribute = attribute.get_attribute(attr)
            else:
                attribute = attribute.text
        self.log.info("%s元素獲取(%s)屬性值爲%s" % (ele_para, attr, attribute))
        return attribute

 

四: js內置操做類

1. 繼承元素操做類,該類主要是經過js來對元素進行輸入/點擊/焦點獲取及失去

2. 代碼以下:

class ActionBuiltWeb(ActionVisible):
    """
    經過web內置的js來作操做。
    例如:
        元素查找
        元素點擊
        元素輸入
        聚焦及移除焦點
    """

    def cursor_execute_id(self, locator, parameter):
        """
        利用js找到相關id的元素,直接對value進行數據修改
        :param locator: 元素對象
        :param parameter: 輸入內容
        :return:
        """
        self.driver.execute_script("document.getElementById(\'" + locator + "\').value=\'" + parameter + "\';")
        sleep(1)

    def cursor_execute_ordinal(self, cursor, parameter):
        """
         根據元素對象自己,經過JS對value進行寫入
        :param cursor:  元素對象自己
        :param parameter:   須要輸入的信息
        :return:
        """
        self.driver.execute_script("\'" + cursor + "\'.value=\'" + parameter + "\';")
        sleep(1)

    def cursor_execute_selectop(self, locator, parameter):
        """
        利用js找到相關selctop的元素,直接對value進行數據修改
        :param locator: 元素對象
        :param parameter: 輸入內容
        :return:
        """
        self.driver.execute_script("document.querySelector(\'" + locator + "\').value=\'" + parameter + "\';")
        sleep(1)

    def id_confirm_execute(self, locator):
        """
        利用js語法經過id執行點擊操做
        :param locator:     元素屬性中,ID的屬性值
        :return:
        """
        self.driver.execute_script("document.getElementById(\'" + locator + "\').click();")
        pass

    def css_confirm_execute(self, locator):
        """
        利用js語法經過元素selector執行點擊操做
        :param locator: 元素屬性中,selector的屬性值
        :return:
        """
        self.driver.execute_script("document.querySelector(\'" + locator + "\').click();")
        pass

    def attribute_focus_blur(self, ele_attr, cursor_type):
        """
        經過元素id,實現元素獲取焦點及失去焦點的操做
        :param ele_attr:    元素的id
        :param cursor_type: 聚焦或失焦
        :return:
        """
        if 'blur' == cursor_type:
            self.driver.execute_script("document.getElementById(\'" + ele_attr + "\').blur();")
            pass
        elif 'focus' == cursor_type:
            self.driver.execute_script("document.getElementById(\'" + ele_attr + "\').focus();")

    def cursor_focus_blur(self, ele_attr, cursor_type: str):
        """
        根據元素對象自己來實現元素獲取焦點及失去焦點的操做
        :param ele_attr:  元素對象
        :param cursor_type:  focus聚焦或blur失焦
        :return:
        """
        if 'blur' == cursor_type:
            self.driver.execute_script("arguments[0].blur();", ele_attr)
            pass
        elif 'focus' == cursor_type:
            self.driver.execute_script("arguments[0].focus();", ele_attr)

 

項目所在位置:

https://github.com/namexiaohuihui/demotest

相關文章
相關標籤/搜索