unittest 运行slenium(二)---打开浏览器及元素操作
一: 打开win10中安装的浏览器
1. 打开的浏览器有:谷歌/火狐/ie/edge
2. 当浏览器的driver没有配置在path环境下时,在启动浏览器时需要传入driver的所在位置
3. 其中火狐浏览器安装不为默认路径时也需要配置说明
4. 具体代码如下:
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. 思路为:
当需要打开浏览器时,需要传入url,浏览器对象默认为谷歌浏览器,浏览器元素默认加载时间为5s。
而浏览器驱动的所在位置存储在ini文件中,文件运行时去读取指定的驱动位置。
二: 创建元素识别类
1. 该类主要识别元素是否存在或者元素是否消失,并且继承浏览器操作类
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)
项目所在位置: