https://github.com/mattfair/SeleniumFactory-for-Python
___没学习的愧疚感,啃老族
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))
test.py
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()