zoukankan      html  css  js  c++  java
  • 转在Python中实现PageFactory模式

    转自: http://www.cnblogs.com/fnng/p/5092383.html

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

    import org.openqa.selenium.support.PageFactory;  
    
    ……

    例子,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中的元素定位是这样的:

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

    或者是这样的:

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

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

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

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

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

    复制代码
    __all__ = ['cacheable', 'callable_find_by', 'property_find_by']
    
    def cacheable_decorator(lookup):
        def func(self):
            if not hasattr(self, '_elements_cache'):
                self._elements_cache = {} # {callable_id: element(s)}
            cache = self._elements_cache
    
            key = id(lookup)
            if key not in cache:
                cache[key] = lookup(self)
            return cache[key]
            
        return func
    
    cacheable = cacheable_decorator
    
    _strategy_kwargs = ['id_', 'xpath', 'link_text', 'partial_link_text',
                        'name', 'tag_name', 'class_name', 'css_selector']
    
    def _callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs):
        def func(self):
            # context - driver or a certain element
            if context:
               ctx = context() if callable(context) else context.__get__(self) # or property
            else:
               ctx = getattr(self, driver_attr)
    
            # 'how' AND 'using' take precedence over keyword arguments
            if how and using:
                lookup = ctx.find_elements if multiple else ctx.find_element
                return lookup(how, using)
    
            if len(kwargs) != 1 or kwargs.keys()[0] not in _strategy_kwargs :
                raise ValueError(
                    "If 'how' AND 'using' are not specified, one and only one of the following "
                    "valid keyword arguments should be provided: %s." % _strategy_kwargs)
    
            key = kwargs.keys()[0]; value = kwargs[key]
            suffix = key[:-1] if key.endswith('_') else key # find_element(s)_by_xxx
            prefix = 'find_elements_by' if multiple else 'find_element_by'
            lookup = getattr(ctx, '%s_%s' % (prefix, suffix))
            return lookup(value)
    
        return cacheable_decorator(func) if cacheable else func
    
    def callable_find_by(how=None, using=None, multiple=False, cacheable=False, context=None, driver_attr='_driver', **kwargs):
        return _callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs)
    
    def property_find_by(how=None, using=None, multiple=False, cacheable=False, context=None, driver_attr='_driver', **kwargs):
        return property(_callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs))
    复制代码

    帖一下具体的例子:

    复制代码
    from pageobject_support import callable_find_by as find_by
    from selenium import webdriver
    
    class BaiduSearchPage(object):
     
        def __init__(self, driver):
            self._driver = driver
    
        search_box = find_by(id_="kw")
        search_button = find_by(id_='su')
     
        def search(self, keywords):
            self.search_box().clear()
            self.search_box().send_keys(keywords)
            self.search_button().click()
    
    
    if __name__ == '__main__':
        driver = webdriver.Chrome()
        driver.get("https://www.baidu.com")
        BaiduSearchPage(driver).search("selenium")
        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

  • 相关阅读:
    eclipse新建JSP页面报错:Multiple annotations found at this line解决方法
    yum 安装报错:*epel: mirrors.aliyun.comError: xzcompressionnot available
    shell脚本中定义路径变量出现的BUG
    Rsync 12种故障排查及思路
    定时清除 /var/log/massage 下的信息脚本文件
    企业集群架构之全网备份
    局域网的某个机器无法上网,的排错思路
    日志审计
    在VUE中使用富文本编辑器ueditor
    ABP框架使用 Swagger
  • 原文地址:https://www.cnblogs.com/saryli/p/5190134.html
Copyright © 2011-2022 走看看