元素的定位
查找元素:find_element(方式,“元素”),表示查找一个元素;
find_element(方式,“元素”),表示查找多个元素。
###使用查找多个元素
ChromeIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromeIns))
driver.get("https://www.baidu.com")
ret=driver.find_elements(By.CSS_SELECTOR,"#hotsearch-content-wrapper > li")
for i in ret:
print(i.text)#获取每个元素对应的文本信息
driver.quit()
如果想要获取页面多个元素时,可以使用find_elements。
查找元素的方式:选择器、xpath、ID、class_name
常⽤的主要由cssSelector和xpath
cssSelector
选择器的功能:选中⻚⾯中指定的标签元素
选择器的种类分为基础选择器和复合选择器,常⻅的元素定位⽅式可以通过id选择器和⼦类选择器来进⾏定位.
之前是ID选择器来定位“百度一下”按钮。
定位百度⾸⻚的“百度热搜”元素,可以使⽤通过id选择器和⼦类选择器进⾏定位:#s-hotsearch-wrapper > div
“搜索输⼊框元素”:#kw
“百度⼀下按钮”:#su
xpath
XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点。
xpath使⽤路径表达式来选择xml⽂档中的节点
xpath语法中:
//* : 表示获取HTML页面所有的节点
[@...] : 实现节点属性的匹配
例如://#[@id='kw']
/ : 获取一个节点中的直接子节点
//[指定节点] : 获取HTML页面指定的节点
.. : 获取一个页面中的父节点
鼠标直接复制可以解决问题,但是难免后面会需要手动的修改/编写选择器元素、xpath元素,因此我们堆选择器和xpath要有一定的了解。
操作测试对象
获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清除、获取⽂本。
- 点击/提交按钮
click()
# 方法一
# driver.find_element(By.CSS_SELECTOR,"#su").click()
# 方法二
# element=driver.find_element(By.CSS_SELECTOR,"#su)
# element.click()
页面上任意位置/元素都可以实行点击操作。
# #1.打开浏览器-----驱动管理
ChromeIns=ChromeDriverManager().install()
# ###创建谷歌浏览器驱动对象
driver=webdriver.Chrome(service=Service(ChromeIns))
time.sleep(2)
# #2.输入百度网址------https://www.baidu.com
driver.get("https://www.baidu.com")
time.sleep(2)
# time.sleep(2)
# #4.点击“百度一下”按钮
driver.find_element(By.CSS_SELECTOR,"#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title").click()
time.sleep(2)
# #5.关闭浏览器
driver.quit()
- 模拟按键输入
send_keys("")
# #1.打开浏览器-----驱动管理
ChromeIns=ChromeDriverManager().install()
# ###创建谷歌浏览器驱动对象
driver=webdriver.Chrome(service=Service(ChromeIns))
time.sleep(2)
# #2.输入百度网址------https://www.baidu.com
driver.get("https://www.baidu.com")
time.sleep(2)
# time.sleep(2)
driver.find_element(By.CSS_SELECTOR,"#kw").send_keys("百度翻译")
time.sleep(2)
# #5.关闭浏览器
driver.quit()
这种也可以写出俩种方式。
模拟键盘输入,因此键盘上可以输入的内容都可以填写上去。
- 清楚文本内容
输入文本又需要更换文本,就需要使用clear()
如果只是这样的代码会出现这样的情况,所以需要使用clear()
连续的send_keys()会将多次输入的内容拼接在一起。
这里就进行了清除。
-
获取文本信息
获取文本信息:Text
获取到元素对应的文本信息后,通过断言判断文本信息是否符合预期。
【注意】特殊情况,元素属性值不等于文本信息
获取属性值需要使用方法 get_attribute(属性)。
- 获取文本标题
获取文本标题:title
- 获取当前页面URL
获取当前页面URL:current_url
适用场景:页面元素可点击跳转的情况下,用来检测跳转的结果是否是正确的。
窗口
窗口的切换
-
打开⼀个新的⻚⾯之后获取到的title和URL仍然还是前⼀个⻚⾯的?
当我们⼿⼯测试的时候,我们可以通过眼睛来判断当前的窗⼝是什么,但对于程序来说它是不知道当前最新的窗⼝应该是哪⼀个。对于程序来说它怎么来识别每⼀个窗⼝呢?每个浏览器窗⼝都有⼀个唯⼀的属性句柄(handle)来表⽰,我们就可以通过句柄来切换。
- 获取当前页面句柄
driver.current_window_handle
- 获取所有页面的句柄
driver.window_handles
- 切换句柄
curHandle = driver.curret_window_handle
allHandle = driver.window_handles
// 遍历所有的句柄,切换新的页面
for handle in allHandle:
if handle != curHandle:
driver.switch_to.window(handle)
在测试中,通常情况下一般会打开俩个标签页实现标签页的切换测试,更多时候直接输入对应页面的链接在当前标签页下进行测试。
若是页面发送跳转后,未打开新的标签,不需要切换。
窗口大小的设置
#窗口最大化
driver.maximize_window()
#窗口最小化
driver.minimize_window()
#窗口全屏
driver.fullscreen_window()
#手动设置窗口大小
driver.set_window_size(1024,768)
仅做了解即可,在自动化测试中不关注页面的变换。
屏幕截图
我们的自动化脚本一般部署在机器上自动的运行,如果出现报错,我们是不知道的,可以通过抓拍来记录当时的错误场景。
当自动化运行报错时,仅仅通过终端的错误提示给到的有用信息是一定的,若是能将当时的页面截图拍下来,能更好的定位问题并解决问题。
driver.save_screenshot(”../images/image.png“)
屏幕截图保存下来的图片名称(路径+名称);
test.png:图片文件保存在脚本文件所在路径下,图片名称为test.png
由于图片给定的图片名称是固定的,当我们多次运行自动化脚本时,历史的图片将会被覆盖。
- 高阶版本
filename="autotest-"+datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S')+'.png'
driver.save_screenshot(“../images/”+filename)
由于文件名中不能包含空格,因此还需要将时间进行格式化
关闭窗口
driver.close();
注意:窗口关闭后driver需要重新定义
- driver.close():退出一个窗口
- driver.quit():退出一个浏览器
当执行driver.quit(),所有的标签页都会退出。
【注意】关闭窗口不等于关闭浏览器,因此在执行driver.close()之和仍然需要调用driver.quit()
弹窗
弹窗是在⻚⾯是找不到任何元素的,这种情况怎么处理?使⽤selenium提供的Alert接⼝
警告弹窗
确认弹窗
提示弹窗
这三个弹窗页面上定位不到弹窗元素;同时出现了弹窗,页面其他的元素也无法定位。
当页面出现了弹窗,必须先处理弹窗之和才能帝国为到页面的元素。
- 切换到弹窗
- 关闭弹窗(点击确定/取消)
alert = driver.switchTo.alert
// 确认
alert.accept()
//取消
alert.dismiss()
// 输入框
alert.send_keys("hello")
等待
【注意】:注意字符”\\“
由于脚本执行的速度非常快,而页面要加载的资源比较多,因此当脚本执行到该行代码时页面还没有渲染完成,因此找不到该元素,当添加了time.sleep(3)之和,页面已经在3秒内加载完成,此时再取查找该元素就可以找到。
通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:
强制等待
time.sleep() // 单位为秒,当调用该方法时,程序会直接阻塞,等待指定秒数后继续执行后面的代码
- 优点:使用简单,调试的时候比较有效
- 缺点:影响运行效率,浪费大量时间。
当有1个数量较少的测试脚本时,添加强制等待消耗的时间不过数秒。实际在工作中,业务场景比较复杂时,要添加的自动化脚本非常多,通常来说自动化测试脚本数量可达到上百。
隐式等待
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错。
implicitly_wait() 参数:秒
隐式等待的生命周期:隐式代码作用域是整个脚本的所有元素,即只要driver对象没有被释放掉driver.quit(),隐式等待一直生效。
【注意】若等待指定秒数查找不到元素,就会报错。
优点:智能等待,作用于全局
显示等待
显示等待也是一种智能等待,在指定超时时间范围内只要满足操作的条件就会继续执行后续代码。
WebDriverWait(driver, sec).until(functions)
functions: 涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类
wait = WebDriverWait(driver, 2)
wait.until(expected_conditions.invisibility_of_element((By.CSS_SELECTOR,"... ..."))
invisibility_of_element(locator):检查元素不可见性;
visibility_of_element(locator):检查元素的可见性
方法 | 说明 |
---|---|
title_is(title) | 检查页面标题的期望值 |
title_contains(title) | 检查标题是否包含区分大小写的子字符串的期望值 |
visibility_of_element_located(locator,str) | 检查元素是否存在于页面的DOM上并且可见的期望值 |
presence_of_element_located(locator,str) | 用于检查元素是否存在于页面的DOM上的期望值 |
visibility_of(element) | 检查已知存在于页面DOM上的元素是否可见的期望 |
alert_is_present() | 检查是否出现弹窗 |
优点:显示等待是智能等待,可以自定义显示等待的条件,操作灵活。
缺点:写法复杂
【注意】显示等待可以等待隐式等待无法处理的问题(例如:弹窗)
隐式等待与显示等待不建议一起使用,可能导致出现不可预测的时间。但是强制等待可以任意配合隐式等待或者等待来使用。
浏览器导航
打开网址
driver.get("")
浏览器的前进、后退和刷新
- driver.back()
- driver.forward()
- driver.refresh()
文件上传
点击⽂件上传的场景下会弹窗系统窗⼝,进⾏⽂件的选择。selenium⽆法识别⾮web的控件,上传⽂件窗⼝为系统⾃带,⽆法识别窗⼝元素。但是可以使⽤sendkeys来上传指定路径的⽂件,达到的效果是⼀样的。
当通过页面元素调起上传的窗口后,文件窗口不能被作为元素选中,此时要解决的问题是,如何定位要弹窗并选中文件。
driver.find_element(By.CSS_SELECTOR,"... ... ").send_keys("文件")
通过send_keys()方法可以实现将本地文件夹中的文件上传上来(注意要写完整的文件路径+文件名)
浏览器参数设置
设置无头参数
创建浏览器对象时,可以传递必要的参数
- 无头模式:程序在后端运行,界面看不到页面的表现
options = weddriver.ChromeOptions()
options.add_argument("-headless")//设置参数,-headless:无头模式
自动化打开浏览器默认情况下为有头模式
driver=webdriver.Chrome
(service=ChromeService(ChromeDriverManager().install()),options=options)
页面加载策略
options.page_load_strategy='加载方式'
页面加载方式主要有三种类型:
策略 | 说明 |
---|---|
normal | 默认值,等待所有资源下载(主体框架、图片、视频等资源) |
eager | DOM访问已经准备就绪,但诸如图像的其他资源可能仍在加载 |
none | 完全不会阻塞WebDriver |
driver.get()的方法会一直等待页面加载完成。但是实际上主页面加载完成之就会继续执行自动化,若一直等待的话可能会造成页面超时,元素找不到问题。