关于 PageFactory 的概念主要是Java中内置了PageFactory类。

  1. import org.openqa.selenium.support.PageFactory;
  2.  
  3. ……

例子,http://libin0019.iteye.com/blog/1260090

  Python(Selenium)中没有这个类。 PageFactory 的概念和Page Object应该类似,属于一种设计模式。所以并不局限于语言及场景。于是,好奇,既然Java有,那Python也应该有类似的玩法。还真让我给找到了类似的实现。

原文在此:https://jeremykao.wordpress.com/2015/06/10/pagefactory-pattern-in-python/

于是,就借助谷歌翻译加代码运行,弄懂了这哥们想要利用PageFactory 模式实现个什么东西,为了便于你的理解,我这里搬运过来给下结论。

selenium in python中的元素定位是这样的:

  1. find_element_by_id("kw")
  2. find_element_by_xpath("//*[@id='kw']")

或者是这样的:

  1. from selenium.webdriver.common.by import By
  2.  
  3. find_element(By.ID,"kw")
  4. find_element(By.XPATH,"//*[@id='kw']")

通过PageFactory 模式的实现可以把元素定位变成这样的:

  1. from pageobject_support import callable_find_by as find_by
  2.  
  3. find_by(id_="kw")
  4. find_by(xpath="//*[@id='kw']")

别看小小的改动,它其实使代码更容易的阅读和理解。

核心实现就是pageobject_support.py文件:

  1. __all__ = ['cacheable', 'callable_find_by', 'property_find_by']
  2.  
  3. def cacheable_decorator(lookup):
  4. def func(self):
  5. if not hasattr(self, '_elements_cache'):
  6. self._elements_cache = {} # {callable_id: element(s)}
  7. cache = self._elements_cache
  8.  
  9. key = id(lookup)
  10. if key not in cache:
  11. cache[key] = lookup(self)
  12. return cache[key]
  13.  
  14. return func
  15.  
  16. cacheable = cacheable_decorator
  17.  
  18. _strategy_kwargs = ['id_', 'xpath', 'link_text', 'partial_link_text',
  19. 'name', 'tag_name', 'class_name', 'css_selector']
  20.  
  21. def _callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs):
  22. def func(self):
  23. # context - driver or a certain element
  24. if context:
  25. ctx = context() if callable(context) else context.__get__(self) # or property
  26. else:
  27. ctx = getattr(self, driver_attr)
  28.  
  29. # 'how' AND 'using' take precedence over keyword arguments
  30. if how and using:
  31. lookup = ctx.find_elements if multiple else ctx.find_element
  32. return lookup(how, using)
  33.  
  34. if len(kwargs) != 1 or kwargs.keys()[0] not in _strategy_kwargs :
  35. raise ValueError(
  36. "If 'how' AND 'using' are not specified, one and only one of the following "
  37. "valid keyword arguments should be provided: %s." % _strategy_kwargs)
  38.  
  39. key = kwargs.keys()[0]; value = kwargs[key]
  40. suffix = key[:-1] if key.endswith('_') else key # find_element(s)_by_xxx
  41. prefix = 'find_elements_by' if multiple else 'find_element_by'
  42. lookup = getattr(ctx, '%s_%s' % (prefix, suffix))
  43. return lookup(value)
  44.  
  45. return cacheable_decorator(func) if cacheable else func
  46.  
  47. def callable_find_by(how=None, using=None, multiple=False, cacheable=False, context=None, driver_attr='_driver', **kwargs):
  48. return _callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs)
  49.  
  50. def property_find_by(how=None, using=None, multiple=False, cacheable=False, context=None, driver_attr='_driver', **kwargs):
  51. return property(_callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs))

然后,我再帖一下具体的例子:

  1. from pageobject_support import callable_find_by as find_by
  2. from selenium import webdriver
  3.  
  4. class BaiduSearchPage(object):
  5.  
  6. def __init__(self, driver):
  7. self._driver = driver
  8.  
  9. search_box = find_by(id_="kw")
  10. search_button = find_by(id_='su')
  11.  
  12. def search(self, keywords):
  13. self.search_box().clear()
  14. self.search_box().send_keys(keywords)
  15. self.search_button().click()
  16.  
  17. if __name__ == '__main__':
  18. driver = webdriver.Chrome()
  19. driver.get("https://www.baidu.com")
  20. BaiduSearchPage(driver).search("selenium")
  21. driver.close()

同样封装了8种定位方法:

  • id_ (为避免与内置的关键字ID冲突,所以多了个下划线的后缀)
  • name
  • class_name
  • css_selector
  • tag_name
  • xpath
  • link_text
  • partial_link_text

当然,这只是PageFactory 模式的一种表现形式而已。除此之外,我还找到了另外一个PageFactory模式的例子。

https://github.com/mattfair/SeleniumFactory-for-Python

这哥们是利用PageFactory模式把驱动的创建做了封装,感兴趣可以了解一下。

搬运完了,准备过年。新年快了~!!!

在Python中实现PageFactory模式的更多相关文章

  1. 转在Python中实现PageFactory模式

    转自: http://www.cnblogs.com/fnng/p/5092383.html 关于 PageFactory 的概念主要是Java中内置了PageFactory类. import org ...

  2. Python中的Bunch模式

    引用: 当树这样的数据结构被原型化(或者乃至于被定型)时,它往往会时一个非常有用而灵活的类型,允许我们在其构造器中设置任何属性.在这些情况下,我们会需要用到一种叫做“Bunch”的设计模式. clas ...

  3. Python 中的设计模式详解之:策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中“不见了,或者简化了”. ...

  4. Python中open文件的各种打开模式

    对于Python打开文件的模式,总是记不住,这次在博客里记录一下 r+: Open for reading and writing.  The stream is positioned  at  th ...

  5. python中文件操作的六种模式及对文件某一行进行修改的方法

    一.python中文件操作的六种模式分为:r,w,a,r+,w+,a+ r叫做只读模式,只可以读取,不可以写入 w叫做写入模式,只可以写入,不可以读取 a叫做追加写入模式,只可以在末尾追加内容,不可以 ...

  6. 简介Python设计模式中的代理模式与模板方法模式编程

    简介Python设计模式中的代理模式与模板方法模式编程 这篇文章主要介绍了Python设计模式中的代理模式与模板方法模式编程,文中举了两个简单的代码片段来说明,需要的朋友可以参考下 代理模式 Prox ...

  7. Python中关于txt的简单读写模式与操作

    Python中关于txt的简单读写操作 常用的集中读写模式: 1.r 打开只读文件,该文件必须存在. 2.r+ 打开可读写的文件,该文件必须存在. 3.w 打开只写文件,若文件存在则文件长度清为0,即 ...

  8. python中各种文件打开模式

    在python中,总的来说有三种大的模式打开文件,分别是:a, w, r 当以a模式打开时,只能写文件,而且是在文件末尾添加内容. 当以a+模式打开时,可以写文件,也可读文件,可是在读文件的时候,会发 ...

  9. python2.7高级编程 笔记二(Python中的描述符)

    Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...

随机推荐

  1. 【整理】--【GPIO】OK6410

    S3C6410的GPIO引脚相对来说比较多,而且大部分引脚都具有多重复用功能,如何在linux上用最简单的方式来控制GPIO这需要我们好好研究一下底层的代码了,其实方法有很多种,鉴于在操作系统端控制G ...

  2. centos yum 安装 mongodb 以及php扩展

    centos yum 安装 mongodb 以及php扩展 投稿:hebedich 字体:[增加 减小] 类型:转载 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用 ...

  3. Git 更换仓库地址

    github国内访问偶尔抽风速度太慢了,想把项目转到oschina上来,今天实践了一下,还是挺简单的. 1.  从原始地址 clone 一份不包含 work copy的仓库: git clone -- ...

  4. 扫描二维码判断移动设备(Android/ios),以及判断是否微信端扫描

    <section class="download"> <a href="apk地址" class="android" st ...

  5. Golang通过Thrift框架完美实现跨语言调用

    每种语言都有自己最擅长的领域,Golang 最适合的领域就是服务器端程序. 做为服务器端程序,需要考虑性能同时也要考虑与各种语言之间方便的通讯.采用http协议简单,但性能不高.采用TCP通讯,则需要 ...

  6. Task:取消异步计算限制操作 & 捕获任务中的异常

    Why:ThreadPool没有内建机制标记当前线程在什么时候完成,也没有机制在操作完成时获得返回值,因而推出了Task,更精确的管理异步线程. How:通过构造方法的参数TaskCreationOp ...

  7. Aspectj 实现Method条件运行

    最近我花了半个小时实现了一个Method的按自定义条件运行的plugin,Condition-Run.实现场景是由于我所工作的客户经常会是在同一个代码集上实现多个Brand,所以有些功能只会限制是几个 ...

  8. [安卓] 17、一个简单的例子学安卓侧滑设计——用开源slidingmenu

    效果如下: 下面是工程结构: 整个工程包括android-v7.SlidingMenu-lib和主工程SlidingMenuTest部分 其中前两个作为lib,后一个为主工程 主工程包含两个lib工程 ...

  9. 使用Notepad++开发C#,一个复杂点的csscript脚本

    使用Notepad++开发C#,一个复杂点的csscript脚本: //css_dir ..\..\lib; //css_ref Geb.Image.dll; //css_ref Geb.Image. ...

  10. js模版引擎handlebars.js实用教程——结束语

    返回目录 有了这些功能,[ajax+json+Handlebars]替代[vo+el表达式]不成问题,新时代的曙光已经来临,最佳解决方案在此,您还等什么? 教程到此结束...祝读者学习愉快... 小菜 ...