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

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

poium测试库之JavaScript API封装原理的更多相关文章

  1. poium测试库介绍

    poium测试库前身为selenium-page-objects测试库,我在以前的文章中也有介绍过:这可能是最简单的Page Object库,项目的核心是基于Page Objects实现元素定位的封装 ...

  2. Page Object设计模式(二)——poium测试库

    一.简介 poium是一个基于Selenium/appium的Page Object测试库,最大的特点是简化了Page层元素的定义. 项目地址:https://github.com/SeldomQA/ ...

  3. RF框架自定义测试库开发

    静态库 方法(methods)直接映射为关键字名称.关键字接受和方法相同的参数, 通过抛异常来 报告错误, 通过往标准输出里写入来写 log, 同时可以通过return 来返回结果. 创建步骤: ▲ ...

  4. 第一百三十五节,JavaScript,封装库--拖拽

    JavaScript,封装库--拖拽 封装库新增1个拖拽方法 /** tuo_zhuai()方法,将一个弹窗元素实现拖拽功能 * 注意:一般需要在css文件将元素里的某一个区块光标设置成提示可以拖拽, ...

  5. 第一百三十四节,JavaScript,封装库--遮罩锁屏

    JavaScript,封装库--遮罩锁屏 封装库新增1个方法 /** zhe_zhao_suo_ping()方法,将一个区块元素设置成遮罩锁屏区块 * 注意:一般需要在css文件将元素设置成隐藏 ** ...

  6. 第一百三十三节,JavaScript,封装库--弹出登录框

    JavaScript,封装库--弹出登录框 封装库,增加了两个方法 yuan_su_ju_zhong()方法,将获取到的区块元素居中到页面,chuang_kou_shi_jian()方法,浏览器窗口事 ...

  7. 第一百三十二节,JavaScript,封装库--下拉菜单

    JavaScript,封装库--下拉菜单 封装库,增加了3个方法 shu_biao_yi_ru_yi_chu()方法,给元素设置鼠标移入移出事件,接收两个参数,参数是移入和移出时的执行函数(包含代码) ...

  8. 第一百三十一节,JavaScript,封装库--CSS

    JavaScript,封装库--CSS 将封装库里的方法,改成了原型添加方法 增加4个方法 tian_jia_class()方法,给获取到的元素添加class属性,参数是class属性值,可以连缀1 ...

  9. 第一百三十节,JavaScript,封装库--连缀

    JavaScript,封装库--连缀 学习要点: 1.连缀介绍 2.改写库对象 本章我们重点来介绍,在调用库的时候,我们需要能够在前台调用的时候可以同时设置多个操作,比如设置CSS,设置innerHT ...

随机推荐

  1. React躬行记(3)——组件

    组件(Component)由若干个React元素组成,包含属性.状态和生命周期等部分,满足独立.可复用.高内聚和低耦合等设计原则,每个React应用程序都是由一个个的组件搭建而成,即组成React应用 ...

  2. 【Arduino】66种传感器模块系列实验(2)---光敏电阻模块

    实验二:光敏电阻传感器模块我手里这块是三针版的,挺秀气吧 光敏电阻是用硫化隔或硒化隔等半导体材料制成的特殊电阻器,其工作原理是基于内光电效应.光照愈强,阻值就愈低,随着光照强度的升高,电阻值迅速降低, ...

  3. 小白学python-day06-

    今天是day06,以下是学习内容总结: 但行努力,莫问前程. --------------------------------------------------------------------- ...

  4. nodejs 获取客户端 ip 地址

    应用场景: php:我们需要拿到用户客户端的ip信息,以识别用户位置,但现在我们拿到的地址永远是杭州 前端:我查一下,稍等 .... 明白了,我们加了一层 node 服务器,服务器在杭州,你们拿到的是 ...

  5. Python解释器安装教程和环境变量配置

    Python解释器安装教程和环境变量配置 Python解释器安装 登录Python的官方网站   https://www.python.org/  进行相应版本的下载. 第一步:根据电脑系统选择软件适 ...

  6. GitHub 用户排行榜

    排行榜预览网址:Github | Githack | UNPKG | Gitee Github 中国用户排名,全球仓库 Star 最多排名,通过 Github API v3 来生成页面数据,排行榜预览 ...

  7. 破解EFCore扩展Dll --- Z.EntityFramework.Extensions.EFCore

    安装 Z.EntityFramework.Extensions.EFCore Install-Package Z.EntityFramework.Extensions.EFCore -Version ...

  8. .net持续集成测试篇之Nunit文件断言、字符串断言及集合断言

    使用前面讲过的方法基本上能够完成工作中的大部分任务了,然而有些功能实现起来还是比较麻烦的,比如说字符串相等性比较不区分大小写,字符串是否匹配某一正则规则,集合中的每一个(某一个)元素是否符合特定规则等 ...

  9. springboot管理类,springboot注入类

    springboot管理类,springboot注入类 定义一个配置类,添加@Configuration注解,EvaluatorTemplate代表你需要注入的第三方类 @Configuration ...

  10. Java集合系列(四):HashMap、Hashtable、LinkedHashMap、TreeMap的使用方法及区别

    本篇博客主要讲解Map接口的4个实现类HashMap.Hashtable.LinkedHashMap.TreeMap的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 ...