selenium scratch on dynamic page objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import string | |
from selenium.webdriver import Chrome | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support.ui import Select | |
CSS = By.CSS_SELECTOR | |
def split_case(n): | |
ret = [] | |
for c in str(n): | |
if c not in string.ascii_lowercase: | |
ret.append('_') | |
ret.append(c.lower()) | |
return ''.join(ret).strip('_') | |
class ParsePageMeta(type): | |
def __new__(cls, name, parents, dct): | |
def btn_field(find_fn): | |
def _click(self): | |
btn = find_fn(self) | |
btn.click() | |
return _click | |
def check_field(find_fn): | |
# page.my_checkbox() -> checked | |
# page.my_checkbox(False) -> unchecked | |
# page.my_checkbox(toggle=True) -> opposite | |
def _checker(self, check_on=True, toggle=None): | |
el = find_fn(self) | |
is_checked = el.is_selected() | |
if toggle is not None: | |
el.click() | |
else: | |
if check_on and not is_checked: | |
# always checked | |
el.click() | |
elif not check_on and is_checked: | |
# always unchecked | |
el.click() | |
return el | |
return _checker | |
def drop_field(find_fn): | |
def _getter(self): | |
return Select(find_fn(self)).first_selected_option.text | |
def _setter(self, value): | |
# find web element | |
el = Select(find_fn(self)) | |
# list of all the "text" values underneath the drop down | |
option_texts = map(lambda e: e.text, el.options) | |
# check if our "set to this" value is valid | |
if value not in option_texts: | |
raise ValueError('not a valid option in dropdown (%s), %s' % (self, value)) | |
# do it and return the underlying WebElement<Select> | |
return el.select_by_visible_text(value) | |
return property(_getter, _setter) | |
def text_field(find_fn): | |
def _getter(self): | |
return find_fn(self).text | |
def _setter(self, value): | |
find_fn(self).clear() | |
return find_fn(self).send_keys(value) | |
def _deleter(self): | |
return find_fn(self).clear() | |
return property(_getter, _setter, _deleter) | |
def as_element(selector): | |
def _as_element(self): | |
return self.driver.find_element(*selector) | |
return _as_element | |
create_by_type = { | |
'btn': btn_field, | |
'check': check_field, | |
'drop': drop_field, | |
'text': text_field, | |
} | |
all_selectors = list() | |
for key, value in dct.items(): | |
if not key.startswith('__'): | |
if not isinstance(value, tuple) or not By.is_valid(value[0]): | |
continue | |
all_selectors.append(value) | |
etype, ename = key.split('_') | |
fn = create_by_type.get(etype) | |
dct[ename] = find_e = as_element(value) | |
dct[split_case(ename)] = fn(find_e) | |
dct['SELECTORS'] = all_selectors | |
return super(ParsePageMeta, cls).__new__(cls, name, parents, dct) | |
def __init__(cls, name, parents, dct): | |
super(ParsePageMeta, cls).__init__(name, parents, dct) | |
class ParsePage(object): | |
__metaclass__ = ParsePageMeta | |
def __init__(self, driver): | |
self.driver = driver | |
class SearchPage(ParsePage): | |
text_Keywords = (CSS, 'input#keywordbox') | |
text_Zip = (CSS, 'input[type=text][name=zip]') | |
text_PriceLo = (CSS, 'input[name=min_price]') | |
text_PriceHi = (CSS, 'input[name=max_price]') | |
drop_Distance = (CSS, 'select[name=distance]') | |
drop_Seller = (CSS, 'select[name=type]') | |
btn_Submit = (CSS, 'input[type=image]') | |
def my_function(self): | |
print 'hi' | |
d = Chrome() | |
d.get('http://www.ksl.com/?nid=13') | |
page = SearchPage(d) | |
page('blake') # <-- breakpoint |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment