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

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

最新文章

  1. 源码之Queue
  2. New Plan!
  3. oracle的IMU和ora-01555
  4. Java抽象类接口、内部类题库
  5. Qt拖拽界面 (*.ui) 缩放问题及解决办法(在最顶层放一个Layout)
  6. Android wakelock机制
  7. app打包,发布(同步发生冲突)
  8. Java Swing 记事本代码
  9. Python3中urllib详细使用方法(header,代理,超时,认证,异常处理) 转
  10. requests-所有异常归类
  11. SpriteBuilder中关于大量CCB文件的数字命名建议
  12. 关于Mybatis的一些随笔
  13. TensorFlow资源整理
  14. 秒懂AOP
  15. 微信小程序如何玩转分销
  16. spring下Junit_jdbc回滚demo
  17. java 多线程 25 :线程和线程组的异常处理
  18. [shiro] - 怎样使用shiro?
  19. Eureka Server项目启动报错处理
  20. [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)

热门文章

  1. TencentTbs腾讯浏览服务 x5内核使用
  2. [leetcode] 120. Triangle (Medium)
  3. [02] HEVD 内核漏洞之栈溢出
  4. cesium 学习(六) 坐标转换
  5. C#中Thread.IsBackground 属性
  6. Intellij IDEA 打开文件tab数量限制的调整
  7. Python秒算24点,行还是不行?
  8. jQuery框架操作CSS
  9. 第十章 Fisco Bcos 权限控制下的数据上链实操演练
  10. 用JavaScript带你体验V8引擎解析标识符过程