一、selenium环境搭建
1.检查python环境
2.在cmd命令窗口,输入pip3 install selenium
3.浏览器驱动安装:由于执行的脚本需要浏览器驱动来驱动浏览器,所以需要安装形影的浏览器驱动
- WebDriver浏览器驱动下载地址:
http://chromedriver.storage.googleapis.com/index.html
4.编写第一个selenium脚本,能吊起Chrome浏览器并运行通过即可
#导包
from selenium import webdriver
#创建浏览器对象
driver = webdriver.Chrome()
#打开百度首页
driver.get("https://www.baidu.com")
#在百度的文本框中输入selenium
# Target:对谁进行操作?可以使用他们的属性进行定位
# command:找到之后,你要对她干嘛?输入、键入
# value:键入啥?abc
driver.find_element_by_id("kw").send_keys("selenium")
#点击百度按钮
driver.find_element_by_id("su").click()
#关闭浏览器
driver.quit()
二、selenium概述
1 历史版本
- Selenium 1.0:Selenium IDE、Selenium Remote Control(RC)、Selenium Grid
- Selenium 1.0:Selenium IDE、Selenium Remote Control(RC)、Selenium Grid、Selenium WebDriver
- Selenium3.0:Selenium IDE、Selenium Grid、Selenium WebDriver
2 Selenium IDE
- selenium IDE是selenium家族中唯一的入门级工具,通过录制并回放功能,可以快速创建测试用例,不用怎么费劲就能学会,因为它很简单,IDE主要用来分析元素的原型,而不是创建全套的复杂的测试用例。
- 特点
- 优点:不需要任何编程逻辑来编写其测试脚本,只需用工具记录与浏览器的交互【测试人员的手工测试操作过程】创建测试用例
不会编程语言的的小白也可以快速上手 - 缺点:只能在Firefox/Chrome上面使用,对于测试系统兼容性不友好
使用录制与回放来执行测试用例稳定性有限
遇到交互性特强的模块需要录制多个用例时处理能力有限
在处理较为复杂的逻辑的时候显得力不从心 - selenium IDE工具的安装
Firefox浏览器中安装:
浏览器右上角菜单选择附加组件
搜索“selenium ide”组件并添加到firefox
浏览器右上角即出现selenium ide的快捷按钮 - selenium IDE工具的使用
- 点击selenium ide按钮进入工具之后,首先是下面的四个选项。
- Record a new test in a new project:录制一个新的测试在新的工程中(自动化测试的项目作为工程,一个具体的功能可以作为一个测试)
- Open an existing project:原来已经开发好了,只需要打开对应的工程文件即可
- Create a new project:创建一个新的空工程
- Close Selenium IDE:关闭selenium IDE工具
- 通过以下五个步骤完成测试脚本的录制
1. 我们选择第一个选项,新建工程名及base url地址(被测系统的URL地址),即可直接启动录制脚本。
2. step02:在selenium ide中点击红色的“停止录制”按钮,即可终止录制并保存为一个测试用例。
生成的代码是以关键字形式展示并进行修改的:主谓宾语法
Target:对谁进行操作?可以使用他们的属性进行定位
command:找到之后,你要对她干嘛?点击、键入…
value:键入啥?
录制完之后,需要把脚本的步骤列表中,不需要的步骤可以删除。
3. 一个完整的测试用例,应该包括哪些内容,步骤(command、target、value)和断言(预期结果和实际对比),断言不需要多,一个就够了,只要能够唯一确定你的脚本是通过的即可断言页面上显示的文本:assert text
4. 点击运行按钮,查看日志,看所有的步骤是否OK,断言是否OK,是否出现最终的结果“‘baidusearch’ completed successfully”,如果都可以,则该脚本运行通过。
5. step05:选中测试集合或者测试用例,右键export导出不同语言的脚本。
- 点击selenium ide按钮进入工具之后,首先是下面的四个选项。
三、WebDriver API之常见元素定位方法
1. 自动化测试的步骤:
- 通过某些方式定位到我们要执行的对象、目标(Target)
- 对这个对象进行什么操作(command)
- 通过操作对定位到事物元素赋值(value)
- 添加断言操作
2. 元素定位操作
2.1 页面元素
在浏览器上能显示的所有要素,如图片、文本框、按钮、下拉列表、视频等。
2.2 定位页面元素的方式
Selenium Webdriver中提供的了8种页面元素定位方式。
1. id属性定位 --> find_element_by_id(“id属性值”)
最常用的一种元素定位方式,一般情况下ID属性不会重复,
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#通过ID来定位文本框和百度一下
driver.find_element_by_id("kw").send_keys("selenium")
time.sleep(2)
driver.find_element_by_id("su").click()
time.sleep(2)
#退出浏览器对象
driver.quit()
2. name属性 —> find_element_by_name(“name属性值”)
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#通过name属性定位元素
driver.find_element_by_name("wd").send_keys("selenium")
time.sleep(2)
driver.find_element_by_id("su").click()
time.sleep(2)
#退出浏览器对象
driver.quit()
3. class 属性定位->find_element_by_class_name(“class属性值”)
对某些具有相同类的元素一网打尽的好方法
4. tag name:->find_element_by_tag_name(“标签名”)
重复率高,定位效率低,基本不用
5. link text:->find_element_by_link_text(“链接的显示文本”)
超链接的显示文本信息,较为常用,参数是全部文本信息。
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#使用link text属性定位(元素显示的文本信息,要求是全部信息)
driver.find_element_by_link_text("新闻").click()
#等待3s
time.sleep(3)
#退出浏览器对象
driver.quit()
6. partial link text:->find_element_by_partial_link_text(“部分链接的显示文本”)
超链接的显示文本信息,较为常用,参数是部分文本信息即可
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#使用link text属性定位(元素显示的文本信息,要求是全部信息)
driver.find_element_by_link_text("新闻").click()
time.sleep(5)
#使用partial link text属性定位(元素显示的文本信息,可以是部分信息)
driver.find_element_by_partial_link_text("全国首家在线“报销”互联网慢病诊室开通").click()
#等待3s
time.sleep(3)
#退出浏览器对象
driver.quit()
7. xpath:->find_element_by_xpath(“xpath”)
Xpath不是selenium专用,只是作为一种定位手段,为selenium所用。Xpath是一门在xml文档中查找信息的语言。Xpath可用来在xml文档中对元素和属性进行遍历。由于html的层次结构与xml的层次结构天然一致,所以使用Xpath也能够进行html元素的定位。
7.1 绝对路径
以/开头,从HTML标签开始,依次遍历HTML结构数的节点,直到找到要定位的页面元素,
> 如百度首页的百度文本框的绝对路径,一般万不得已不使用。
> 为:/html/body/div/div/div[3]/div/div/form/span/input
> 父子节点是使用/连接,从上往下依次遍历
> 兄弟节点是[]表示兄弟的排行,比如同一级别上有2个以上的input标签,input[2]就是排在第二位的,排行老大可以写为:input或者是input[1]
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#使用绝对路径定位
# driver.find_element_by_xpath("/html/body/div/div/div[3]/div/div/form/span/input").send_keys("selenium")
# time.sleep(2)
# driver.find_element_by_xpath("/html/body/div/div/div[3]/div/div/form/span[2]/input").click()
# time.sleep(2)
driver.quit()
7.2、通过属性定位(相对路径)
一般以//开头,使用属性id、name、class结合xpath进行定位,如百度文本框的定位:
> //input[@id='kw']
//input[@name='wd']
//input[@class='bg s_btn']
在一个属性不能定位到元素的时候,可以逻辑运算符的使用。
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#利用元素属性定位
# driver.find_element_by_xpath("//input[@id='kw']").send_keys("selenium")
# time.sleep(2)
# driver.find_element_by_xpath("//input[@id='su']").click()
# time.sleep(2)
#使用逻辑运算符
driver.find_element_by_xpath("//input[@id='kw' or @name = 'wd']").send_keys("selenium")
time.sleep(2)
driver.find_element_by_xpath("//input[@id='su']").click()
time.sleep(2)
driver.quit()
7.3 通过父子关系和属性定位
假设某个标签就一个标签名,其他属性一概没有(或者有一个class name,而且是重复的)
使用绝对路径没问题,就是复杂点
使用属性定位,就不靠谱了,定位不到
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 利用父子关系以及属性定位:
# driver.find_element_by_xpath("//form[@id='form']/span/input").send_keys("selenium")
# time.sleep(2)
# driver.find_element_by_xpath("//form[@id='form']/span[2]/input").click()
# time.sleep(2)
driver.quit()
7.4 直接Chrome浏览器复制
8. css:---->find_element_by_css_selector(“css”)(掌握)
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#css的类选择器定位百度文本框,使用css的id选择器定位百度一下按钮
# driver.find_element_by_css_selector(".s_ipt").send_keys("selenium")
# driver.find_element_by_css_selector("#su").click()
driver.find_element_by_css_selector("form#form > span > input#kw").send_keys("selenium")
driver.find_element_by_css_selector("#su").click()
time.sleep(3)
driver.quit()
四、WebDriver API之浏览器控制方法
1. 控制浏览器窗口大小
WebDriver提供了以下三种API用于调整窗口大小:
17. Set_window_size():方法来设置浏览器的大小
18. minimize_window():最大化显示
19. minimize_window():最小化显示,在最小化情况下,也可以进行元素定位及操作
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#比较喜欢宽屏显示,我也要设置打开的窗口为:1920 * 600
#driver是浏览器对象
# windowHandle:一个页面的标识
# driver.set_window_size(1920,600)
#最大化显示窗口
# driver.maximize_window()
# 最小化
# time.sleep(2)
# driver.minimize_window()
# time.sleep(2)
# driver.find_element_by_id("kw").send_keys("selenium")
# driver.maximize_window()
#退出浏览器对象
# driver.quit()
2 控制浏览器后退、前进、刷新
在使用浏览器浏览网页时,浏览器提供了后退和前进按钮,可以方便的在浏览过的页面之间来回切换、刷新等,WebDriver也提供了对应的:
20. back():后退
21. forward():前进
22. refresh():刷新
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#页面的前进后退操作
# driver.find_element_by_link_text("新闻").click()
# time.sleep(2)
# #后退到百度首页
# driver.back()
# time.sleep(2)
# #再前进到新闻页面
# driver.forward()
# time.sleep(2)
# #再执行一次刷新操作
# driver.refresh()
#退出浏览器对象
# driver.quit()
3 截屏操作
将运行的页面截图保存在本地,推荐使用png格式:
23. driver.save_screenshot(r"e:\abc.png")
24. driver.get_screenshot_as_file(“{}.{}”.format(“e:/aaa”,“png”))
25. driver.get_screenshot_as_file(r"e:\abc.png")
#导包、创建浏览器对象、获取一下url地址
from selenium import webdriver
import time
#driver:就是一个普通的变量,dr也行
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# driver.save_screenshot(r"e:\sss.png")
# driver.get_screenshot_as_file("{}.{}".format("e:/aaa","png"))
# driver.get_screenshot_as_file(r"e:\sss.png")
#退出浏览器对象
# driver.quit()
4 模拟浏览器关闭
webdriver提供两种关闭的方法:
26. quit():关闭浏览器,不管页面有几个窗口,一概关掉
27. close():只关掉了一个当前的窗口,而且关掉的是前面的一个
5 多窗口操作
每一个页面都一个句柄(handle)值,对一个页面来说是唯一,是页面的一个标识webdriver进行自动化测试,需要将driver绑定到页面句柄,你的driver只能控制你绑定句柄的这个页面,因此对不不同的窗口页面的元素,driver就不能操作了,下面就看如何解决这种多窗口问题。
获取句柄的方式:
1.driver.current_window_handle: 获取当前页面的句柄
28. driver.window_handles:获取所有打开窗口的句柄
实现需求:淘宝首页->聚划算->女装
29. 拿到聚划算的句柄,返回的是一个列表
handles = driver.window_handles
30. 将句柄绑定给driver,参数是列表中聚划算页面的句柄,x为0表示浏览器中的第一个窗口,1表示第二个窗口,-1表示最后一个窗口。
driver.switch_to_window(handles[x])
#导包、创建浏览器对象、获取淘宝的首页
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("https://www.taobao.com")
#等待两秒钟
time.sleep(2)
#获取当前页面的句柄
# CDwindow-AA8085746F56C04363172064996E1A52
handler1 = driver.current_window_handle
print(handler1)
# 2、点击聚划算,进入聚划算页面。
driver.find_element_by_link_text("聚划算").click()
#等待两秒钟
time.sleep(2)
#第一步:获取所有打开窗口的句柄
handlers = driver.window_handles
# ['CDwindow-AA8085746F56C04363172064996E1A52', 'CDwindow-FD84D68BEFF3DBFFB64A5AC48E4F1703']
print(handlers)
#第二步:将聚划算的句柄绑定给driver
driver.switch_to_window(handlers[1])
# 3、选择“女装”,进入女装页面。
driver.find_element_by_link_text("女装").click()
#等待两秒钟
time.sleep(2)
# 4、返回到聚划算页面。
driver.back()
#等待两秒钟
time.sleep(2)
#关闭当前窗口(driver所绑定的哪个窗口)
driver.close()
五、WebDriver API之鼠标、键盘操作方法
使用 Selenium WebDriver 做web自动化测试的时候,会经常模拟鼠标和键盘的一些行为:
比如使用鼠标单击、双击、右击、拖拽、悬浮等动作
或者键盘输入、快捷键使用、组合键使用等模拟键盘的操作
在 WebDeriver 中,有专门的类来负责实现这些测试场景,那就是 ActionChains和Keys类。
1. 鼠标事件
ActionChains类中封装了对鼠标事件操作的方法,常见方法有:
-
context_click() 右击 --> 此方法模拟鼠标右键效果
-
double_click() 双击 --> 此方法模拟鼠标双击效果
-
drag_and_drop() 拖动 --> 此方法模拟鼠标拖动效果
-
move_to_element() 悬停 --> 此方法模拟鼠标悬停效果
-
perform() 执行 --> 此方法用来执行封装在ActionChains的行为
在ActionChains类中所有提供的鼠标事件方法,在调用的时候所有的行为都存储在ActionChains类中,需要调用perform()方法才能真正执行。 -
导包:rom selenium.webdriver.common.action_chains import ActionChains
-
封装鼠标事件到ActionChains中
-
执行ActionChains中封装的的行为
1、鼠标悬浮和点击
#导包、创建浏览器对象、获取百度的首页
from selenium import webdriver
#导入鼠标事件的ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
# 案例1:控制鼠标悬浮到百度首页“设置”按钮上
# setButton = driver.find_element_by_xpath('//*[@id="s-usersetting-top"]')
# 将对“设置”按钮的操作行为封装到ActionChains
# element = ActionChains(driver).move_to_element(setButton)
# 并调用perform方法执行悬浮操作
# element.perform()
# 案例2:在百度文本框中鼠标右键
webEdit = driver.find_element_by_id("kw")
element = ActionChains(driver).context_click(webEdit)
element.perform()
time.sleep(5)
driver.quit()
2、鼠标拖拽动作
方法的格式:drag_and_drop(source,target)
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep
driver = webdriver.Firefox()
url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
driver.get(url)
#切换到目标元素所在的frame
driver.switch_to.frame("iframeResult")
#确定拖拽目标的起点
source = driver.find_element_by_id("draggable")
#确定拖拽目标的终点
target = driver.find_element_by_id("droppable")
#执行动作
actions = ActionChains(driver)
actions.drag_and_drop(source,target)
#执行
actions.perform()
sleep(5)
2. 键盘事件操作
Keys中封装了键盘上的按键或者组合键的字段,sendkeys()方法可以用来模拟键盘输入,除此之外还可以使用sendkeys方法发送文件到服务器(上传功能以input标签实现),常见的键盘事件操作有:
- send_keys(Keys.Back_SPACE):删除键
- send_keys(Keys.SPACE):空格键
- send_keys(Keys.TAB):制表键
- send_keys(Keys.ESCAPE):esc键
- send_keys(Keys.ENTER):回车键
- send_keys(Keys.CONTROL,’a’):全选
- send_keys(Keys.CONTROL,’c’):复制
- send_keys(Keys.CONTROL,’x’):剪切
- send_keys(Keys.CONTROL,’v’):粘贴
- send_keys(Keys.F1):F1键
键盘事件使用步骤:
- 导包:from selenium.webdriver.common.keys import keys
- 使用send_keys()方法发送Keys中定义的键、组合键及功能键
##导包、创建浏览器对象、获取一下url地址 from selenium import webdriver from selenium.webdriver.common.keys import Keys import time #driver:就是一个普通的变量,dr也行 driver = webdriver.Chrome() driver.get("https://www.baidu.com") # 1、百度“seleniumm” driver.find_element_by_id("kw").send_keys("seleniumm") time.sleep(1) # 2、删除多输入的m driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE) time.sleep(1) # 3、再输入“空格 教程”,再次发送字符串,是和前面的进行拼接 driver.find_element_by_id("kw").send_keys(" 教程") time.sleep(1) # 4、ctrl+a,全选文本框内容 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"a") time.sleep(1) # 5、ctrl+x,剪切选择的内容 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"x") time.sleep(1) # 6、ctrl+v,粘贴复制的内容 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"v") time.sleep(1) # 7、回车代替单击,完成搜索 driver.find_element_by_id("kw").send_keys(Keys.ENTER) time.sleep(1) # 8、退出浏览器 driver.quit()
六、WebDriver API之iframe/frame页面嵌套操作
在一个页面中可以嵌套另外一个页面,如frame/iframe技术,这是现在很多web应用中使用的一种方式,webdriver对象只能在一个页面(外层是默认的)中定位元素,需要一种方式将driver对象从外层切换给内层使用才能对内层的对象进行处理。
下图是qq邮箱登录页面,其中的登录框就是一个内嵌的frame页面,下面我们就以他为案例。
webdriver中提供的对iframe/frame操作API常用到有:
- driver.switch_to.frame()
- driver.switch_to.default_content()
- driver.switch_to.parent_frame()
1. driver.switch_to.frame()
从外部页面切入frame框架中,参数可以为id/name/index及页面元素对象。
第一种方式:默认是可以给ID、name的
- driver.switch_to.frame(“login_frame”)
第二种方式:给出页面的iframe的索引index,根据同层frame的顺序定位 - driver.switch_to.frame()
第三种方式:可以传参iframe的元素对象 - iframeObj = driver.find_element_by_xpath(‘//*[@id=“login_frame”]’)
- driver.switch_to.frame(iframeObj)
#导包、创建浏览器对象、打开qq首页 from selenium import webdriver import time driver = webdriver.Chrome() # 1.打开腾讯首页;http://www.qq.com driver.get("https://www.qq.com") # 2.点击邮箱图标; driver.find_element_by_link_text("Qmail").click() # 跳转到邮箱登录界面(窗口),涉及到多窗口的处理 handles = driver.window_handles driver.switch_to.window(handles[1]) #现在先验证窗口跳转是否成功 # driver.find_element_by_link_text("基本版").click() # 3.输入用户名 #webdriver中提供API:driver.switch_to.frame()实现frame的切换 #第一种方式,默认是可以给ID或者name的 # driver.switch_to.frame("login_frame") #第二种方式,可以传参iframe的元素对象 # iframeObj = driver.find_element_by_xpath('//*[@id="login_frame"]') # driver.switch_to.frame(iframeObj) #第三种方式,可以给索引号 driver.switch_to.frame(1) driver.find_element_by_link_text('帐号密码登录').click() driver.find_element_by_xpath('//*[@id="u"]').send_keys("2572612580") time.sleep(2) # 4.输入密码; driver.find_element_by_xpath('//*[@id="p"]').send_keys("123456789") time.sleep(2) # 5.点击登录; driver.find_element_by_xpath('//*[@id="login_button"]').click() time.sleep(2) # 6.关闭浏览器。 driver.quit()
2. driver.switch_to.default_content()
切到frame中之后,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档。
- driver.switch_to.default_content() # 直接从内层frame页面切换回到主文档中。
3. driver.switch_to.parent_frame()
如果frame/iframe有多层,我们可以通过driver.switch_to.frame()一层层切入到内层,并可以通过driver.switch_to.parent_frame()一层层再退出来,相当于前进、后退。
相对driver.switch_to.default_content()方法,是一层层退回,而不是直接退回主页面
driver.switch_to.frame(“frame1”) #从主页面切入到frame1,相当于前进
driver.switch_to.frame(“frame2”) #从frame1再切入到frame2,相当于前进
driver.switch_to.parent_frame() #返回到上级frame1,相当于后退
driver.switch_to.parent_frame() #返回到主页面
七、WebDriver API之消息框处理
webdriver处理javascript生成的alert、confirm、prompt消息框的方式十分简单,都是统一使用switch_to.alert将driver的控制权限交给消息框,然后再调用相应方法进行操作:
- text:返回alert/confirm/prompt中的文字信息
- accep():接受现有警告信息,相当于确认按钮
- dismiss():放弃现有警告信息,相当于取消按钮
- send_keys(keysToSend):发送文本至警告框
1.警告消息框alert
alert 方法生成的警告消息框提供了一个“确定”按钮让用户关闭该消息框,并且该消息框是模式对话框,也就是说,用户必须先关闭该消息框然后才能继续进行操作。
案例:百度搜索设置中,保存后弹出警告框,确认接收该提示信息。
#导包、创建浏览器对象、获取百度的首页
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#控制鼠标悬浮到“设置”按钮上
setButton = driver.find_element_by_xpath('//*[@id="s-usersetting-top"]')
ActionChains(driver).move_to_element(setButton).perform()
driver.find_element_by_link_text("搜索设置").click()
time.sleep(3)
#时间等待的作用,如果不加的话可能会元素定位失败
# driver.find_element_by_xpath('//*[@id="SL_0"]').click()
# time.sleep(2)
# driver.find_element_by_xpath('//*[@id="nr"]/option[2]').click()
# time.sleep(2)
#点击保存设置按钮,弹出一个警告框
driver.find_element_by_link_text("保存设置").click()
time.sleep(2)
#就可以对他做操作啦,由于版本问题,switch_to.alert
dd = driver.switch_to.alert
#获取alert里面的文本信息
tt = dd.text
#已经记录下您的使用偏好
print(tt)
time.sleep(2)
#接受窗口信息(确定这个文本框)
# dd.accept()
dd.dismiss()
#退出浏览器对象
driver.quit()
2. 确认消息框confirm
使用确认消息框可向用户问一个“是-或-否”问题,并且用户可以选择单击“确定”按钮或者单击“取消”按钮。confirm 方法的返回值为 true 或 false。该消息框也是模式对话框:用户必须在响应该对话框(单击一个按钮)将其关闭后,才能进行下一步操作。
案例:复制下面html代码,保存在本地的文本文件中,并将文件重命名为:confirm.html,文件保存在:e:\confirm.html
<html>
<head>
<script type="text/javascript">
function show_confirm()
{
var r=confirm("Press a button!");
if (r==true)
{
alert("You pressed OK!");
}
else
{
alert("You pressed Cancel!");
}
}
</script>
</head>
<body>
<input type="button" onclick="show_confirm()" value="Show a confirm box" />
</body>
</html>
编写自动化测试脚本,处理该确认消息框:
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("file:///E:/confirm.html")
#点击页面的:show a confirm box
driver.find_element_by_xpath('/html/body/input').click()
#driver对象切换到confirm提示框
aaa = driver.switch_to.alert
#点击确认消息框的确定按钮或者取消按钮
# aaa.accept()
aaa.dismiss()
time.sleep(5)
#点击后续弹出的alert窗口的确定按钮
aaa.accept()
time.sleep(5)
#退出浏览器对象
driver.quit()
3. 提示消息框prompt
提示消息框提供了一个文本字段,用户可以在此字段输入一个答案来响应您的提示。该消息框有一个“确定”按钮和一个“取消”按钮。
案例:复制下面html代码,保存在本地的文本文件中,并将文件重命名为:prompt.html,文件保存在:e:\prompt.html
<html>
<head>
<script type="text/javascript">
function disp_prompt()
{
var name=prompt("请输入您的名字","Bill Gates")
if (name!=null && name!="")
{
document.write("你好," + name + "!今天过得好吗?")
}
}
</script>
</head>
<body>
<input type="button" onclick="disp_prompt()" value="显示一个提示框" />
</body>
</html>
编写自动化测试脚本,处理该提示消息框prompt:
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("file:///E:/prompt.html")
#点击页面的按钮:先是一个提示框
driver.find_element_by_xpath('/html/body/input').click()
#driver对象切换到prompt提示框
aaa = driver.switch_to.alert
#使用提示消息框的send_keys()方法
aaa.send_keys("捉虫布道人")
time.sleep(5)
#使用提示消息框的确认accept()方法及取消dismiss()方法
aaa.accept()
# aaa.dismiss()
time.sleep(3)
driver.quit()
八、WebDriver API之页面元素时间等待
元素等待:如今很多web都在使用AJAX技术,运用这种技术的软件当浏览器加载页面时,页面上的元素可能不会被同步加载完成,如此一来,定位元素时就会出现困难,我们可以通过设置元素等待来改善这类问题导致的测试脚本不稳定。
WebDriver脚本开发中可以使用三种种元素等待方式:
1 强制等待
time.sleep(5),单位是s,就是直接让线程休眠,这几秒啥事也不用干
import time #导入时间模块
time.sleep(5) #休眠5s钟
2. 隐式等待
在脚本创建driver对象之后,给driver设置一个全局的等待时间,对driver的整个生命周期(创建到关闭)都起效。如果在设置等待时间(超时时间)内,定位到了页面元素,则不再等待,继续执行下面的代码如果超出了等待时间,则抛出异常TimeoutException。
driver.implicity_wait(10):默认是0s等待,设置之后的值是最大超时时间
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
# 隐式等待,设置10s的超时时间
driver.implicitly_wait(10)
注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部不断的刷新页面去寻找我们需要的元素,在使用AJAX技术的页面自动化测试中,建议使用。
3. 显式等待
就是明确的要等到某个元素的出现或者是某个元素的可点击等条件,等到就可以返回元素对象;在超时时间到达之后仍未等到,那么就抛出TimeoutException。(简而言之,就是直到元素出现才去操作,如果超时则报异常)。
先来看一下显式等待的语法,然后我们在分别解析:
element = WebDriverWait(driver,10,0.5,ignored_exceptions=None).until(EC.presence_of_element_located((By.ID,“kw”)),“找不到”)
- WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
使用的话需要先导包:from selenium.webdriver.support.ui import WebDriverWait- driver:浏览器驱动
- timeout:最长超时时间,默认以秒为单位
- poll_frequency:检测的间隔(步长)时间,默认为0.5S
- ignored_exceptions:超时后的异常信息,默认情况下抛NoSuchElementException异常
该WebDriverWait类中提供两个方法用于处理等待的条件:
- until(method, message=’ '):调用该方法提供的驱动程序作为一个参数,直到返回值为True
- until_not(method, message=’ '):调用该方法提供的驱动程序作为一个参数,直到返回值为False
- until(method, message=’ ')
直到满足某一个条件method,返回method返回的结果,否则就抛出TimeoutException。
该method参数,我们采用Expected Conditions 类提供的预期条件判断方法。 - Expected Conditions()
需要先导包:from selenium.webdriver.support import expected_conditions as EC
该类提供的预期条件判定方法,常见的有:- title_is:判断当前页面的title是否等于预期
- title_contains:判断当前页面的title是否包含预期字符串
- presence_of_element_located:判断某个元素是否被加到了dom树里,并不代表该元素一定可见
- visibility_of_element_located:判断某个元素是否可见.可见代表元素非隐藏,并且元素的宽和高都不等于0
- alert_is_present:判断页面上是否存在alert
- text_to_be_present_in_element:判断某个元素中的text是否包含了预期的字符串
- text_to_be_present_in_element_value:判断某个元素中的value属性是否包含了预期的字符串
- element_to_be_selected:判断某个元素是否被选中了,一般用在下拉列表
- By()
需要导包:from selenium.webdriver.common.by import By
隐式等待的案例
需求,等待百度首页百度一下是否被加载(加载到DOM),成功则返回元素对象并执行点击操作,否则抛出异常。
from selenium import webdriver
#ui--模块,WebDriverWait是个类
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
# driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
try:
driver.find_element_by_id("kw").send_keys("selenium")
element = WebDriverWait(driver,10,0.5,ignored_exceptions=None).until(EC.presence_of_element_located((By.ID,"su")),"找不到")
element.click()
time.sleep(3)
except Exception as e:
print(e)
driver.quit()
总结
若同时设置了隐式等待和显示等待,则以隐式等待为第一优先级,也就是说,若隐式等待时间大于显示等待,显示等待时间设置无效,因为driver若找不到元素,会先等待隐式等待的时间
time.sleep()是强制休眠,只要执行到这句代码,就会等待