zoukankan      html  css  js  c++  java
  • poium测试库之JavaScript API封装原理

    poium一直我在维护的一个开源项目,它的定位是以极简的方式在自动化项目中Page Objects设计模式。我在之前的文章中也有介绍。

    本篇文章主要介绍一个JavaScript元素操作的封装原理。

    为什么要封装JavaScript的API?

    因为有些场景下Selenium提供的API并不能满足我们需求。比如,滑动浏览滚动条,控制元素的显示/隐藏,日历控件的操作等,都可以通过JavaScrip实现,而且Selenium为我们提供了 execute_script()方法可以用来运行JavaScrip脚本。

    旧的设计思路

    先看旧的设计代码和调用。

    # =====封装代码======
    class Page(object):
    
        def __init__(self, driver):
            self.driver = driver
    
        def set_text(self, css_selector, value):
            """
            JavaScript API, Only support css positioning
            Simulates typing into the element.
            """
            js = """var elm = document.querySelector("{css}");
                        elm.style.border="2px solid red";
                        elm.value = "{value}";""".format(css=css_selector(), value=value)
            self.driver.execute_script(js)
    
        def click(self, css_selector):
            """
            JavaScript API, Only support css positioning
            Click element.
            """
            js = """var elm = document.querySelector("{css}");
                       elm.style.border="2px solid red";
                       elm.click();""".format(css=css_selector())
            self.driver.execute_script(js)
    
    
    class CSSElement(object):
    
        def __init__(self, css):
            self.css = css
    
        def __call__(self):
            return self.css
    
    
    # =======调用代码==============
    from selenium import webdriver
    
    class baiduPage(Page):
        search_input = CSSElement("#kw")
        search_button = CSSElement("#su")
    
    
    dr = webdriver.Chrome()
    dr.get("http://www.baidu.com")
    page = baiduPage(dr)
    page.set_text(page.search_input, "poium")
    page.click(page.search_button)
    
    dr.close()
    

    如果你看不懂上面的封装代码的话,可以重点看下面的调用代码,针对元素的点击和输入。

    page.set_text()
    page.click()
    

    表示操作的方法,在Page类中实现。

    page.search_input
    page.search_button
    

    表示操作的对象,在Page的继承类baiduPage中定义。

    page.set_text(page.search_input, "poium")
    page.click(page.search_button)
    

    操作的动作操作的对象 都是以 page. 调用,万一我要操作的对象也命名为 click 那不就和操作的动作 傻傻分不清楚了, 所以,这样的语法不是很怪么?

    所以,这个问题一直困扰我挺久的,我一直没想到更好的设计。

    新的设计思路

    直到前几天又重新学习了Python的 __get____set__ 内置方法,才把这个问题解决。

    
    # =====封装代码======
    class Page(object):
    
        def __init__(self, driver):
            self.driver = driver
    
    
    class CSSElement(object):
    
        driver = None
    
        def __init__(self, css):
            self.css = css
    
        def __get__(self, instance, owner):
            if instance is None:
                return None
            global driver
            driver = instance.driver
            return self
    
        def set_text(self, value):
            global driver
            driver.execute_script("""var elm = document.querySelector("{css}");
                        elm.style.border="2px solid red";
                        elm.value = "{value}";""".format(css=self.css, value=value))
    
        def click(self):
            global driver
            driver.execute_script("""var elm = document.querySelector("{css}");
                       elm.style.border="2px solid red";
                       elm.click();""".format(css=self.css))
    
    
    # =======调用代码==============
    from selenium import webdriver
    
    class baiduPage(Page):
        search_input = CSSElement("#kw")
        search_button = CSSElement("#su")
    
    
    dr = webdriver.Chrome()
    dr.get("http://www.baidu.com")
    page = baiduPage(dr)
    page.search_input.set_text("poium")
    page.search_button.click()
    
    dr.close()
    

    如果看不懂封装代码的话,直接看调用代码。

    page.search_input.set_text("poium")
    page.search_button.click()
    

    page 表示页面; search_input 表示页面上的某个对象; set_text() 表示对象的动作。

    这样的语法是不是要比前面好了很多?而保持了与Selenium API 封装的语法一致性。

    项目地址:https://github.com/defnngj/poium

    做开源项目的生活就是这么朴实无华,且有趣!

  • 相关阅读:
    计算机中最重要的两个硬件是什么它们如何相互作用。
    音乐光盘
    下列各项包含多少位?
    下列包含多少字节?
    自测题‘
    自测题.
    python 并发编程多线程之进程池/线程池
    python 并发编程之多线程
    基于解决高并发生的产者消费者模型
    守护进程、互斥锁、进程间通信(IPC机制)
  • 原文地址:https://www.cnblogs.com/fnng/p/11415590.html
Copyright © 2011-2022 走看看