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