• poium测试库之JavaScript API封装原理


    为什么要封装JavaScript的API?

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

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

    1. # =====封装代码======
    2. class Page(object):
    3. def __init__(self, driver):
    4. self.driver = driver
    5. def set_text(self, css_selector, value):
    6. """
    7. JavaScript API, Only support css positioning
    8. Simulates typing into the element.
    9. """
    10. js = """var elm = document.querySelector("{css}");
    11. elm.style.border="2px solid red";
    12. elm.value = "{value}";""".format(css=css_selector(), value=value)
    13. self.driver.execute_script(js)
    14. def click(self, css_selector):
    15. """
    16. JavaScript API, Only support css positioning
    17. Click element.
    18. """
    19. js = """var elm = document.querySelector("{css}");
    20. elm.style.border="2px solid red";
    21. elm.click();""".format(css=css_selector())
    22. self.driver.execute_script(js)
    23. class CSSElement(object):
    24. def __init__(self, css):
    25. self.css = css
    26. def __call__(self):
    27. return self.css
    28. # =======调用代码==============
    29. from selenium import webdriver
    30. class baiduPage(Page):
    31. search_input = CSSElement("#kw")
    32. search_button = CSSElement("#su")
    33. dr = webdriver.Chrome()
    34. dr.get("http://www.baidu.com")
    35. page = baiduPage(dr)
    36. page.set_text(page.search_input, "poium")
    37. page.click(page.search_button)
    38. dr.close()

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

    1. page.set_text()
    2. page.click()

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

    1. page.search_input
    2. page.search_button

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

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

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

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

    新的设计思路
    直到前几天又重新学习了Python的 __get__ 和 __set__ 内置方法,才把这个问题解决。

    1. # =====封装代码======
    2. class Page(object):
    3. def __init__(self, driver):
    4. self.driver = driver
    5. class CSSElement(object):
    6. driver = None
    7. def __init__(self, css):
    8. self.css = css
    9. def __get__(self, instance, owner):
    10. if instance is None:
    11. return None
    12. global driver
    13. driver = instance.driver
    14. return self
    15. def set_text(self, value):
    16. global driver
    17. driver.execute_script("""var elm = document.querySelector("{css}");
    18. elm.style.border="2px solid red";
    19. elm.value = "{value}";""".format(css=self.css, value=value))
    20. def click(self):
    21. global driver
    22. driver.execute_script("""var elm = document.querySelector("{css}");
    23. elm.style.border="2px solid red";
    24. elm.click();""".format(css=self.css))
    25. # =======调用代码==============
    26. from selenium import webdriver
    27. class baiduPage(Page):
    28. search_input = CSSElement("#kw")
    29. search_button = CSSElement("#su")
    30. dr = webdriver.Chrome()
    31. dr.get("http://www.baidu.com")
    32. page = baiduPage(dr)
    33. page.search_input.set_text("poium")
    34. page.search_button.click()
    35. dr.close()

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

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

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

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

     总结:
    感谢每一个认真阅读我文章的人!!!

     我个人整理了我这几年软件测试生涯整理的一些技术资料,包含:电子书,简历模块,各种工作模板,面试宝典,自学项目等。欢迎大家点击下方名片免费领取,千万不要错过哦。

     文档获取方式:

    加入我的软件测试交流群:632880530免费获取~(同行大佬一起学术交流,每晚都有大佬直播分享技术知识点)

    这份文档,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

    以上均可以分享,只需要你搜索vx公众号:程序员雨果,即可免费领取

  • 相关阅读:
    【MyBatis-Plus】条件构造器 & ActiveRecord
    ES6如何声明一个类?类如何继承?
    用Prophet在Python中进行时间序列预测
    行人重识别
    六、不root不magisk不xposed lsposed frida原生修改定位
    软件测试面试题之自动化测试题合集(金九银十必备)
    tqdm使用
    不熟练的模版集合
    MSTP+VRRP vlan接口作为网关(2)
    【MySQL入门指北】主从复制及读写分离
  • 原文地址:https://blog.csdn.net/yjt2045263063/article/details/133827542