九、Selenium执行JavaScript脚本

目录

  • 使用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脚本

  1. 按F12 键,点击Console
    image.png
  2. document.title,获取窗口标题
  • "百度一下,你就知道"`
  1. window.alert("hello selenium"),调用弹框
    image.png
  2. 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可以滑动到顶部
    image.png
  • 使用js脚本定位元素,document.getElementById("su"),便可定位带百度一下元素
    image.png
  • 使用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来操作。
  • 处理时间控件思路:
    1. 要取消日期的readonly属性
    2. 给value赋值
    • 写js代码来实现如上的1,2点,再使用webdriver对js进行处理
  • 测试案例二∶
  • 在Console中使用js脚本实现
    1. 将出发日期元素赋值给a,a = document.getElementById("train_date")
    2. 移除a的readonly属性,a.removeAttribute("readonly")
      image.png
    3. 给a重新赋值,a.value="2020-12-30"
      image.png
  • 使用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),移动到目标元素,类似于滑动查找

下一节:文件上传弹框处理,文件上传的自动化与弹框处理机制。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容