• 第三十九基础:JavaScript在自动化测试中的应用


    一.窗口滚动

    1.用途:滑动web页面

    2.参数说明:

    x:屏幕向右移动的距离。

    y:屏幕向下移动的距离。

    def scrollTo(x, y):
        js = """
        window.scrollTo("{x}", "{y}")
        """.format(x=x, y=y)
        driver.execute_script(js)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二.移除属性

    1.用途:以下方法可以删除元素的任何属性,主要用来移除时间控件的readonly属性。

    2.参数说明:

    css::css表达式。

    index:索引值,默认0,标识第一个元素。

    attribute:元素的某个属性,比如value,name等。

    def remove_attribute(css, attribute, index=0):
        js = """
        var element = document.querySelectorAll("{css}")[{index}];
            element.removeAttribute("{attr}");
        """.format(css=css, index=index, attr=attribute)
        driver.execute_script(js)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三.高亮元素

    1.用途:方便用户查看当前操作的是哪个页面元素。

    2.参数说明:

    css:css表达式。

    index:索引值,默认0,标识第一个元素。

    def height_light(css, index=0):
        js = """
        var element = document.querySelectorAll("{css}")[{index}];
            element.style.border="2px solid red";
        """.format(css=css, index=index)
        driver.execute_script(js)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    四.点击元素

    1.用途:由于web自动化的最大问题就是稳定性比较差,有些时候使用selenium无法点击元素,因此可以使用JS实现元素的点击操作。

    2.参数说明:

    css:css表达式。

    index:索引值,默认0,标识第一个元素。

    def click(css, index=0):
        js = """var element = document.querySelectorAll("{css}")[{index}];
                   element.click();""".format(css=css, index=index)
        driver.execute_script(js)
    
    • 1
    • 2
    • 3
    • 4

    五.清除输入框内容

    1.用途:用来清除输入框的内容。

    2.参数说明:

    css:css表达式。

    index:索引值,默认0,标识第一个元素。

    def clear(css, index=0):
        js = """var element = document.querySelectorAll("{css}")[{index}];
                    element.value = "";""".format(css=css, index=index)
        driver.execute_script(js)
    
    • 1
    • 2
    • 3
    • 4

    六.输入内容

    1.用途:输入框中输入内容。

    2.参数说明:

    css:css表达式。

    value:待输入的数据。

    index:索引值,默认0,标识第一个元素。

    def input(self, css, value, index=0):
        js = """var element = document.querySelectorAll("{css}")[{index}];
                    element.value = "{value}";""".format(css=css, index=index, value=value)
        driver.execute_script(js)
    
    • 1
    • 2
    • 3
    • 4

    七.说明

    1.以上所有的JS操作,还可以结合selenium中的WebElement按照以下方式实现,因为JS中查找元素的方法有限,比如xpath定位,在js中不存在。

    2.如滚动页面参数说明:

    element:通过selenium中的定位方法查找到的WebElement元素对象。

    arguments[0]:代表execute_script()方法的第二个参数。

    def scrollTo(self, element, x, y):
        js = """
        arguments[0].scrollTo("{}", "{}")
        """.format(x, y)
        driver.execute_script(js, element)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    八.测试代码

    js_element.py

    class CssElement(object):
    
        driver = None
    
        def __init__(self, css, index=None, describe=None):
            self.css = css
            if index is None:
                self.index = 0
            else:
                self.index = index
            self.desc = describe
    
    
        def __get__(self, instance, owner):
            if instance is None:
                return None
            global driver
            driver = instance.driver
            return self
    
    
        def clear(self):
            """清除内容"""
            js = """var elm = document.querySelectorAll("{css}")[{index}];
                        elm.style.border="2px solid red";
                        elm.value = "";""".format(css=self.css, index=self.index)
            driver.execute_script(js)
    
    
        def input(self, value):
            """输入内容"""
            js = """var elm = document.querySelectorAll("{css}")[{index}];
                        elm.style.border="2px solid red";
                        elm.value = "{value}";""".format(css=self.css, index=self.index, value=value)
            driver.execute_script(js)
    
    
        def click(self):
            """点击元素"""
            js = """var elm = document.querySelectorAll("{css}")[{index}];
                       elm.style.border="2px solid red";
                       elm.click();""".format(css=self.css, index=self.index)
            driver.execute_script(js)
    
    
        def remove_attribute(self, attribute):
            """删除某个元素的属性,比如日期空间的readonly属性"""
            js = """
            var elm = document.querySelectorAll("{css}")[{index}];
                elm.removeAttribute("{attr}");
            """.format(css=self.css, index=self.index, attr=attribute)
            driver.execute_script(js)
    
    
        @staticmethod
        def remove_attr(element, attribute):
            js = """
            arguments[0].removeAttribute("{attr}");
            """.format(attr=attribute)
            driver.execute_script(js, element)
    
    
        @staticmethod
        def scrollTo(x, y):
            js = """
            window.scrollTo("{}", "{}")
            """.format(x, y)
            driver.execute_script(js)
    
    
        @staticmethod
        def window_scroll(element, x, y):
            js = """
            arguments[0].scrollTo("{}", "{}")
            """.format(x, y)
            driver.execute_script(js, element)
    
    
        def height_light(self):
            js = """
            var element = document.querySelectorAll("{css}")[{index}];
                element.style.border="2px solid red";
            """.format(css=self.css, index=self.index)
            driver.execute_script(js)
            
    
        @staticmethod
        def height_lig(element):
            js = """
            arguments[0].style.border="2px solid red";
            """
            driver.execute_script(js, element)
    
    
    if __name__ == '__main__':
        pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    九.用例

    test_js.py

    import time
    from selenium.webdriver.remote.webdriver import WebDriver
    import unittest
    from selenium import webdriver
    from javascript.js_element import CssElement
    
    
    class Base(object):
    
        window = CssElement
    
        def __init__(self, driver: WebDriver):
            self.driver = driver
    
    
        def load_url(self, url):
            return self.driver.get(url)
    
    
    class BaiDuPage(Base):
        search_input = CssElement("#kw", describe=u"百度搜索框")
        search_button = CssElement("#su", describe=u"百度按钮")
    
    
        def search(self):
            self.search_input.height_light()
            self.search_input.clear()
            # 为了看到效果
            time.sleep(2)
            self.search_input.input(u"linux超")
            time.sleep(2)
            self.search_button.height_light()
            self.search_button.click()
            time.sleep(2)
            self.window.scrollTo("0", "500")
            # 为了看到效果
            time.sleep(2)
    
    
    class ChinaRailway(Base):
    
        data_input = CssElement("#train_date", describe=u"日期控件")
    
        def input_date(self, date):
            self.data_input.height_light()
            self.data_input.remove_attribute("readonly")
            self.data_input.input(date)
            # 为了看到效果
            time.sleep(2)
    
    
    class TestJs(unittest.TestCase):
    
        def setUp(self):
            self.driver = webdriver.Firefox()
            self.driver.maximize_window()
            self.driver.implicitly_wait(20)
            self.bai_du_page = BaiDuPage(self.driver)
            self.china_railway = ChinaRailway(self.driver)
    
    
        def test_search(self):
            """百度搜索"""
            self.bai_du_page.load_url("https://www.baidu.com")
            self.bai_du_page.search()
            
    
        def test_china_railway(self):
            """12306日期"""
            self.china_railway.load_url("https://www.12306.cn/index/")
            time.sleep(5)  #
            self.china_railway.input_date("2021-01-01")
            
    
        def tearDown(self):
            self.driver.quit()
    
    
    if __name__ == '__main__':
        unittest.main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    1.执行效果及输出。
    在这里插入图片描述

    十.总结

    1.以上所有的操作仅支持CSS表达式, 当然可以修改替换querySelectorAll方法为getElementById,getElementByClassName等,但是需要注意使用getElementById时,不需要index参数。

  • 相关阅读:
    TCP和UDP的区别以及它们各自的优缺点
    不务正业,捣鼓了一个破网站,全过程记录
    【探索Linux】—— 强大的命令行工具 P.7(进程 · 进程的概念)
    32.Python面向对象(五)【描述符、运算符底层、装饰器:闭包-闭包参数-内置装饰器-类装饰器】
    CH58X/CH57X/V208的Broadcaster(广播者)例程讲解
    Oracle批量修改字段类型varchar2(2000)转clob
    QT线程池的使用
    一文教你如何发挥好 TDengine Grafana 插件作用
    私有化轻量级持续集成部署方案--04-私有代码仓库服务-Gitea
    Go语言开发环境安装,hello world!
  • 原文地址:https://blog.csdn.net/hyq413950612/article/details/126352104