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
1=== modified file 'u1testutils/sst/sso/helpers.py'
2--- u1testutils/sst/sso/helpers.py 2013-01-16 02:55:27 +0000
3+++ u1testutils/sst/sso/helpers.py 2013-01-29 14:54:22 +0000
4@@ -14,17 +14,11 @@
5 # You should have received a copy of the GNU General Public License along
6 # with this program. If not, see <http://www.gnu.org/licenses/>.
7
8-from u1testutils.sst.sso.pages import (
9- create_account,
10- log_in,
11- registration_mail_sent,
12- site_not_recognised,
13- subheader,
14-)
15+from u1testutils.sst.sso import pages
16 from u1testutils.sst.sso.utils import mail
17
18
19-def create_new_account(user, not_recognized=True):
20+def create_new_account(user, is_site_recognized=True):
21 """Create a new account on Ubuntu Single Sign On.
22
23 The browser must be on the Log in page.
24@@ -34,22 +28,27 @@
25 Keyword arguments:
26 user -- The user object with the information for the new account.
27 It must have the full_name, email and password attributes.
28- not_recognized -- If True, the user will be logged in even if the site
29- is not recognized, and all the user information will be made available
30- to the site. Default is True.
31+ is_site_recognized -- Boolean indicating if the site that requested the
32+ log in is recognized. If it is not recognized, all the user available
33+ information will be send to it. Default is True.
34
35 """
36- log_in.assert_page()
37- log_in.click_create_new_account()
38- create_account.create_ubuntu_sso_account(user)
39+ log_in = pages.LogIn()
40+ create_account = log_in.go_to_create_new_account()
41+ registration_mail_sent = create_account.create_ubuntu_sso_account(user)
42 confirmation_code = mail.get_verification_code_for_address(user.email)
43- registration_mail_sent.confirm_email(confirmation_code)
44- if not_recognized and site_not_recognised.is_site_not_recognized():
45- site_not_recognised.make_all_information_available_to_website()
46- site_not_recognised.yes_sign_me_in()
47-
48-
49-def sign_in(user=None, not_recognized=True):
50+ if is_site_recognized:
51+ registration_mail_sent.confirm_email_to_site_recognized(
52+ confirmation_code)
53+ else:
54+ site_not_recognized = \
55+ registration_mail_sent.confirm_email_to_site_not_recognized(
56+ confirmation_code)
57+ site_not_recognized.make_all_information_available_to_website()
58+ site_not_recognized.yes_sign_me_in()
59+
60+
61+def sign_in(user=None, is_site_recognized=True):
62 """Log in with an Ubuntu Single Sign On account.
63
64 The browser must be on the Log in page.
65@@ -62,20 +61,21 @@
66 If its value is None, it means that the user has already started a
67 session on Ubuntu Single Sign On and it's not necessary to enter the
68 credentials again. Default is None.
69- not_recognized -- If True, the user will be logged in even if the site
70- is not recognized, and all the user information will be made available
71- to the site. Default is True.
72+ is_site_recognized -- Boolean indicating if the site that requested the
73+ log in is recognized. If it is not recognized, all the user available
74+ information will be send to it. Default is True.
75
76 """
77- if user is not None:
78- log_in.assert_page()
79- log_in.log_in(user)
80- if not_recognized and site_not_recognised.is_site_not_recognized():
81- site_not_recognised.make_all_information_available_to_website()
82- site_not_recognised.yes_sign_me_in()
83-
84-
85-def log_out():
86+ log_in = pages.LogIn()
87+ if is_site_recognized:
88+ log_in.log_in_to_site_recognized(user)
89+ else:
90+ site_not_recognized = log_in.log_in_to_site_not_recognized(user)
91+ site_not_recognized.make_all_information_available_to_website()
92+ site_not_recognized.yes_sign_me_in()
93+
94+
95+def log_out(user_name):
96 """Log out from the Ubuntu Single Sign On site.
97
98 The browser must be on the Single Sign On site, and the user must have the
99@@ -84,6 +84,9 @@
100 If the log out succeeds, the browser will be on the Ubuntu Single Sign On
101 logout page.
102
103+ Keyword arguments:
104+ user_name -- The name of the logged in user.
105+
106 """
107- assert subheader.is_logged_in()
108- subheader.log_out()
109+ your_account = pages.YourAccount(user_name)
110+ return your_account.sub_header.log_out()
111
112=== removed directory 'u1testutils/sst/sso/pages'
113=== renamed file 'u1testutils/sst/sso/pages/__init__.py' => 'u1testutils/sst/sso/pages.py'
114--- u1testutils/sst/sso/pages/__init__.py 2013-01-16 02:55:27 +0000
115+++ u1testutils/sst/sso/pages.py 2013-01-29 14:54:22 +0000
116@@ -0,0 +1,279 @@
117+# -*- coding: utf-8 -*-
118+
119+# Copyright 2013 Canonical Ltd.
120+#
121+# This program is free software: you can redistribute it and/or modify it
122+# under the terms of the GNU Lesser General Public License version 3, as
123+# published by the Free Software Foundation.
124+#
125+# This program is distributed in the hope that it will be useful, but
126+# WITHOUT ANY WARRANTY; without even the implied warranties of
127+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
128+# PURPOSE. See the GNU Lesser General Public License for more details.
129+#
130+# You should have received a copy of the GNU General Public License along
131+# with this program. If not, see <http://www.gnu.org/licenses/>.
132+
133+import sst.actions
134+
135+
136+class Page(object):
137+ """Base class for the page objects used in acceptance testing.
138+
139+ Instance variables:
140+ title -- The title of the page.
141+
142+ """
143+
144+ title = None
145+
146+ def __init__(self):
147+ super(Page, self).__init__()
148+ self.assert_page_is_open()
149+
150+ def assert_page_is_open(self):
151+ """Assert that the page is open."""
152+ sst.actions.assert_title(self.title)
153+
154+
155+class LogIn(Page):
156+ """Log in page of the Ubuntu Single Sign On website.
157+
158+ This is a subclass of the Page object. It extends the assert_page_is_open
159+ method with additional verifications and adds methods for the actions
160+ available in this page.
161+
162+ Instance variables:
163+ title -- The title of the page.
164+
165+ """
166+
167+ title = 'Log in'
168+
169+ def assert_page_is_open(self):
170+ """Assert that the page is open."""
171+ super(LogIn, self).assert_page_is_open()
172+ sst.actions.assert_element(tag='h1', text='Ubuntu Single Sign On')
173+ sst.actions.assert_element(tag='h2', text='Are you new?')
174+
175+ def log_in_to_site_recognized(self, user=None):
176+ """Fill the log in form and continue to the site that requested it.
177+
178+ Keyword arguments:
179+ user -- The user credentials. It must have the attributes email and
180+ password. If None is passed as the user, it means that the user
181+ has already started session on the identity provider and it's not
182+ necessary to enter the credentials again.
183+
184+ """
185+ self._log_in(user)
186+
187+ def log_in_to_site_not_recognized(self, user=None):
188+ """Fill the log in form and continue to the next step.
189+
190+ As the site is not recognized, the next step is the page where the
191+ user can select the information that will be send to the site.
192+
193+ Keyword arguments:
194+ user -- The user credentials. It must have the attributes email and
195+ password. If None is passed as the user, it means that the user
196+ has already started session on the identity provider and it's not
197+ necessary to enter the credentials again.
198+
199+ """
200+ self._log_in(user)
201+ return SiteNotRecognized()
202+
203+ def _log_in(self, user=None):
204+ if user is not None:
205+ sst.actions.wait_for(sst.actions.assert_title, 'Log in')
206+ self._fill_log_in_form(user.email, user.password)
207+ self._click_continue_button()
208+ else:
209+ # If None is passed as the user, it means that the user has
210+ # already started session on the identity provider and it's not
211+ # necessary to enter the credentials again.
212+ pass
213+
214+ def _fill_log_in_form(self, email, password):
215+ sst.actions.write_textfield('id_email', email)
216+ sst.actions.write_textfield('id_password', password)
217+
218+ def _click_continue_button(self):
219+ continue_button = sst.actions.get_element(
220+ css_class='btn', name='continue')
221+ sst.actions.click_button(continue_button)
222+
223+ def go_to_create_new_account(self):
224+ """Go to the Create new account page."""
225+ new_account_link = sst.actions.get_element(id='new-account-link')
226+ sst.actions.click_link(new_account_link)
227+ return CreateAccount()
228+
229+
230+class CreateAccount(Page):
231+ """Create account page of the Ubuntu Single Sign On website.
232+
233+ This is a subclass of the Page object. It adds methods for the actions
234+ available in this page.
235+
236+ Instance variables:
237+ title -- The title of the page.
238+
239+ """
240+
241+ title = 'Create account'
242+
243+ def create_ubuntu_sso_account(self, user):
244+ """Fill the new account form and continue to the next step.
245+
246+ Keyword arguments:
247+ user -- The user credentials. It must have the attributes email and
248+ password.
249+
250+ """
251+ self._fill_new_account_form(user)
252+ self._click_continue()
253+ return RegistrationMailSent()
254+
255+ def _fill_new_account_form(self, user):
256+ sst.actions.write_textfield('id_displayname', user.full_name)
257+ sst.actions.write_textfield('id_email', user.email)
258+ sst.actions.write_textfield('id_password', user.password)
259+ sst.actions.write_textfield('id_passwordconfirm', user.password)
260+
261+ def _click_continue(self):
262+ continue_button = sst.actions.get_element(name='continue')
263+ sst.actions.click_button(continue_button)
264+
265+
266+class RegistrationMailSent(Page):
267+ """Registration mail sent page of the Ubuntu Single Sign On website.
268+
269+ This is a subclass of the Page object. It extends the assert_page_is_open
270+ method with additional verifications and adds methods for the actions
271+ available in this page.
272+
273+ Instance variables:
274+ title -- The title of the page.
275+
276+ """
277+
278+ title = 'Registration mail sent'
279+
280+ def confirm_email_to_site_recognized(self, confirmation_code):
281+ """Confirm email and continue to the site that requested the log in.
282+
283+ Keyword arguments:
284+ confirmation_code -- The confirmation code sent to the user email
285+ address.
286+
287+ """
288+ self._confirm_email(confirmation_code)
289+
290+ def confirm_email_to_site_not_recognized(self, confirmation_code):
291+ """Enter the confirmation code and continue to the next step.
292+
293+ As the site is not recognized, the next step is the page where the
294+ user can select the information that will be send to the site.
295+
296+ Keyword arguments:
297+ confirmation_code -- The confirmation code sent to the user email
298+ address.
299+
300+ """
301+ self._confirm_email(confirmation_code)
302+ return SiteNotRecognized()
303+
304+ def _confirm_email(self, confirmation_code):
305+ self._enter_confirmaiton_code(confirmation_code)
306+ self._click_continue_button()
307+
308+ def _enter_confirmation_code(self, confirmation_code):
309+ confirmation_code_text_field = sst.actions.get_element(
310+ name='confirmation_code')
311+ sst.actions.write_textfield(confirmation_code_text_field,
312+ confirmation_code)
313+
314+ def _click_continue_button(self):
315+ continue_button = sst.actions.get_element(css_class='btn',
316+ text='Continue')
317+ sst.actions.click_button(continue_button)
318+
319+
320+class SiteNotRecognized(Page):
321+ """Site not Recognized page of the Ubuntu Single Sign On website.
322+
323+ This is a subclass of the Page object. It adds methods for the actions
324+ available in this page.
325+
326+ Instance variables:
327+ title -- The title of the page.
328+
329+ """
330+ def make_all_information_available_to_website(self):
331+ """Select all the user available information.
332+
333+ This information will be send to the site that requested the log in.
334+
335+ """
336+ information_checkboxes = self._get_information_checkboxes()
337+ for checkbox in information_checkboxes:
338+ sst.actions.set_checkbox_value(checkbox, True)
339+ return self
340+
341+ def _get_information_checkboxes(self):
342+ return sst.actions.get_elements_by_css(
343+ 'form[name="decideform"] > .info-items > .list > li > '
344+ 'input[type="checkbox"]')
345+
346+ def yes_sign_me_in(self):
347+ """Accept to sign in to the site not recognized and go back to it."""
348+ sign_me_in_button = sst.actions.get_element(css_class='btn',
349+ name='yes')
350+ sst.actions.click_button(sign_me_in_button)
351+
352+
353+class YourAccount(Page):
354+ """Your account page of the Ubuntu Single Sign On website.
355+
356+ This is a subclass of the Page object. It extends the constructor to
357+ to receive the user name, and adds methods for the actions available in
358+ this page.
359+
360+ Instance variables:
361+ title -- The title of the page. It's build when the page is instantiated
362+ using the user name.
363+ sub_header -- The sub header menu displayed on the pages shown to logged
364+ in users.
365+
366+ """
367+
368+ title = "{0}'s details"
369+
370+ def __init__(self, user_name):
371+ super(YourAccount, self).__init__()
372+ self.title = self.title.format(user_name)
373+ self.sub_header = _UserSubHeader()
374+
375+
376+class _UserSubHeader(object):
377+
378+ def log_out(self):
379+ """Log out from the web site."""
380+ sst.actions.click_link('logout-link')
381+ return YouHaveBeenLoggedOut()
382+
383+
384+class YouHaveBeenLoggedOut(Page):
385+ """Your account page of the Ubuntu Single Sign On website.
386+
387+ This is a subclass of the Page object.
388+
389+ Instance variables:
390+ title -- The title of the page. It's build when the page is instantiated
391+ using the user name.
392+
393+ """
394+
395+ title = 'You have been logged out'
396
397=== removed file 'u1testutils/sst/sso/pages/create_account.py'
398--- u1testutils/sst/sso/pages/create_account.py 2013-01-16 15:16:50 +0000
399+++ u1testutils/sst/sso/pages/create_account.py 1970-01-01 00:00:00 +0000
400@@ -1,37 +0,0 @@
401-# -*- coding: utf-8 -*-
402-
403-# Copyright 2012, 2013 Canonical Ltd.
404-#
405-# This program is free software: you can redistribute it and/or modify it
406-# under the terms of the GNU Lesser General Public License version 3, as
407-# published by the Free Software Foundation.
408-#
409-# This program is distributed in the hope that it will be useful, but
410-# WITHOUT ANY WARRANTY; without even the implied warranties of
411-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
412-# PURPOSE. See the GNU Lesser General Public License for more details.
413-#
414-# You should have received a copy of the GNU General Public License along
415-# with this program. If not, see <http://www.gnu.org/licenses/>.
416-
417-import sst.actions
418-
419-
420-def create_ubuntu_sso_account(user):
421- _fill_new_account_form(user)
422- _click_continue()
423-
424-
425-def _fill_new_account_form(user):
426- sst.actions.write_textfield('id_displayname', user.full_name)
427- sst.actions.write_textfield('id_email', user.email)
428- sst.actions.write_textfield('id_password', user.password)
429- sst.actions.write_textfield('id_passwordconfirm', user.password)
430-
431-
432-def _click_continue():
433- sst.actions.click_button(_get_continue_button())
434-
435-
436-def _get_continue_button():
437- return sst.actions.get_element(name='continue')
438
439=== removed file 'u1testutils/sst/sso/pages/log_in.py'
440--- u1testutils/sst/sso/pages/log_in.py 2013-01-16 15:16:50 +0000
441+++ u1testutils/sst/sso/pages/log_in.py 1970-01-01 00:00:00 +0000
442@@ -1,63 +0,0 @@
443-# -*- coding: utf-8 -*-
444-
445-# Copyright 2012, 2013 Canonical Ltd.
446-#
447-# This program is free software: you can redistribute it and/or modify it
448-# under the terms of the GNU Lesser General Public License version 3, as
449-# published by the Free Software Foundation.
450-#
451-# This program is distributed in the hope that it will be useful, but
452-# WITHOUT ANY WARRANTY; without even the implied warranties of
453-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
454-# PURPOSE. See the GNU Lesser General Public License for more details.
455-#
456-# You should have received a copy of the GNU General Public License along
457-# with this program. If not, see <http://www.gnu.org/licenses/>.
458-
459-import sst.actions
460-
461-
462-def assert_page():
463- _assert_page_heading1()
464- _assert_page_heading2()
465-
466-
467-def _assert_page_heading1():
468- sst.actions.assert_element(tag='h1', text='Ubuntu Single Sign On')
469-
470-
471-def _assert_page_heading2():
472- sst.actions.assert_element(tag='h2', text='Are you new?')
473-
474-
475-def log_in(user=None):
476- if user is not None:
477- sst.actions.wait_for(sst.actions.assert_title, 'Log in')
478- _fill_log_in_form(user.email, user.password)
479- _click_continue_button()
480- else:
481- # If no user is passed as parameter, the user has already started
482- # session on the identity provider and it's not necessary to enter
483- # the credentials again.
484- pass
485-
486-
487-def _fill_log_in_form(email, password):
488- sst.actions.write_textfield('id_email', email)
489- sst.actions.write_textfield('id_password', password)
490-
491-
492-def _click_continue_button():
493- sst.actions.click_button(_get_continue_button())
494-
495-
496-def _get_continue_button():
497- return sst.actions.get_element(css_class='btn', name='continue')
498-
499-
500-def click_create_new_account():
501- sst.actions.click_link(_get_new_account_link())
502-
503-
504-def _get_new_account_link():
505- return sst.actions.get_element(id='new-account-link')
506
507=== removed file 'u1testutils/sst/sso/pages/registration_mail_sent.py'
508--- u1testutils/sst/sso/pages/registration_mail_sent.py 2013-01-16 15:16:50 +0000
509+++ u1testutils/sst/sso/pages/registration_mail_sent.py 1970-01-01 00:00:00 +0000
510@@ -1,35 +0,0 @@
511-# -*- coding: utf-8 -*-
512-
513-# Copyright 2012, 2013 Canonical Ltd.
514-#
515-# This program is free software: you can redistribute it and/or modify it
516-# under the terms of the GNU Lesser General Public License version 3, as
517-# published by the Free Software Foundation.
518-#
519-# This program is distributed in the hope that it will be useful, but
520-# WITHOUT ANY WARRANTY; without even the implied warranties of
521-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
522-# PURPOSE. See the GNU Lesser General Public License for more details.
523-#
524-# You should have received a copy of the GNU General Public License along
525-# with this program. If not, see <http://www.gnu.org/licenses/>.
526-
527-import sst.actions
528-
529-
530-def confirm_email(confirmation_code):
531- sst.actions.write_textfield(
532- _get_confirmation_code_text_field(), confirmation_code)
533- _click_continue_button()
534-
535-
536-def _get_confirmation_code_text_field():
537- return sst.actions.get_element(name='confirmation_code')
538-
539-
540-def _click_continue_button():
541- sst.actions.click_button(_get_continue_button())
542-
543-
544-def _get_continue_button():
545- return sst.actions.get_element(css_class='btn', text='Continue')
546
547=== removed file 'u1testutils/sst/sso/pages/site_not_recognised.py'
548--- u1testutils/sst/sso/pages/site_not_recognised.py 2013-01-16 15:16:50 +0000
549+++ u1testutils/sst/sso/pages/site_not_recognised.py 1970-01-01 00:00:00 +0000
550@@ -1,53 +0,0 @@
551-# -*- coding: utf-8 -*-
552-
553-# Copyright 2012, 2013 Canonical Ltd.
554-#
555-# This program is free software: you can redistribute it and/or modify it
556-# under the terms of the GNU Lesser General Public License version 3, as
557-# published by the Free Software Foundation.
558-#
559-# This program is distributed in the hope that it will be useful, but
560-# WITHOUT ANY WARRANTY; without even the implied warranties of
561-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
562-# PURPOSE. See the GNU Lesser General Public License for more details.
563-#
564-# You should have received a copy of the GNU General Public License along
565-# with this program. If not, see <http://www.gnu.org/licenses/>.
566-
567-import sst.actions
568-
569-
570-def is_site_not_recognized():
571- return _is_decide_form_present()
572-
573-
574-def _is_decide_form_present():
575- return sst.actions.exists_element(name='decideform')
576-
577-
578-def make_all_information_available_to_website():
579- information_checkboxes = _get_information_checkboxes()
580- for checkbox in information_checkboxes:
581- sst.actions.set_checkbox_value(checkbox, True)
582-
583-
584-def _get_information_checkboxes():
585- return sst.actions.get_elements_by_css(
586- 'form[name="decideform"] > .info-items > .list > li > '
587- 'input[type="checkbox"]')
588-
589-
590-def yes_sign_me_in():
591- sst.actions.click_button(_get_sign_me_in_button())
592-
593-
594-def _get_sign_me_in_button():
595- return sst.actions.get_element(css_class='btn', name='yes')
596-
597-
598-def cancel():
599- sst.actions.click_link(_get_cancel_link())
600-
601-
602-def _get_cancel_link():
603- return sst.actions.get_element(tag='a', text='cancel')
604
605=== removed file 'u1testutils/sst/sso/pages/subheader.py'
606--- u1testutils/sst/sso/pages/subheader.py 2013-01-16 02:55:27 +0000
607+++ u1testutils/sst/sso/pages/subheader.py 1970-01-01 00:00:00 +0000
608@@ -1,9 +0,0 @@
609-import sst.actions
610-
611-
612-def is_logged_in():
613- return sst.actions.exists_element(id='logout-link')
614-
615-
616-def log_out():
617- sst.actions.click_link('logout-link')

Subscribers

People subscribed via source and target branches

to all changes: