一、显式等待和隐式等待:
1、直接等待:
强制等待,线程休眠一段时间
time.sleep(3)
2、隐式等待:
设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,如果在等待时间内出现元素,则退出等待,如果没有出现则抛出异常
self.driver.implicitly_wait(3)
(1)缺点:设置的是全局的等待,作用于所有find_element()方法;
(2)找到元素就会退出,不管元素是否加载到可点击状态。
3、显式等待:
在代码中定义条件,当条件发生时才继续执行代码。WedDriverWait
配合until()
或until_not()
方法,根据判断条件进行等待。
def findelement(self, loc, wait=10, num=0.5):
'''定位元素'''
element = WebDriverWait(self.driver, wait,num).until(EC.presence_of_element_located(loc))
return element
程序每隔一段时间(默认0.5秒)进行条件判断,如果条件成立,则执行下一步,否则继续等待,直到超过设置的最长等待时间。
(1)注意:
until()
或until_not()
中需要传一个方法名(不需要带括号,仅方法名),这个方法必须要有一个入参(可参考until源码)expected_conditions
中提供了大量可用的条件方法(可参考expected_conditions
源码)
二、web控件定位和常见操作
1、xpath
(1)缺点:
- 速度慢:从头到尾遍历
(1)优点:
- 可以用于appnium和selenium
2、css_selector:
- 用的是css选择器,速度更快,用样式来定位
- by.Id,by.name,by.tag_name,by.class_name本质是css_selector
3、Actions
3.1、ActionChains:
执行PC端的鼠标点击,双击,右键和拖拽等事件:
3.2、TouchActions:
模拟PC和移动端的点击,滑动,拖拽,多点触控等多种手势操作;
三、其他
1、多窗口处理:
- 获取当前页面的句柄:
driver.current_window_handle
- 获取当前所以的句柄:
driver.window_handles
- 切换至所需要操作的句柄:
driver.switch_to.window()
def switch_window(self,data,type='index',isClose=False):
'''切换窗口,可根据index,url,title,handle切换'''
to_window=current_window = self.driver.current_window_handle # 当前窗口句柄
windows = self.driver.window_handles # 所有窗口句柄
if type=='index' and isinstance(data,int): # 根据窗口顺序切换
to_window=windows[data]
elif type=='handle':
to_window = data
else:
for handle in windows:
self.driver.switch_to.window(handle)
if type == 'url':
current_url = self.driver.current_url
if data in current_url:
to_window=handle
break
elif type=='title':
current_title=self.driver.title
if data in current_title:
to_window = handle
break
# 切换至所需要的句柄
self.driver.switch_to.window(to_window)
if isClose:
# 关闭掉第一个句柄,仅保留第二个句柄
self.driver.switch_to.window(current_window)
self.driver.close()
return current_window,to_window
2、frame处理:
- 切换至frame:
switch_to.frame(reference)
(reference是传入的参数,用来定位frame,可以传入id、name、index以及selenium的WebElement对象) - 从frame切回主文档:
driver.switch_to.default_content()
- 嵌套frame的操作:
driver.switch_to.parent_frame()
(从子frame切回到父frame,如果当前已是主文档,则无效果)
3、JS的处理:
处理方法是用js把隐藏的显示出来,方法如下:
js="document.getElementById('li').style.display='block';"
driver.execute_script(js)
1、时间控件的处理:
4、弹窗处理机制:
5、解决扫码登录问题:
1、复用已有浏览器:
不会重新开启一个浏览器,复用已经在运行的浏览器
之后,我们就可以在启动的浏览器上运行我们的测试代码了。
2、通过获取当前浏览器cookie的方式
- 以企业微信的后台管理登录为例,使用新的浏览器,打开登录扫码页面,强制等待10秒手动完成扫码,扫码进入管理后台;
- 登录后,在代码中使用driver返回当前页面的cookies值,并保存为json文件;
- 后续的测试用例,可以使用新保存的cookie,添加在driver中即可
6、PO模式
(1)po模式六大原则
- 公共方法代表页面提供的服务
- 不要暴露页面细节
- 不要把断言和操作细节混用
- 方法可以return到新打开的页面
- 不要把整页内容都放到PO中
- 相同的行为会产生不同的结果,可以封装不同结果