在Python中实现PageFactory模式

简介:

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

 

import org.openqa.selenium.support.PageFactory;  

……

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

  PythonSelenium)中没有这个类。 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

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

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

目录
相关文章
|
6天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
11天前
|
数据可视化 算法 JavaScript
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
本文探讨了如何利用图论分析时间序列数据的平稳性和连通性。通过将时间序列数据转换为图结构,计算片段间的相似性,并构建连通图,可以揭示数据中的隐藏模式。文章介绍了平稳性的概念,提出了基于图的平稳性度量,并展示了图分区在可视化平稳性中的应用。此外,还模拟了不同平稳性和非平稳性程度的信号,分析了图度量的变化,为时间序列数据分析提供了新视角。
28 0
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
|
2月前
|
算法 数据挖掘 Python
Python中的拟合技术:揭示数据背后的模式
Python中的拟合技术:揭示数据背后的模式
37 0
Python中的拟合技术:揭示数据背后的模式
|
2天前
|
Python
探索Python中的异步编程模式
【10月更文挑战第29天】在编程世界中,时间就是效率。Python的异步编程模式,就像是给程序装上了翅膀,让任务并行处理不再是梦想。本文将带你了解如何在Python中实现异步编程,解锁高效代码的秘密。
10 0
|
2月前
|
IDE JavaScript Java
Processing介绍及几个python模式下的案例
该文章介绍了Processing这一开源编程语言和环境,主要用于视觉艺术和设计领域,并提供了Python模式下的编程案例。
42 5
|
2月前
|
设计模式 安全 API
探索Python中的异步编程模式
【9月更文挑战第19天】在本文中,我们将深入探讨Python的异步编程世界。通过理解其背后的原理和实践应用,你将学会如何编写更加高效、响应更快的程序。文章将引导你从基础概念出发,逐步过渡到高级用法,确保你能够自信地运用异步特性来优化你的代码。
|
30天前
|
设计模式 机器学习/深度学习 算法
现代 Python:编写高效代码的模式、功能和策略(第 1 部分)
现代 Python:编写高效代码的模式、功能和策略(第 1 部分)
27 0
|
2月前
|
Python Windows
Python交互模式
Python交互模式。
16 1
|
3月前
|
存储 中间件 PHP
Python编程入门:从零到一的代码实践深入理解 PHP 中的中间件模式
【8月更文挑战第28天】本文旨在通过浅显易懂的方式,向初学者介绍Python编程的基础知识,并结合具体代码示例,带领读者一步步实现从零基础到能够独立编写简单程序的转变。文章将围绕Python语言的核心概念进行讲解,并通过实例展示如何应用这些概念解决实际问题。无论你是编程新手还是希望扩展技能的专业人士,这篇文章都将为你打开编程世界的大门。 【8月更文挑战第28天】在PHP的世界中,设计模式是构建可维护和可扩展软件的重要工具。本文将通过浅显易懂的语言和生动的比喻,带领读者深入理解中间件模式如何在PHP应用中发挥魔力,实现请求处理的高效管理。我们将一步步揭开中间件的神秘面纱,从它的定义、工作原理到
|
4月前
|
数据可视化 Python
时间序列分析是一种统计方法,用于分析随时间变化的数据序列。在金融、经济学、气象学等领域,时间序列分析被广泛用于预测未来趋势、检测异常值、理解周期性模式等。在Python中,`statsmodels`模块是一个强大的工具,用于执行各种时间序列分析任务。
时间序列分析是一种统计方法,用于分析随时间变化的数据序列。在金融、经济学、气象学等领域,时间序列分析被广泛用于预测未来趋势、检测异常值、理解周期性模式等。在Python中,`statsmodels`模块是一个强大的工具,用于执行各种时间序列分析任务。