Selenium3自动化测试【34】执行JS脚本

1. 引言

页面上的操作,有时通过Selenium是无法实现的,如滚动条、时间控件等,此时就需要借助JavaScript来完成。JavaScript是一种脚本语言,它在客户端运行,即在浏览器上运行。
WebDriver提供了一个内置方法来操作JavaScript。
driver.execute_script(self,script,args)
可以通过两种方式在浏览器中执行JavaScript。


同步视频知识与系列知识内容,可关注:【公众号】:柒哥测试;【WX】:Lee-890;【视频号】:柒哥思维


1.1 在文档根级别执行JavaScript

在这种方式下,使用JavaScript提供的方法捕获想要的元素,然后声明一些操作并使用WebDriver执行此JavaScript。
例如:

JSScript = "document.getElementsByName('input')[1].click();"
driver.execute_script(JSScript)

1.2 在元素级别执行JavaScript

在这种方式下,使用WebDriver捕获想要使用的元素,然后使用JavaScript声明一些操作,并通过将web元素作为参数传递给JavaScript来使用WebDriver执行此JavaScript。
例如:

BtnName = driver.find_element_by_xpath("//input[@name=' go']")
driver.execute_script("arguments[0].click();", BtnName)

解释:

  1. WebDriver提供的xpath方法捕获元素
    BtnName = driver.find_element_by_xpath("//input[@name=' go']")
  2. JavaScript声明并对元素执行单击操作
    arguments[0].click()
  3. execute_script() 使用的JavaScript语句作为字符串值调用方法
    driver.execute_script("arguments[0].click();", BtnName)~~

当有多个JS操作时,可以如下书写代码:

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("http://cn.bing.com/")

SearchName = driver.find_element_by_xpath("//input[@name='q']")
BtnName = driver.find_element_by_xpath("//input[@name='go']")
driver.execute_script("arguments[0].value='bella'; arguments[1].click(); ",SearchName,BtnName)
sleep(3)
driver.quit()

注:
JS操作中,value='bella'是给元素赋值,click()是对元素进行单击。

2. JS操作日期控件

日期控件在网站上是经常遇到的,如12306网站、旅游订票网站(如携程、去哪儿等)、租车网站(如神州租车等)等。

1.1 常规日期控件的操作

我们拿神州租车官网,【上门取送】下租为例,如图所示。

当通过send_keys给时间控件赋值时,观察到只是把时间控件打开了,并没有选择设定的日期。采用JS赋值,则可以完成对时间控件的操作,代码如下:

from selenium import webdriver

driver = webdriver.Firefox()
driver.get("https://www.zuche.com")

#通过send_keys无法操作时间控件
# driver.find_element_by_xpath('//*[@id="fromDate"]').send_keys("2020-05-26")

# JS可以实现对时间控件的操作
DateJS="document.getElementById('fromDate').value='2020-05-26'"
driver.execute_script(DateJS)

通过上面的代码,观察到给日期控件赋值,是通过JS方法改掉了输入框的value值。

1.2 Readonly日期控件的操作

有些日期控件元素包含readonly属性,要想实现给readonly属性的日期控件赋值,需要先通过JS去掉readonly属性,然后再给日期控件赋值。
以12306官网为例,如图所示,打开出发日期控件,设定出发日期。

先通过WebDriver提供的send_keys()方法操作,代码如下:

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("https://www.12306.cn/index/")
sleep(5)

driver.find_element_by_xpath("//*[@id='train_date']").clear()
driver.find_element_by_xpath("//*[@id='train_date']").send_keys("2020-03-20")

代码运行后,观察到运行失败,代码运行clear()方法时就出错,错误如下。

driver.find_element_by_xpath("//*[@id='train_date']").clear()
Selenium.common.exceptions.InvalidElementStateException: Message: Element is read-only:


将代码优化为通过JS给时间控件元素赋值,代码如下:
from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("https://www.12306.cn/index/")

sleep(5)
driver.find_element_by_xpath("//*[@id='train_date']").clear()
DateJS="document.getElementById(' train_date ').value='2020-05-26'"
driver.execute_script(DateJS)

代码运行后,观察到同样是运行失败,报与使用send_keys()方法同样的错误。
通过FireFox的开发者工具,观察到,12306日期控件的属性中包含readonly属性,如图所示。

时间控件标签代码如下:

<input type="text" class="input inp-txt_select" value="2018-07-21" id="train_date" readonly="">

通过查看代码,看到该元素包含readonly属性后。需要借助JS先去掉元素的readonly属性,然后再赋值,代码如下:

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("https://www.12306.cn/index/")
sleep(5)

# 去掉readonly属性
JS = 'document.getElementById("train_date").removeAttribute("readonly")'
driver.execute_script(JS)

# 去掉readonly属性,通过clear,send_keys可正确运行
driver.find_element_by_xpath("//*[@id='train_date']").clear()
driver.find_element_by_xpath("//*[@id='train_date']").send_keys("2020-03-20")

运行代码后,可观察到成功给日期控件赋值。
上面的代码,也可通过JS方法改掉了输入框的value值,给日期控件直接赋值,代码如下:

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("https://www.12306.cn/index/")
sleep(5)

# 去掉readonly属性
JS = 'document.getElementById("train_date").removeAttribute("readonly")'
driver.execute_script(JS)

# 去掉readonly属性,通过send_keys可正确运行
# driver.find_element_by_xpath("//*[@id='train_date']").clear()
# driver.find_element_by_xpath("//*[@id='train_date']").send_keys("2020-03-20")
# 去掉readonly属性,借助JS赋值,可正确运行
driver.find_element_by_xpath("//*[@id='train_date']").clear()
DateJS="document.getElementById('train_date').value='2020-05-26'"
driver.execute_script(DateJS)

精讲视频

如果你觉的文章读的不过瘾,可以查看详细的视频教程。

测试学习路线如下

热销图书

图书京东、当当有售
京东图书地址
当当图书地址
0.9733767060093851.png

同步视频知识与系列知识内容,欢迎可关注:【公众号】:柒哥测试;或【WX】:Lee-890交流

posted @ 2022-05-19 08:52  BlaLeo  阅读(259)  评论(0编辑  收藏  举报