
为什么要封装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 封装的语法一致性。
总结:
感谢每一个认真阅读我文章的人!!!
我个人整理了我这几年软件测试生涯整理的一些技术资料,包含:电子书,简历模块,各种工作模板,面试宝典,自学项目等。欢迎大家点击下方名片免费领取,千万不要错过哦。

文档获取方式:
加入我的软件测试交流群:632880530免费获取~(同行大佬一起学术交流,每晚都有大佬直播分享技术知识点)
这份文档,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
以上均可以分享,只需要你搜索vx公众号:程序员雨果,即可免费领取