目录
- 使用selenium直接在当前页面中进行js交互
- 常用的几种操作使用js实现
js的处理
- Selenium能够执行js,这使得Selenium拥有更为强大的能力。既然能
执行js,那么js能做的事,Selenium应该大部分也能做 - 直接使用js操作页面,能解决很多click()不生效的问题
- 页面滚动到底部,顶部
- 处理富文本,时间控件的输入
Selenium中如何调用js
- 例如js代码:
window.alert('Selenium弹框测试')
a = document.getElementById('kw').value
document.title
JSON.stringify(performance.timing)
- selenium如何调用js, selenium提供了一个内置的方法
execute_script()
driver.execute_script("window.alert('Selenium弹框测试')")
driver.execute_script("a = document.getElementByld('kw').value;window.alert(a)")
- 如何返回呢?
driver.execute _script("return document.getElementById('kw').value")
在浏览器中执行js脚本
- 按F12 键,点击
Console
-
document.title
,获取窗口标题
- "百度一下,你就知道"`
-
window.alert("hello selenium")
,调用弹框
-
JSON.stringify(performance.timing)
,可以获取当前页面的部分性能数据,如加载速度等
{"connectStart":1618126096472,"navigationStart":1618126096415,"loadEventEnd":1618126097448,"domLoading":1618126096801,"secureConnectionStart":1618126096575,"fetchStart":1618126096423,"domContentLoadedEventStart":1618126097276,"responseStart":1618126096779,"responseEnd":1618126096984,"domInteractive":1618126097156,"domainLookupEnd":1618126096472,"redirectStart":0,"requestStart":1618126096653,"unloadEventEnd":0,"unloadEventStart":0,"domComplete":1618126097440,"domainLookupStart":1618126096430,"loadEventStart":1618126097440,"domContentLoadedEventEnd":1618126097288,"redirectEnd":0,"connectEnd":1618126096653}"
Selenium调用js实战
-
execute_script
:执行js -
return
: 可以返回js的返回结果 -
execute_script
: arguments传参
js处理-案例一-滑动、获取标题、获取页面性能
- 场景:页面显示的数据比较多,需要点击底部的对象,我们就需要把鼠标移动到底部,才可以点击对象
- 案例一:滑动到浏览器底部或者顶部
- 打开百度首页
- 输入搜索关键字
- 点击搜索后,跳转到搜索结果页滑动到底部点击’下一页’
- 获取页面标题和性能数据
- 使用js脚本来实现,在Console中输入
document.documentElement.scrollTop=10000
可以滑动到底部,将10000
改为0
可以滑动到顶部
- 使用js脚本定位元素,
document.getElementById("su")
,便可定位带百度一下
元素
- 使用js脚本获取页面标题,
document.title
- 使用js脚本获取页面性能,
JSON.stringify(performance.timing
- 使用Selenium实现如下:
from time import sleep
from selenium import webdriver
class TestJS:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(5)
def teardown(self):
self.driver.quit()
def test_js_scroll(self):
self.driver.get("http://www.baidu.com")
self.driver.find_element_by_id('kw').send_keys('selenium测试')
"""使用js脚本进行元素定位,如果要获取返回一定要加入return"""
element = self.driver.execute_script("return document.getElementById('su')")
element.click()
"""滑动到页面最底端"""
self.driver.execute_script("document.documentElement.scrollTop=10000")
sleep(2)
"""点击下一页按钮"""
self.driver.find_element_by_xpath("//*[@id='page']/div/a[10]").click()
sleep(3)
"""获取页面标题和部分性能数据"""
"""方法一:将js命令放在列表中逐个执行"""
# for code in ['return document.title', 'return JSON.stringify(performance.timing)']:
# print(self.driver.execute_script(code))
"""方法二:使用分号隔开js命令,在一条语句中执行,但是这时只返回第一个js命令的返回值"""
print(self.driver.execute_script("return document.title;return JSON.stringify(performance.timing)"))
Tips:使用遍历js脚本列表的方式能获取每个js脚本的返回值,但是分号隔开js脚本执行使用一条语句,只会获取第一个js脚本的返回值。
- 使用方法一的执行结果:所有js脚本的返回值都获取到
test_js.py::TestJS::test_js_scroll
============================= 1 passed in 11.66s ==============================
Process finished with exit code 0
PASSED [100%]selenium测试_百度搜索
{"connectStart":1618128452734,"navigationStart":1618128452484,"loadEventEnd":1618128453788,"domLoading":1618128453048,"secureConnectionStart":1618128452744,"fetchStart":1618128452698,"domContentLoadedEventStart":1618128453570,"responseStart":1618128452997,"responseEnd":1618128453153,"domInteractive":1618128453489,"domainLookupEnd":1618128452734,"redirectStart":0,"requestStart":1618128452921,"unloadEventEnd":0,"unloadEventStart":0,"domComplete":1618128453779,"domainLookupStart":1618128452734,"loadEventStart":1618128453779,"domContentLoadedEventEnd":1618128453581,"redirectEnd":0,"connectEnd":1618128452921}
- 使用方法二的执行结果:只有第一个js脚本的返回值
test_js.py::TestJS::test_js_scroll
============================= 1 passed in 10.57s ==============================
Process finished with exit code 0
PASSED [100%]selenium测试_百度搜索
js处理-案例二-时间控件
- 大部分时间控件都是readonly属性,需要手动去选择对应的时间,手
工测试中很容易做到,自动化中对控件的操作可以使用js来操作。 - 处理时间控件思路:
- 要取消日期的readonly属性
- 给value赋值
- 写js代码来实现如上的1,2点,再使用webdriver对js进行处理
- 测试案例二∶
- 打开网址:https://www.12306.cn/index/
- 修改出发日期为2020-12-30
- 打印出发日期
- 关闭网址
- 在Console中使用js脚本实现
- 将出发日期元素赋值给a,
a = document.getElementById("train_date")
- 移除a的readonly属性,
a.removeAttribute("readonly")
- 给a重新赋值,
a.value="2020-12-30"
- 将出发日期元素赋值给a,
- 使用Selenium脚本实现
def test_js_datetime(self):
self.driver.get("https://www.12306.cn/index/")
# 将出发元素赋值
time_element = "document.getElementById('train_date')"
# 打印修改前的日期
print(self.driver.execute_script(f"return {time_element}.value"))
# 移除元素的readonly属性
self.driver.execute_script(f"{time_element}.removeAttribute('readonly')")
# 修改元素的值
self.driver.execute_script(f"{time_element}.value='2020-12-30'")
sleep(2)
# 打印修改的日期
print(self.driver.execute_script(f"return {time_element}.value"))
- 执行结果
test_js.py::TestJS::test_js_datetime
============================= 1 passed in 14.60s ==============================
Process finished with exit code 0
PASSED [100%]2021-04-11
2020-12-30
常用js脚本
-
driver.execute_script("arguments[0].click();", element)
,点击操作 -
driver.execute_script("arguments[0].scrollIntoView();", element)
,移动到目标元素,类似于滑动查找
下一节:文件上传弹框处理,文件上传的自动化与弹框处理机制。