取之于论坛,用之于论坛,这些方法的实现大部分是我依赖论坛上的资源进行的整合,如有侵权,告知我,我删贴。
我做的这个共功能是公司框架的一部分,我主要做了一件事,就是对selenium 的webdriver API 进行二次封装,需要达到的要求有两个:1.化繁为简,简化定位元素->对元素进行操作的流程,从而方便使用框架的人员,更加方便的编写脚本。2.定位元素的方法传参越简单越好,最好让人一眼就看明白,不需要了解背后的原理(HTML语言,八大元素定位等)。基于此,代码如下:
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium import webdriver
from Library.Doc.page_elements import *
class Browser:
def __init__(self, driver):
self.browser = self.__choose_browser(driver)
def element(self, locator):
locate_way, web_element = self._find_locator(locator)
for locate_key, locate_value in locate_way_index.items():
if locate_key == locate_way:
return self.browser.find_element(locate_value, web_element)
def elements(self, locator):
locate_way, web_element = self._find_locator(locator)
for locate_key, locate_value in locate_way_index.items():
if locate_key == locate_way:
return self.browser.find_elements(locate_value, web_element)
def element_wait(self, locator, wait_time=20): # 显式等待
locate_way, web_element = self._find_locator(locator)
for locate_key, locate_value in locate_way_index.items():
if locate_key == locate_way:
WebDriverWait(self.browser, wait_time, 1).until(
ec.presence_of_element_located((locate_value, web_element)))
break
# wait event
def _implicitly_wait(self, wait_time):
self.browser.implicitly_wait(wait_time)
def sleep(self, sleep_time):
sleep(sleep_time)
# mouse event
def click(self, locator):
self.element_wait(locator)
ele = self.element(locator)
ele.click()
def click_and_hold(self, locator):
self.element_wait(locator)
ele = self.element(locator)
ActionChains(self.browser).click_and_hold(ele).perform()
def right_click(self, locator):
self.element_wait(locator)
ele = self.element(locator)
ActionChains(self.browser).context_click(ele).perform()
def double_click(self, locator):
self.element_wait(locator)
ele = self.element(locator)
ActionChains(self.browser).double_click(ele).perform()
...
...
...
# 不赘叙那些重复性的封装方法了
# keyboard event
def send_keys_to_element(self, locator, *text):
self.element_wait(locator)
ele = self.element(locator)
ele.send_keys(*text)
...
...
...
def quit(self):
self.browser.quit()
def close(self):
self.browser.close()
...
...
@staticmethod
def __choose_browser(browser: str):
if browser.lower() == 'chrome':
return webdriver.Chrome()
elif browser == 'firefox':
return webdriver.Firefox()
elif browser == 'edge':
return webdriver.Edge()
elif browser == 'ie':
return webdriver.Ie()
else:
raise NameError("只支持firefox/chrome/edge/ie.")
# 对字典中指定的键对应的值拆分成定位方式,对应的定位方式的页面参数值
def _split_the_value(self, value: str):
return value.split('->>')
# 在定位器字典中,根据键,查找对应的值,并利用拆分函数对其进行拆分
def _find_locator(self, locator: str):
for locator_way, locator_value in locators_dic.items():
if locator_way == locator:
return self._split_the_value(locators_dic[locator_way])
以百度为例,简单测试了一下,在page_elements.py模块建一个页面元素字典:
page_elements = {'search': 'id->>kw',
'search_button': 'id->>su'
}
新建一个测试用例,简单测试一下,是可以跑通的,今天有点晚了,不想弄了,明天再好好调一调。(选择浏览器的操作,以及获取页面地址和前后夹具都写到conftest.py配置文件里了)
import pytest
@pytest.mark.demo
def test_locate_function(driver):
driver.send_keys_to_element('search', 'selenium')
driver.click('search_button')
附:conftest.py代码段:
@pytest.fixture(scope="session", autouse=True) # conftest 中的夹具可以在测试用例中作为参数调用
def driver():
global _driver
_driver = Browser('chrome')
return _driver
@pytest.fixture(scope="session", autouse=True)
def open_url_fixture(): # 利用此方式实现统一的前后置,conftest 在package内,只允许包内调用,相当于局部变量,在根目录下可以全局调用。
# desired_capabilities = DesiredCapabilities.CHROME
# desired_capabilities['pageLoadStrategy'] = 'none'
_driver.open('http://www.baidu.com')
yield
_driver.sleep(5)
_driver.quit()