Merge lp:~elopio/u1-test-utils/page-objects into lp:u1-test-utils

Proposed by Leo Arias
Status: Merged
Merged at revision: 20
Proposed branch: lp:~elopio/u1-test-utils/page-objects
Merge into: lp:u1-test-utils
Diff against target: 617 lines (+317/-232)
7 files modified
u1testutils/sst/sso/helpers.py (+38/-35)
u1testutils/sst/sso/pages.py (+279/-0)
u1testutils/sst/sso/pages/create_account.py (+0/-37)
u1testutils/sst/sso/pages/log_in.py (+0/-63)
u1testutils/sst/sso/pages/registration_mail_sent.py (+0/-35)
u1testutils/sst/sso/pages/site_not_recognised.py (+0/-53)
u1testutils/sst/sso/pages/subheader.py (+0/-9)
To merge this branch: bzr merge lp:~elopio/u1-test-utils/page-objects
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Online Services QA Pending
Review via email: mp+144212@code.launchpad.net

Commit message

Refactor pages to use page objects.

Description of the change

We have been playing with the u1servers acceptance test, and experimenting with a pure page object pattern, nicely explained in [1].
This branch is a prototype for SSO helpers, to gather feedback and opinions.

The functions in helpers.py show in a great way the cool ideas of this pattern:
 * The methods are the actions a user can do with each page.
 * The methods return other pages. This shows in a clear way the site workflow and gives immediate access to the methods available in the new page.
 * Actions with different results are modeled in different methods. This helps avoiding conditional logic in the tests and make them more expressive.

[1] http://code.google.com/p/selenium/wiki/PageObjects

To post a comment you must log in.
21. By Leo Arias

Removed the site not recognized default values.

Revision history for this message
Matias Bordese (matiasb) wrote :

Liking the pages approach.

A few questions/comments:

- return_page should be a Page instance? related, a Page class is expected here (l.103)?

- the return_page argument seems to be just for checks? (verifying the user is correctly redirected after an action to that page); at first I thought it was a way to tell the action where to redirect me after it. I would expect getting a page instance as result and maybe the caller check the got object in an instance of the right page?

- shouldn't l.149 and l.332 be comments instead?

22. By Leo Arias

Now we are passing instantiated return pages.

Revision history for this message
Leo Arias (elopio) wrote :

> Liking the pages approach.
>
> A few questions/comments:
>
> - return_page should be a Page instance? related, a Page class is expected
> here (l.103)?

Yes. We are passing instantiated page objects. At first I tried passing just the classes so the verification could be done when we instantiated them, but it seemed harder to understand. l.103 is a typo left from that experiment, I fixed it.

> - the return_page argument seems to be just for checks? (verifying the user is
> correctly redirected after an action to that page); at first I thought it was
> a way to tell the action where to redirect me after it. I would expect getting
> a page instance as result and maybe the caller check the got object in an
> instance of the right page?

It's a way to make sure we are on the right page, and a way to make it clearer for the caller where I will be after the call.
A page instance as a result is what I like too, but I thought the check could be done on the action that leads to that page instead of leaving the job to every caller. I added to the __init__ a call to assert_page_is_open, and I added it too to all methods that don't instantiate the return page, so there's no need for the caller to do an extra check. Maybe I'm not getting right what you are saying, if you can give me a little code snippet it will be easier.

> - shouldn't l.149 and l.332 be comments instead?

I think not. Why? They are docstrings, and according to pep257 they should use triple double quotes. It really doesn't say anything specific to class attributes, but that's what I understood. I might be wrong.

Revision history for this message
Matias Bordese (matiasb) wrote :

> It's a way to make sure we are on the right page, and a way to make it clearer
> for the caller where I will be after the call.

In that case I would make it clearer in the method description that you are not redirected there but that's where you expect to be after the call (instead of 'The page to return on a successful log in.').

> A page instance as a result is what I like too, but I thought the check could
> be done on the action that leads to that page instead of leaving the job to
> every caller.

Well, right now the caller should know where it would be redirected and pass the respective page instance to the action. If that wasn't required it would make more sense to me to the action internally check the page is ok, but it sounds like the caller is the one who knows where it should be redirected.

> I added to the __init__ a call to assert_page_is_open, and I
> added it too to all methods that don't instantiate the return page, so there's
> no need for the caller to do an extra check. Maybe I'm not getting right what
> you are saying, if you can give me a little code snippet it will be easier.

I was thinking on something like (pseudo code):

page = sign_in(user)
self.assert_is_page(page, ExpectedPage) # isinstance?

instead of:

expected_page = ExpectedPage()
page = sign_in(user, return_page=expected_page)

But this is just an opinion, maybe I'm missing something/context.

> I think not. Why? They are docstrings, and according to pep257 they should use
> triple double quotes. It really doesn't say anything specific to class
> attributes, but that's what I understood. I might be wrong.

They look as comments about the attributes and not a class docstring, I think.

This for example (l.331-2):
    title = "{0}'s details"
    """The title of the page. The parameter is the user name."""
I think should be:
    # The title of the page. The parameter is the user name.
    title = "{0}'s details"

Revision history for this message
Leo Arias (elopio) wrote :

> > It's a way to make sure we are on the right page, and a way to make it
> clearer
> > for the caller where I will be after the call.
>
> In that case I would make it clearer in the method description that you are
> not redirected there but that's where you expect to be after the call (instead
> of 'The page to return on a successful log in.').

You are right, I'll try to improve that.

> > A page instance as a result is what I like too, but I thought the check
> could
> > be done on the action that leads to that page instead of leaving the job to
> > every caller.
>
> Well, right now the caller should know where it would be redirected and pass
> the respective page instance to the action. If that wasn't required it would
> make more sense to me to the action internally check the page is ok, but it
> sounds like the caller is the one who knows where it should be redirected.
>
> > I added to the __init__ a call to assert_page_is_open, and I
> > added it too to all methods that don't instantiate the return page, so
> there's
> > no need for the caller to do an extra check. Maybe I'm not getting right
> what
> > you are saying, if you can give me a little code snippet it will be easier.
>
> I was thinking on something like (pseudo code):
>
> page = sign_in(user)
> self.assert_is_page(page, ExpectedPage) # isinstance?

The problem here is that sign_in doesn't know what's the expected page. If it's called from sso, it would be the account page. If it's called from pay, it would be the payment history page. And from u1, it would be the dashboard.

But what you say is actually an option. It could be something like:

anonymous_home_page = AnonymousHomePage()
ubuntu_single_sign_on = anonymous_home_page.go_to_sign_in()
ubuntu_single_sign_on.sign_in(user)
# Here is a workflow glitch
user_home_page = UserHomePage()
user_home_page.do_the_test()

I think I would prefer:

anonymous_home_page = AnonymousHomePage()
ubuntu_single_sign_on = anonymous_home_page.go_to_sign_in()
user_home_page = ubuntu_single_sign_on.sign_in(user, UserHomePage())
user_home_page.do_the_test()

But I'm definitely not sure about which is best. And maybe both can be improved.

> They look as comments about the attributes and not a class docstring, I think.
>
> This for example (l.331-2):
> title = "{0}'s details"
> """The title of the page. The parameter is the user name."""
> I think should be:
> # The title of the page. The parameter is the user name.
> title = "{0}'s details"

Yes. It was Vincent who told me that the comment was expected after the variable. Any insights Vincent?

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Regarding the comments for attributes, as you can see in the pep-257 intro:

'A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the __doc__ special attribute of that object.'

So, class or instance variables do not have docstrings, ergo the clarification added in the source (which comes handy to the one inspecting the class) should be a comment, if not relevant to go into the class' docstring. I personally prefer adding those details to the class' docstring, so this particular case:

329 +class YourAccount(Page):
330 +
331 + title = "{0}'s details"
332 + """The title of the page. The parameter is the user name."""

would result in:

329 +class YourAccount(Page):
3xx + """A page showing the details for the currently logged in user.
3xx +
3xx + This class defines a class attribute 'title' that represents the title of
3xx + the page, and is built using the user name.
3xx +
3xx + """
3xx +
332 + title = "{0}'s details"

And since we're talking about pep-257, the docstring for make_all_information_available_to_website (and every other docstring that has the first line longer than a single 80 column line) is not pep-257 compliant.

Any chance you fix that?

Revision history for this message
Leo Arias (elopio) wrote :

> Any chance you fix that?

Of course, sounds good.

I've just read the pep again, and it says: "The docstring for a class should summarize its behavior and list the public methods and instance variables."

23. By Leo Arias

Fixed comments style.

Revision history for this message
Leo Arias (elopio) wrote :

> I think I would prefer:
>
> anonymous_home_page = AnonymousHomePage()
> ubuntu_single_sign_on = anonymous_home_page.go_to_sign_in()
> user_home_page = ubuntu_single_sign_on.sign_in(user, UserHomePage())
> user_home_page.do_the_test()

Actually, there's a problem here because we shouldn't instantiate pages that are not visible. So, instead of this I think I would go back to my first approach:

anonymous_home_page = AnonymousHomePage()
ubuntu_single_sign_on = anonymous_home_page.go_to_sign_in()
# UserHomePage is the name of the class, and it will be instantiated by sign_in just before returning it.
user_home_page = ubuntu_single_sign_on.sign_in(user, UserHomePage)
user_home_page.do_the_test()

Or, the other option that's not sending any return page to SSO, and leave it all to the caller.

24. By Leo Arias

Improved the comment on return_page.

25. By Leo Arias

pages.__init__.py is now not necessary.

26. By Leo Arias

Remove the return pages, and leave them to the caller.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Branch looks good! Approving with some comments:

* I personally would not recommend changing the order of the param to existing API (so I would not swap is_site_recognized with user, I would leave user first). But I also understand this lib is not heavily used, so you can leave as is. What I do think we need to leave in place is a default value for is_site_recognized.

* I advice against having method that return different stuff depending on the branch being used. Any chance that
create_new_account returns something more unified (I'm not sure what type does site_not_recognized.yes_sign_me_in() has)? In any case, if you feel like this is the right approach, feel free to leave as is.

* Same two comments for sign_in.

review: Approve
27. By Leo Arias

Yes sign me in returns no value, and inverted the order of the parameters.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'u1testutils/sst/sso/helpers.py'
--- u1testutils/sst/sso/helpers.py 2013-01-16 02:55:27 +0000
+++ u1testutils/sst/sso/helpers.py 2013-01-29 14:54:22 +0000
@@ -14,17 +14,11 @@
14# You should have received a copy of the GNU General Public License along14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.15# with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17from u1testutils.sst.sso.pages import (17from u1testutils.sst.sso import pages
18 create_account,
19 log_in,
20 registration_mail_sent,
21 site_not_recognised,
22 subheader,
23)
24from u1testutils.sst.sso.utils import mail18from u1testutils.sst.sso.utils import mail
2519
2620
27def create_new_account(user, not_recognized=True):21def create_new_account(user, is_site_recognized=True):
28 """Create a new account on Ubuntu Single Sign On.22 """Create a new account on Ubuntu Single Sign On.
2923
30 The browser must be on the Log in page.24 The browser must be on the Log in page.
@@ -34,22 +28,27 @@
34 Keyword arguments:28 Keyword arguments:
35 user -- The user object with the information for the new account.29 user -- The user object with the information for the new account.
36 It must have the full_name, email and password attributes.30 It must have the full_name, email and password attributes.
37 not_recognized -- If True, the user will be logged in even if the site31 is_site_recognized -- Boolean indicating if the site that requested the
38 is not recognized, and all the user information will be made available32 log in is recognized. If it is not recognized, all the user available
39 to the site. Default is True.33 information will be send to it. Default is True.
4034
41 """35 """
42 log_in.assert_page()36 log_in = pages.LogIn()
43 log_in.click_create_new_account()37 create_account = log_in.go_to_create_new_account()
44 create_account.create_ubuntu_sso_account(user)38 registration_mail_sent = create_account.create_ubuntu_sso_account(user)
45 confirmation_code = mail.get_verification_code_for_address(user.email)39 confirmation_code = mail.get_verification_code_for_address(user.email)
46 registration_mail_sent.confirm_email(confirmation_code)40 if is_site_recognized:
47 if not_recognized and site_not_recognised.is_site_not_recognized():41 registration_mail_sent.confirm_email_to_site_recognized(
48 site_not_recognised.make_all_information_available_to_website()42 confirmation_code)
49 site_not_recognised.yes_sign_me_in()43 else:
5044 site_not_recognized = \
5145 registration_mail_sent.confirm_email_to_site_not_recognized(
52def sign_in(user=None, not_recognized=True):46 confirmation_code)
47 site_not_recognized.make_all_information_available_to_website()
48 site_not_recognized.yes_sign_me_in()
49
50
51def sign_in(user=None, is_site_recognized=True):
53 """Log in with an Ubuntu Single Sign On account.52 """Log in with an Ubuntu Single Sign On account.
5453
55 The browser must be on the Log in page.54 The browser must be on the Log in page.
@@ -62,20 +61,21 @@
62 If its value is None, it means that the user has already started a61 If its value is None, it means that the user has already started a
63 session on Ubuntu Single Sign On and it's not necessary to enter the62 session on Ubuntu Single Sign On and it's not necessary to enter the
64 credentials again. Default is None.63 credentials again. Default is None.
65 not_recognized -- If True, the user will be logged in even if the site64 is_site_recognized -- Boolean indicating if the site that requested the
66 is not recognized, and all the user information will be made available65 log in is recognized. If it is not recognized, all the user available
67 to the site. Default is True.66 information will be send to it. Default is True.
6867
69 """68 """
70 if user is not None:69 log_in = pages.LogIn()
71 log_in.assert_page()70 if is_site_recognized:
72 log_in.log_in(user)71 log_in.log_in_to_site_recognized(user)
73 if not_recognized and site_not_recognised.is_site_not_recognized():72 else:
74 site_not_recognised.make_all_information_available_to_website()73 site_not_recognized = log_in.log_in_to_site_not_recognized(user)
75 site_not_recognised.yes_sign_me_in()74 site_not_recognized.make_all_information_available_to_website()
7675 site_not_recognized.yes_sign_me_in()
7776
78def log_out():77
78def log_out(user_name):
79 """Log out from the Ubuntu Single Sign On site.79 """Log out from the Ubuntu Single Sign On site.
8080
81 The browser must be on the Single Sign On site, and the user must have the81 The browser must be on the Single Sign On site, and the user must have the
@@ -84,6 +84,9 @@
84 If the log out succeeds, the browser will be on the Ubuntu Single Sign On84 If the log out succeeds, the browser will be on the Ubuntu Single Sign On
85 logout page.85 logout page.
8686
87 Keyword arguments:
88 user_name -- The name of the logged in user.
89
87 """90 """
88 assert subheader.is_logged_in()91 your_account = pages.YourAccount(user_name)
89 subheader.log_out()92 return your_account.sub_header.log_out()
9093
=== removed directory 'u1testutils/sst/sso/pages'
=== renamed file 'u1testutils/sst/sso/pages/__init__.py' => 'u1testutils/sst/sso/pages.py'
--- u1testutils/sst/sso/pages/__init__.py 2013-01-16 02:55:27 +0000
+++ u1testutils/sst/sso/pages.py 2013-01-29 14:54:22 +0000
@@ -0,0 +1,279 @@
1# -*- coding: utf-8 -*-
2
3# Copyright 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License version 3, as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import sst.actions
18
19
20class Page(object):
21 """Base class for the page objects used in acceptance testing.
22
23 Instance variables:
24 title -- The title of the page.
25
26 """
27
28 title = None
29
30 def __init__(self):
31 super(Page, self).__init__()
32 self.assert_page_is_open()
33
34 def assert_page_is_open(self):
35 """Assert that the page is open."""
36 sst.actions.assert_title(self.title)
37
38
39class LogIn(Page):
40 """Log in page of the Ubuntu Single Sign On website.
41
42 This is a subclass of the Page object. It extends the assert_page_is_open
43 method with additional verifications and adds methods for the actions
44 available in this page.
45
46 Instance variables:
47 title -- The title of the page.
48
49 """
50
51 title = 'Log in'
52
53 def assert_page_is_open(self):
54 """Assert that the page is open."""
55 super(LogIn, self).assert_page_is_open()
56 sst.actions.assert_element(tag='h1', text='Ubuntu Single Sign On')
57 sst.actions.assert_element(tag='h2', text='Are you new?')
58
59 def log_in_to_site_recognized(self, user=None):
60 """Fill the log in form and continue to the site that requested it.
61
62 Keyword arguments:
63 user -- The user credentials. It must have the attributes email and
64 password. If None is passed as the user, it means that the user
65 has already started session on the identity provider and it's not
66 necessary to enter the credentials again.
67
68 """
69 self._log_in(user)
70
71 def log_in_to_site_not_recognized(self, user=None):
72 """Fill the log in form and continue to the next step.
73
74 As the site is not recognized, the next step is the page where the
75 user can select the information that will be send to the site.
76
77 Keyword arguments:
78 user -- The user credentials. It must have the attributes email and
79 password. If None is passed as the user, it means that the user
80 has already started session on the identity provider and it's not
81 necessary to enter the credentials again.
82
83 """
84 self._log_in(user)
85 return SiteNotRecognized()
86
87 def _log_in(self, user=None):
88 if user is not None:
89 sst.actions.wait_for(sst.actions.assert_title, 'Log in')
90 self._fill_log_in_form(user.email, user.password)
91 self._click_continue_button()
92 else:
93 # If None is passed as the user, it means that the user has
94 # already started session on the identity provider and it's not
95 # necessary to enter the credentials again.
96 pass
97
98 def _fill_log_in_form(self, email, password):
99 sst.actions.write_textfield('id_email', email)
100 sst.actions.write_textfield('id_password', password)
101
102 def _click_continue_button(self):
103 continue_button = sst.actions.get_element(
104 css_class='btn', name='continue')
105 sst.actions.click_button(continue_button)
106
107 def go_to_create_new_account(self):
108 """Go to the Create new account page."""
109 new_account_link = sst.actions.get_element(id='new-account-link')
110 sst.actions.click_link(new_account_link)
111 return CreateAccount()
112
113
114class CreateAccount(Page):
115 """Create account page of the Ubuntu Single Sign On website.
116
117 This is a subclass of the Page object. It adds methods for the actions
118 available in this page.
119
120 Instance variables:
121 title -- The title of the page.
122
123 """
124
125 title = 'Create account'
126
127 def create_ubuntu_sso_account(self, user):
128 """Fill the new account form and continue to the next step.
129
130 Keyword arguments:
131 user -- The user credentials. It must have the attributes email and
132 password.
133
134 """
135 self._fill_new_account_form(user)
136 self._click_continue()
137 return RegistrationMailSent()
138
139 def _fill_new_account_form(self, user):
140 sst.actions.write_textfield('id_displayname', user.full_name)
141 sst.actions.write_textfield('id_email', user.email)
142 sst.actions.write_textfield('id_password', user.password)
143 sst.actions.write_textfield('id_passwordconfirm', user.password)
144
145 def _click_continue(self):
146 continue_button = sst.actions.get_element(name='continue')
147 sst.actions.click_button(continue_button)
148
149
150class RegistrationMailSent(Page):
151 """Registration mail sent page of the Ubuntu Single Sign On website.
152
153 This is a subclass of the Page object. It extends the assert_page_is_open
154 method with additional verifications and adds methods for the actions
155 available in this page.
156
157 Instance variables:
158 title -- The title of the page.
159
160 """
161
162 title = 'Registration mail sent'
163
164 def confirm_email_to_site_recognized(self, confirmation_code):
165 """Confirm email and continue to the site that requested the log in.
166
167 Keyword arguments:
168 confirmation_code -- The confirmation code sent to the user email
169 address.
170
171 """
172 self._confirm_email(confirmation_code)
173
174 def confirm_email_to_site_not_recognized(self, confirmation_code):
175 """Enter the confirmation code and continue to the next step.
176
177 As the site is not recognized, the next step is the page where the
178 user can select the information that will be send to the site.
179
180 Keyword arguments:
181 confirmation_code -- The confirmation code sent to the user email
182 address.
183
184 """
185 self._confirm_email(confirmation_code)
186 return SiteNotRecognized()
187
188 def _confirm_email(self, confirmation_code):
189 self._enter_confirmaiton_code(confirmation_code)
190 self._click_continue_button()
191
192 def _enter_confirmation_code(self, confirmation_code):
193 confirmation_code_text_field = sst.actions.get_element(
194 name='confirmation_code')
195 sst.actions.write_textfield(confirmation_code_text_field,
196 confirmation_code)
197
198 def _click_continue_button(self):
199 continue_button = sst.actions.get_element(css_class='btn',
200 text='Continue')
201 sst.actions.click_button(continue_button)
202
203
204class SiteNotRecognized(Page):
205 """Site not Recognized page of the Ubuntu Single Sign On website.
206
207 This is a subclass of the Page object. It adds methods for the actions
208 available in this page.
209
210 Instance variables:
211 title -- The title of the page.
212
213 """
214 def make_all_information_available_to_website(self):
215 """Select all the user available information.
216
217 This information will be send to the site that requested the log in.
218
219 """
220 information_checkboxes = self._get_information_checkboxes()
221 for checkbox in information_checkboxes:
222 sst.actions.set_checkbox_value(checkbox, True)
223 return self
224
225 def _get_information_checkboxes(self):
226 return sst.actions.get_elements_by_css(
227 'form[name="decideform"] > .info-items > .list > li > '
228 'input[type="checkbox"]')
229
230 def yes_sign_me_in(self):
231 """Accept to sign in to the site not recognized and go back to it."""
232 sign_me_in_button = sst.actions.get_element(css_class='btn',
233 name='yes')
234 sst.actions.click_button(sign_me_in_button)
235
236
237class YourAccount(Page):
238 """Your account page of the Ubuntu Single Sign On website.
239
240 This is a subclass of the Page object. It extends the constructor to
241 to receive the user name, and adds methods for the actions available in
242 this page.
243
244 Instance variables:
245 title -- The title of the page. It's build when the page is instantiated
246 using the user name.
247 sub_header -- The sub header menu displayed on the pages shown to logged
248 in users.
249
250 """
251
252 title = "{0}'s details"
253
254 def __init__(self, user_name):
255 super(YourAccount, self).__init__()
256 self.title = self.title.format(user_name)
257 self.sub_header = _UserSubHeader()
258
259
260class _UserSubHeader(object):
261
262 def log_out(self):
263 """Log out from the web site."""
264 sst.actions.click_link('logout-link')
265 return YouHaveBeenLoggedOut()
266
267
268class YouHaveBeenLoggedOut(Page):
269 """Your account page of the Ubuntu Single Sign On website.
270
271 This is a subclass of the Page object.
272
273 Instance variables:
274 title -- The title of the page. It's build when the page is instantiated
275 using the user name.
276
277 """
278
279 title = 'You have been logged out'
0280
=== removed file 'u1testutils/sst/sso/pages/create_account.py'
--- u1testutils/sst/sso/pages/create_account.py 2013-01-16 15:16:50 +0000
+++ u1testutils/sst/sso/pages/create_account.py 1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
1# -*- coding: utf-8 -*-
2
3# Copyright 2012, 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License version 3, as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import sst.actions
18
19
20def create_ubuntu_sso_account(user):
21 _fill_new_account_form(user)
22 _click_continue()
23
24
25def _fill_new_account_form(user):
26 sst.actions.write_textfield('id_displayname', user.full_name)
27 sst.actions.write_textfield('id_email', user.email)
28 sst.actions.write_textfield('id_password', user.password)
29 sst.actions.write_textfield('id_passwordconfirm', user.password)
30
31
32def _click_continue():
33 sst.actions.click_button(_get_continue_button())
34
35
36def _get_continue_button():
37 return sst.actions.get_element(name='continue')
380
=== removed file 'u1testutils/sst/sso/pages/log_in.py'
--- u1testutils/sst/sso/pages/log_in.py 2013-01-16 15:16:50 +0000
+++ u1testutils/sst/sso/pages/log_in.py 1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
1# -*- coding: utf-8 -*-
2
3# Copyright 2012, 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License version 3, as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import sst.actions
18
19
20def assert_page():
21 _assert_page_heading1()
22 _assert_page_heading2()
23
24
25def _assert_page_heading1():
26 sst.actions.assert_element(tag='h1', text='Ubuntu Single Sign On')
27
28
29def _assert_page_heading2():
30 sst.actions.assert_element(tag='h2', text='Are you new?')
31
32
33def log_in(user=None):
34 if user is not None:
35 sst.actions.wait_for(sst.actions.assert_title, 'Log in')
36 _fill_log_in_form(user.email, user.password)
37 _click_continue_button()
38 else:
39 # If no user is passed as parameter, the user has already started
40 # session on the identity provider and it's not necessary to enter
41 # the credentials again.
42 pass
43
44
45def _fill_log_in_form(email, password):
46 sst.actions.write_textfield('id_email', email)
47 sst.actions.write_textfield('id_password', password)
48
49
50def _click_continue_button():
51 sst.actions.click_button(_get_continue_button())
52
53
54def _get_continue_button():
55 return sst.actions.get_element(css_class='btn', name='continue')
56
57
58def click_create_new_account():
59 sst.actions.click_link(_get_new_account_link())
60
61
62def _get_new_account_link():
63 return sst.actions.get_element(id='new-account-link')
640
=== removed file 'u1testutils/sst/sso/pages/registration_mail_sent.py'
--- u1testutils/sst/sso/pages/registration_mail_sent.py 2013-01-16 15:16:50 +0000
+++ u1testutils/sst/sso/pages/registration_mail_sent.py 1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
1# -*- coding: utf-8 -*-
2
3# Copyright 2012, 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License version 3, as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import sst.actions
18
19
20def confirm_email(confirmation_code):
21 sst.actions.write_textfield(
22 _get_confirmation_code_text_field(), confirmation_code)
23 _click_continue_button()
24
25
26def _get_confirmation_code_text_field():
27 return sst.actions.get_element(name='confirmation_code')
28
29
30def _click_continue_button():
31 sst.actions.click_button(_get_continue_button())
32
33
34def _get_continue_button():
35 return sst.actions.get_element(css_class='btn', text='Continue')
360
=== removed file 'u1testutils/sst/sso/pages/site_not_recognised.py'
--- u1testutils/sst/sso/pages/site_not_recognised.py 2013-01-16 15:16:50 +0000
+++ u1testutils/sst/sso/pages/site_not_recognised.py 1970-01-01 00:00:00 +0000
@@ -1,53 +0,0 @@
1# -*- coding: utf-8 -*-
2
3# Copyright 2012, 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License version 3, as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import sst.actions
18
19
20def is_site_not_recognized():
21 return _is_decide_form_present()
22
23
24def _is_decide_form_present():
25 return sst.actions.exists_element(name='decideform')
26
27
28def make_all_information_available_to_website():
29 information_checkboxes = _get_information_checkboxes()
30 for checkbox in information_checkboxes:
31 sst.actions.set_checkbox_value(checkbox, True)
32
33
34def _get_information_checkboxes():
35 return sst.actions.get_elements_by_css(
36 'form[name="decideform"] > .info-items > .list > li > '
37 'input[type="checkbox"]')
38
39
40def yes_sign_me_in():
41 sst.actions.click_button(_get_sign_me_in_button())
42
43
44def _get_sign_me_in_button():
45 return sst.actions.get_element(css_class='btn', name='yes')
46
47
48def cancel():
49 sst.actions.click_link(_get_cancel_link())
50
51
52def _get_cancel_link():
53 return sst.actions.get_element(tag='a', text='cancel')
540
=== removed file 'u1testutils/sst/sso/pages/subheader.py'
--- u1testutils/sst/sso/pages/subheader.py 2013-01-16 02:55:27 +0000
+++ u1testutils/sst/sso/pages/subheader.py 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
1import sst.actions
2
3
4def is_logged_in():
5 return sst.actions.exists_element(id='logout-link')
6
7
8def log_out():
9 sst.actions.click_link('logout-link')

Subscribers

People subscribed via source and target branches

to all changes: