Selenium WebDriver中执行JS语句那些事

2021年7月12日 476点热度 0人点赞 0条评论

图片

出品|51Testing软件测试网


Selenium WebDriver让我们轻松实现与浏览器的交互,通过页面元素定位、执行对应的元素操作及断言设置,这一系列的步骤开启了Web自动化脚本的创建。


相信大家对于元素定位及其执行并不陌生,今天我们就来聊一聊Selenium WebDriver中另一大特色JS语句的执行,即JavaScriptExecutor。


  ◆    

什么是JavaScriptExecutor


JavaScriptExecutor 是Selenium WebDriver提供的一个接口,它提供了一种通过WebDriver直接执行JavaScript的方式,在选定窗口或当前页面上运行 JavaScript 的方法。

如果你用的是Java语言,那么可以通过导入“org.openqa.selenium.JavascriptExecutor” 直接使用它;如果你用的是Python,那就更方便了,直接“from selenium import webdriver”即可。

  ◆    

为什么在Selenium中

使用JavaScriptExecutor

通常情况下我们会使用各种Web定位器来定位页面元素,例如id、name、XPath等。

但是如果这些定位器无法按预期工作,定位不到对应的元素,这时我们就可以通过JavaScriptExecutor来尝试解决这类问题。

同理,当我们对页面上某个元素执行点击操作时,最常见的就是driver.findElement(By.id(“button”)).click()。

 但是click()方法并非适用于所有Web浏览器,有时同一个Web控件在不同浏览器上的行为也有可能不同。

为了应对这类情况,JavaScriptExecutor同样是一个最优的解决方案,因为JS语句本身就是Web脚本语言,用来控制网页行为。

  ◆    

Selenium中使用JavaScriptExecutor场景介绍

图片
1

点击按钮

方法一:

  • Python版

driver.execute_script("document.getElementById('XXX').click()")

(左右滑动查看完整代码)

  • Java版

js.executeScript("document.getElementById('XXX').click();");

(左右滑动查看完整代码)

方法二:

  • Python版

driver.execute_script("arguments[0].click()",button)

(左右滑动查看完整代码)

  • Java版

js.executeScript("arguments[0].click();", button);

(左右滑动查看完整代码)

方法二中的arguments指的是execute_script()方法中js代码后面的所有参数,arguments[0]表示第一个参数,argument[1]表示第二个参数。

图片
2

在不使用sendKeys()方法的情况下

在文本框中键入文本

  • Python版

driver.execute_script("document.getElementById('XXX').value='someValue' ")

(左右滑动查看完整代码)

  • Java版

js.executeScript("document.getElementById('XXX').value='someValue';");

(左右滑动查看完整代码)

图片
3

通过值传递“真”|“假”来处理复选框

  • Python版

driver.execute_script("document.getElementById('XXX').checked=false")

(左右滑动查看完整代码)

  • Java版

js.executeScript("document.getElementById('enter element id').checked=false;");

(左右滑动查看完整代码)

图片
4

在Selenium WebDriver中

生成Alert弹框

  • Python版

driver.execute_script("alert('注册成功');")

(左右滑动查看完整代码)

  • Java版

js.executeScript("alert('注册成功');");

(左右滑动查看完整代码)

图片
5

使用Javascript刷新浏览器窗口

  • Python版

driver.execute_script("history.go(0)")

(左右滑动查看完整代码)

  • Java版

js.executeScript("history.go(0)");

(左右滑动查看完整代码)

图片
6

获取网页标题

  • Python版

driver.execute_script("return document.title")

(左右滑动查看完整代码)

  • Java版

js.executeScript("return document.title;").toString();

(左右滑动查看完整代码)

图片
7

获取当前域名

  • Python版

driver.execute_script("return document.domain")

(左右滑动查看完整代码)

  • Java版

js.executeScript("return document.domain;").toString();

(左右滑动查看完整代码)

图片
8

实现页面滚动效果

  • Python版

# 通过JS进行页面滚动至末尾  driver.execute_script("window.scrollBy(0,document.body.scrollHeight)")# 通过JS进行页面回滚至开始  driver.execute_script("window.scrollBy(0,-document.body.scrollHeight)")

(左右滑动查看完整代码)

  • Java版

# 通过JS进行页面滚动至末尾js.executeScript(“window.scrollBy(0,document.body.scrollHeight)”);# 通过JS进行页面回滚至开始js.executeScript(“window.scrollBy(0,-document.body.scrollHeight)”);

(左右滑动查看完整代码)

图片
9

获取整个页面的内容

  • Python版

driver.execute_script(return document.documentElement.innerText)

(左右滑动查看完整代码)

  • Java版

js.executeScript(" return document.documentElement.innerText;").toString();

(左右滑动查看完整代码)

  ◆    

Demo实战演练

我们以“大众点评”,通过Selenium Python+JavaScriptExecutor进行多版本迭代实战演练,获取首页网红餐厅信息。

图片
1

测试场景1

不通过JavaScriptExecutor,使用常规元素定位及操作实现:

(1) 通过Chrome浏览器,打开“大众点评”主页;

(2) 定位搜索框,搜索“网红餐厅”;

(3) 获取首页搜索结果中的全部餐厅名称;

(4) 获取获取首页“有团购”的餐厅名称;

(5) 获取获取首页“可订座”的餐厅名称;

(6) 关闭浏览器。

图片

测试脚本实现

(1)相关库的导入;

图片

(2)初始化Chrome驱动,开启大众点评首页,且窗口最大化;

图片

(3)通过ID定位搜索框,搜索“网红餐厅”;

图片

(4)这时由于搜索结果显示页面属于新开启的页面,我们需要切换到当前页面窗口;

图片

图片

(5)获取首页搜索结果中的所有“网红餐厅”名称;

图片

通过观察发现,首页中显示的餐厅共有15个,并且餐厅名称的XPath都有固定的规则,仅通过li的下标值的递增。

第一个餐厅名称的XPath:

//*[@id="shop-all-list"]/ul/li[1]/div[2]/div[1]/a/h4

(左右滑动查看完整代码)

最后一个餐厅名称的XPath:

//*[@id="shop-all-list"]/ul/li[15]/div[2]/div[1]/a/h4

(左右滑动查看完整代码)

所以通过range(1,16)循环获取当前页面上15个餐厅的名称:

图片

(6)获取获取首页前5个“有团购”的餐厅名称;

图片

图片

(7)获取获取首页前5个“可订座”的餐厅名称;

图片

图片

(8)关闭退出。

图片

运行结果

图片

图片

图片
2

测试场景2

通过JavaScriptExecutor实现上述场景。基于场景1,本场景中还增加演示通过JS获取页面标题、当前域名、执行页面滚动操作,实现Alert弹框操作效果。

测试脚本实现

(1)相关库的导入;

图片

(2)初始化Chrome驱动,开启大众点评首页,且窗口最大化;

图片

(3)通过JS在文本框中输入“网红餐厅”,通过JS执行搜索;

图片

(4)同场景一,需要切换到当前页面窗口(结果展示窗口);

图片

(5)通过执行JS,进行页面滚动操作,查看当前页面中的餐厅信息;

图片

(6)获取首页搜索结果中的所有“网红餐厅”名称;

图片

我们直接从页面获取餐厅名称JS Path,通过观察发现,不难发现首页餐厅名称的JS Path也是有规律的,仅通过li:nth-child的下标值的递增。

第一个餐厅名称的JS Path:

document.querySelector("#shop-all-list > ul > li:nth-child(1) > div.txt > div.tit > a > h4")

(左右滑动查看完整代码)

最后一个餐厅名称的JS Path:

document.querySelector("#shop-all-list > ul > li:nth-child(15) > div.txt > div.tit > a > h4")

(左右滑动查看完整代码)

在定位到元素后,我们需要获取该元素的文本信息,通过JS语句获取餐厅名称元素的文本信息方式如下:

return document.querySelector('#shop-all-list > ul > li:nth-child(1) > div.txt > div.tit > a> h4').innerText

(左右滑动查看完整代码)

由于querySelector()中的字符串内容比较长,建议将上面的JS命令进行拆分:

style = "#shop-all-list > ul > li:nth-child(1) > div.txt > div.tit > a> h4"  js_style = "return document.querySelector(" + "'" + style + "'" + ").innerText"

(左右滑动查看完整代码)

下面我们同样结合range(1,16)循环获取当前页面上所有餐厅的名称:

图片

(7)获取获取首页前5个“有团购”的餐厅名称,同理,我们通过定位“有团购”勾选框,获取其JS Path;图片

document.querySelector("body > div.section.Fix.J-shop-search > div.content-wrap > div.shop-wrap > div.content > div.filter-box.J_filter_box >div.filt-classify > a:nth-child(1) > i.icon-check")

(左右滑动查看完整代码)

获取前5个“有团购”餐厅名称代码如下:

图片

(8)获取获取首页前5个“可订座”的餐厅名称,同理,我们通过定位“可订座”勾选框,获取其JS Path;

图片

document.querySelector("body > div.section.Fix.J-shop-search > div.content-wrap > div.shop-wrap > div.content > div.filter-box.J_filter_box >div.filt-classify > a:nth-child(2) > i")

(左右滑动查看完整代码)

获取前5个“可订座”餐厅名称代码如下:

图片

(9)通过JS获取当前页面标题;

图片

(10)通过JS获取当前域名;

图片

(11)通过JS以弹框形式显示“查询成功”消息;

图片

(12)关闭退出。

图片

运行结果

图片

图片

图片
3

测试场景3(优化)

从场景2中可以看出,有三次都在获取当前页面中的餐厅名称,且获取名称所用到的JS代码非常相似,可见代码存在冗余情况。

为了后期能够有效维护代码,我们可以将获取餐厅名称的脚步单独拿出来,作为一个函数,每次需要的时候直接调用即可。

对需要重复使用的方法进行函数封装:

图片

完整代码如下:

图片

图片

图片

  ◆    

总结

JavaScriptExecutor让我们能够通过WebDriver在网页上执行JavaScript代码,在传统定位方式失效或者某些浏览器下元素执行方式失效的情况下,JavaScriptExecutor不失为一个最优的备选方案。在同等情况下,它还能使自动化脚本更高效地执行。

以上为大家分享了如何在Selenium WebDriver中使用JavascriptExecutor,通过对JavascriptExecutor常用方法的介绍,并结合具体场景演示了JS在Selenium WebDriver中的实际应用,希望能够给大家的测试工作带来帮助,感兴趣的读者不妨一试。

  ◆    

End

图片

推荐阅读

点击阅读☞这些大厂的内推高薪职位,一定不能错过!

点击阅读☞功能测试进阶,记一次简单的性能测试实践

点击阅读☞一种DevOps模式下UI自动化测试左移思路的探究

点击阅读☞工作效率起飞:Windows共享网盘三部曲

点击阅读☞35岁+要么牛哄哄,要么惨兮兮,测试员“沸”了…

图片
“阅读原文”一起来充电吧!

图片

83740Selenium WebDriver中执行JS语句那些事

这个人很懒,什么都没留下

文章评论