![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0418.png)
# She notices a "Share this list" option
self
.
wait_for
(
lambda
:
self
.
assertEqual
(
self
.
browser
.
find_element_by_css_selector
(
'input[name=email]'
)
.
get_attribute
(
'placeholder'
),
'your-friend@example.com')
)
The Page Pattern
But do you know what would be even better? This is an occasion for a “three strikes and
refactor”. This test, and many others, all begin off with the user starting a new list. What
if we had a helper function called “start new list” that would do the
wait_for
as well as
the list item input?
We’ve already seen how to use helper methods on the base
FunctionalTest
class, but
if we continue using too many of them, it’s going to get very crowded. I’ve worked on a
base FT class that was over 1,500 lines long, and that got pretty unwieldy.
One accepted pattern for splitting up your FT helper code is called the
Page pattern ,and it involves having objects to represent the different pages on your site, and to be the
single place to store information about how to interact with them.
Let’s see how we would create Page objects for the home and lists pages. Here’s one for
the home page:
functional_tests/home_and_list_pages.py.
class
HomePage
(
object
):
def
__init__
(
self
,
test
):
self
.
test
=
test
#
def
go_to_home_page
(
self
):
#
self
.
test
.
browser
.
get
(
self
.
test
.
server_url
)
self
.
test
.
wait_for
(
self
.
get_item_input
)
return
self
#
def
get_item_input
(
self
):
return
self
.
test
.
browser
.
find_element_by_id
(
'id_text'
)
def
start_new_list
(
self
,
item_text
):
#
self
.
go_to_home_page
()
inputbox
=
self
.
get_item_input
()
inputbox
.
send_keys
(
item_text
+
'
\n
'
)
list_page
=
ListPage
(
self
.
test
)
#
390
|
Chapter 21: The Token Social Bit, the Page Pattern, and an Exercise for the Reader