Page object¶
Page object is common pattern for UI tests development. We offer our implementation.
Simple example¶
This code for demonstration of simple usage
import seismograph
from seismograph import selenium
suite = selenium.Suite(__name__)
class GoogleSearchPage(selenium.Page):
search_input = selenium.PageElement(
selenium.query(
selenium.query.INPUT,
name='q',
),
)
submit_button = selenium.PageElement(
selenium.query(
selenium.query.INPUT,
name='btnG',
),
)
@suite.register
def test_google_search(case, browser):
browser.go_to('http://google.com')
page = MyFirstPage(browser)
page.search_input.set('python')
page.submit_button.click()
if __name__ == '__main__':
seismograph.main()
Page, PageItem and PageElement. How and when to use.¶
Page, PageItem and PageElement class is a solid foundation to description html markup in your test code. Let look at html code...
<html>
<body>
<div id="top-menu">
<a href="/">Index page></a>
<a href="/about/">About Us</a>
</div>
<div id="content">
Something content...
</div>
<div id="footer">
<a href='/contacts/'>contacts</a>
</div>
</body>
</html>
How is it be described with help page object? See example
from seismograph.ext import selenium
class TopMenu(selenium.PageItem):
__area__ = selenium.query(
selenium.query.DIV,
id='top-menu',
)
index_page_link = selenium.PageElement(
selenium.query(
selenium.query.A,
href='/',
),
)
about_us_link = selenium.PageElement(
selenium.query(
selenium.query.A,
href='/about/',
),
)
go_to_index_page = selenium.PageElement(
index_page_link,
call=lambda we: we.click(),
)
go_to_about_us = selenium.PageElement(
about_us_link,
call=lambda we: we.click(),
)
class Footer(selenium.PageItem):
__area__ = selenium.query(
selenium.query.DIV,
id='footer',
)
contacts_link = selenium.PageElement(
selenium.query(
selenium.query.A,
href='/contacts/',
),
)
class MyPage(selenium.Page):
__url_path__ = '/'
top_menu = selenium.PageElement(TopMenu)
content_wrapper = selenium.PageElement(
selenium.query(
selenium.query.DIV,
id='content',
),
)
content = selenium.PageElement(
content_wrapper,
property=lambda we: we.text,
)
footer = selenium.PageElement(Footer)
Page element result¶
Page element does return first element of query. If you want to do it otherwise then should to use additional params.
from seismograph import selenium
class GoogleSearchPage(selenium.Page):
# get element of query by index
some_element = selenium.PageElement(
selenium.query(
selenium.query.A,
_class='some_class',
),
index=0,
)
# get list all elements of query
some_elements = selenium.PageElement(
selenium.query(
selenium.query.LI,
id='some_id',
),
is_list=True,
)
# set timeout to wait for first element of query
another_some_element = selenium.PageElement(
selenium.query(
selenium.query.A,
_class='some_class',
),
wait_timeout=5,
)
How to make element of result as callable¶
If you want to create call method for result, should to use “call” keyword argument for that.
from seismograph import selenium
class GoogleSearchPage(selenium.Page):
search_input = selenium.PageElement(
selenium.query(
selenium.query.INPUT,
name='q',
),
)
submit = selenium.PageElement(
selenium.query(
selenium.query.BUTTON,
name='btnG',
),
call=lambda we: we.click(),
)
It’s working so
>>> page = GoogleSearchPage(browser)
>>> page.search_input.set('some text')
>>> page.submit()
How to create web element class¶
If you want to wrap result then use decorator class for that.
from seismograph import selenium
class SubmitButton(selenium.PageItem):
def do_search(self):
self.we.click()
class GoogleSearchPage(selenium.Page):
search_input = selenium.PageElement(
selenium.query(
selenium.query.INPUT,
name='q',
),
)
submit_button = selenium.PageElement(
selenium.query(
selenium.query.BUTTON,
name='btnG',
),
we_class=SubmitButton,
)
It’s working so
>>> page = GoogleSearchPage(browser)
>>> page.search_input.set('some text')
>>> page.submit_button.do_search()
How to restrict area of DOM tree for query¶
You can to restrict area of DOM tree for search elements on page.
from seismograph import selenium
class MyPage(selenium.Page):
__area__ = selenium.query(
selenium.query.DIV,
_class='some-class',
)
Routing¶
Page class can has url path for open page.
from seismograph import selenium
class MyPage(selenium.Page):
__url_path__ = '/path/to/page'
Url path can has params for format string
from seismograph import selenium
class MyPage(selenium.Page):
__url_path__ = '/path/to/page/{id}'
page = MyPage(browser)
page.open(id=1)
Page class can to be related to URL ule. URL rule is regexp pattern.
selenium.add_url_rule('/hello', SomePageClass)
page = browser.router.get('/hello')