Merge lp:~elopio/u1-test-utils/sso-helpers-1 into lp:u1-test-utils

Proposed by Leo Arias
Status: Merged
Merged at revision: 49
Proposed branch: lp:~elopio/u1-test-utils/sso-helpers-1
Merge into: lp:u1-test-utils
Diff against target: 388 lines (+133/-86)
4 files modified
u1testutils/sso/sst/__init__.py (+3/-3)
u1testutils/sso/sst/pages.py (+90/-78)
u1testutils/sst/__init__.py (+9/-3)
u1testutils/sst/selftests/unit/test_pages.py (+31/-2)
To merge this branch: bzr merge lp:~elopio/u1-test-utils/sso-helpers-1
Reviewer Review Type Date Requested Status
Canonical ISD hackers Pending
Review via email: mp+158723@code.launchpad.net
To post a comment you must log in.
53. By Leo Arias

Renamed test open page to make it clearer.

54. By Leo Arias

Added a password confirmation that defaults to the user password.

55. By Leo Arias

Added the Anonymous subheader and various page attributes.

56. By Leo Arias

Fixed lint.

57. By Leo Arias

Typo.

58. By Leo Arias

Added the check parameter.

59. By Leo Arias

Added the h1 to the log in page.

60. By Leo Arias

Remove the \ character that escapes the url paths, before opening the page.

61. By Leo Arias

Added a better error message for assert_url_path. Added attributes to SSO pages.

62. By Leo Arias

Raise a NotImplementedError for the pages with parameters in the path.

63. By Leo Arias

Typo, inverted the order.

64. By Leo Arias

Typo. Inverted the order of the special characters.

65. By Leo Arias

Pass the right argument to the parent.

66. By Leo Arias

Updated the id of the account link.

67. By Leo Arias

Do not receive the user name if it will not use it.

68. By Leo Arias

Inherit from UserSubheader.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'u1testutils/sso/sst/__init__.py'
2--- u1testutils/sso/sst/__init__.py 2013-04-09 19:06:01 +0000
3+++ u1testutils/sso/sst/__init__.py 2013-04-14 03:49:22 +0000
4@@ -33,7 +33,7 @@
5
6 """
7 log_in = pages.LogIn()
8- create_account = log_in.go_to_create_new_account()
9+ create_account = log_in.subheader.go_to_create_new_account()
10 create_account.create_ubuntu_sso_account(user)
11
12 if is_site_recognized:
13@@ -61,7 +61,7 @@
14 """
15 vlink = mail.get_verification_link_for_address(user.email)
16 sst.actions.go_to(vlink)
17- validate_email = pages.ValidateEmail(user.full_name)
18+ validate_email = pages.CompleteEmailAddressValidation()
19 validate_email.confirm()
20
21
22@@ -117,4 +117,4 @@
23
24 """
25 your_account = pages.YourAccount(user_name)
26- return your_account.sub_header.log_out()
27+ return your_account.subheader.log_out()
28
29=== modified file 'u1testutils/sso/sst/pages.py'
30--- u1testutils/sso/sst/pages.py 2013-04-12 18:09:38 +0000
31+++ u1testutils/sso/sst/pages.py 2013-04-14 03:49:22 +0000
32@@ -21,27 +21,35 @@
33 from u1testutils.sst import log_action
34
35
36-class LogIn(u1testutils.sst.Page):
37+class PageWithAnonymousSubheader(u1testutils.sst.Page):
38+
39+ def __init__(self, check=True):
40+ super(PageWithAnonymousSubheader, self).__init__(check)
41+ self.subheader = _AnonymousSubheader()
42+
43+
44+class _AnonymousSubheader(object):
45+
46+ @log_action(logging.info)
47+ def go_to_create_new_account(self):
48+ """Go to the Create new account page."""
49+ new_account_link = sst.actions.get_element(id='new-account-link')
50+ sst.actions.click_link(new_account_link)
51+ return CreateAccount()
52+
53+
54+class LogIn(PageWithAnonymousSubheader):
55 """Log in page of the Ubuntu Single Sign On website.
56
57- This is a subclass of the Page object. It extends the assert_page_is_open
58- method with additional verifications and adds methods for the actions
59- available in this page.
60-
61- Instance variables:
62- title -- The title of the page.
63- url_path -- The path of the page.
64+ This is a subclass of the PageWithAnonymousSubheader object to add
65+ methods for the actions available in this page.
66
67 """
68
69 title = 'Log in'
70 url_path = '/'
71-
72- def assert_page_is_open(self):
73- """Assert that the page is open."""
74- super(LogIn, self).assert_page_is_open()
75- sst.actions.assert_element(tag='h1', text='Ubuntu Single Sign On')
76- sst.actions.assert_element(tag='h2', text='Are you new?')
77+ headings1 = ['Ubuntu Single Sign On']
78+ headings2 = ['Log in to Ubuntu Single Sign On', 'Are you new?']
79
80 @log_action(logging.info)
81 def log_in_to_site_recognized(self, user=None):
82@@ -93,28 +101,18 @@
83 css_class='btn', name='continue')
84 sst.actions.click_button(continue_button)
85
86- @log_action(logging.info)
87- def go_to_create_new_account(self):
88- """Go to the Create new account page."""
89- new_account_link = sst.actions.get_element(id='new-account-link')
90- sst.actions.click_link(new_account_link)
91- return CreateAccount()
92-
93-
94-class CreateAccount(u1testutils.sst.Page):
95+
96+class CreateAccount(PageWithAnonymousSubheader):
97 """Create account page of the Ubuntu Single Sign On website.
98
99- This is a subclass of the Page object. It adds methods for the actions
100- available in this page.
101-
102- Instance variables:
103- title -- The title of the page.
104- url_path -- The path of the page.
105+ This is a subclass of the PageWithAnonymousSubheader object to add
106+ methods for the actions available in this page.
107
108 """
109
110 title = 'Create account'
111 url_path = '/\+new_account'
112+ headings1 = ['Ubuntu Single Sign On', 'Create an account']
113
114 @log_action(logging.info)
115 def create_ubuntu_sso_account(self, user):
116@@ -128,32 +126,35 @@
117 self._fill_new_account_form(user)
118 self._click_continue()
119
120- def _fill_new_account_form(self, user):
121+ def _fill_new_account_form(self, user, password_confirmation=None):
122+ if password_confirmation is None:
123+ password_confirmation = user.password
124 sst.actions.write_textfield('id_displayname', user.full_name)
125 sst.actions.write_textfield('id_email', user.email)
126 sst.actions.write_textfield('id_password', user.password)
127- sst.actions.write_textfield('id_passwordconfirm', user.password)
128+ sst.actions.write_textfield(
129+ 'id_passwordconfirm', password_confirmation)
130+ # Even though the recaptcha field is ignored for our tests, we do
131+ # want to verify that it is on the page.
132+ sst.actions.write_textfield('recaptcha_response_field', 'ignored')
133
134 def _click_continue(self):
135 continue_button = sst.actions.get_element(name='continue')
136 sst.actions.click_button(continue_button)
137
138
139-class RegistrationMailSent(u1testutils.sst.Page):
140- """Registration mail sent page of the Ubuntu Single Sign On website.
141-
142- This is a subclass of the Page object. It extends the assert_page_is_open
143- method with additional verifications and adds methods for the actions
144- available in this page.
145-
146- Instance variables:
147- title -- The title of the page.
148- url_path -- The path of the page.
149+class AccountCreationMailSent(PageWithAnonymousSubheader):
150+ """AccountCreation mail sent page of the Ubuntu Single Sign On website.
151+
152+ This is a subclass of the PageWithAnonymousSubheader object to add methods
153+ for the actions available in this page.
154
155 """
156
157- title = 'Registration mail sent'
158+ title = 'Account creation mail sent'
159 url_path = '/\+new_account'
160+ headings1 = ['Account creation mail sent']
161+ headings2 = ["Haven't received it?"]
162
163 @log_action(logging.info)
164 def confirm_email_to_site_recognized(self, confirmation_code):
165@@ -197,8 +198,27 @@
166 sst.actions.click_button(continue_button)
167
168
169-class ValidateEmail(u1testutils.sst.Page):
170- """Validate email address confirmation page.
171+class PageWithUserSubheader(u1testutils.sst.Page):
172+
173+ def __init__(self, check=True):
174+ super(PageWithUserSubheader, self).__init__(check)
175+ self.subheader = _UserSubheader()
176+
177+
178+class _UserSubheader(object):
179+
180+ @log_action(logging.info)
181+ def log_out(self):
182+ """Log out from the web site."""
183+ sst.actions.click_link('logout-link')
184+ return YouHaveBeenLoggedOut()
185+
186+ def get_user_name(self):
187+ return sst.actions.get_element(id='account').text
188+
189+
190+class CompleteEmailValidation(PageWithUserSubheader):
191+ """Complete email address validation page.
192
193 This is a subclass of the Page object. It adds methods for the actions
194 available in this page.
195@@ -210,11 +230,15 @@
196 """
197
198 title = "Complete email address validation"
199- url_path = '/token/.*/\+newemail/*.@*.'
200-
201- def __init__(self, user_name):
202- self.user_name = user_name
203- super(ValidateEmail, self).__init__()
204+ url_path = '/token/.*/\+newemail/.*@.*'
205+
206+ def __init__(self, check=True):
207+ super(CompleteEmailValidation, self).__init__(check)
208+
209+ def open_page(self, check=True):
210+ # TODO we can receive the token and email as parameters.
211+ # Currently not needed.
212+ raise NotImplementedError('Not yet implemented.')
213
214 def _click_continue_button(self):
215 continue_button = sst.actions.get_element(css_class='btn',
216@@ -228,11 +252,13 @@
217 @log_action(logging.info)
218 def confirm(self):
219 self._click_continue_button()
220- return YourAccount(self.user_name)
221+ user_name = self.subheader.get_user_name()
222+ return YourAccount(user_name)
223
224 @log_action(logging.info)
225 def cancel(self):
226- return YourAccount(self.user_name)
227+ user_name = self.subheader.get_user_name()
228+ return YourAccount(user_name)
229
230
231 class SiteNotRecognized(u1testutils.sst.Page):
232@@ -248,9 +274,13 @@
233
234 """
235
236- title = 'Authenticate to .+'
237+ title = '^Authenticate to .+'
238 url_path = '/.*/\+decide'
239
240+ def open_page(self, check=True):
241+ # TODO we can receive the token as parameter. Currently not needed.
242+ raise NotImplementedError('Not yet implemented.')
243+
244 def assert_page_is_open(self):
245 """Assert that the page is open.
246
247@@ -286,7 +316,7 @@
248 sst.actions.click_button(sign_me_in_button)
249
250
251-class YourAccount(u1testutils.sst.Page):
252+class YourAccount(PageWithUserSubheader):
253 """Your account page of the Ubuntu Single Sign On website.
254
255 This is a subclass of the Page object. It extends the constructor to
256@@ -305,32 +335,14 @@
257 title = "{0}'s details"
258 url_path = '/'
259
260- def __init__(self, user_name):
261+ def __init__(self, user_name, check=True):
262 self.title = self.title.format(user_name)
263- super(YourAccount, self).__init__()
264- self.sub_header = _UserSubHeader()
265-
266-
267-class _UserSubHeader(object):
268-
269- @log_action(logging.info)
270- def log_out(self):
271- """Log out from the web site."""
272- sst.actions.click_link('logout-link')
273- return YouHaveBeenLoggedOut()
274-
275-
276-class YouHaveBeenLoggedOut(u1testutils.sst.Page):
277- """Your account page of the Ubuntu Single Sign On website.
278-
279- This is a subclass of the Page object.
280-
281- Instance variables:
282- title -- The title of the page. It's build when the page is instantiated
283- using the user name.
284- url_path -- The path of the page.
285-
286- """
287+ super(YourAccount, self).__init__(check)
288+
289+
290+class YouHaveBeenLoggedOut(PageWithAnonymousSubheader):
291+ """Your account page of the Ubuntu Single Sign On website."""
292
293 title = 'You have been logged out'
294 url_path = '/\+logout'
295+ headings1 = ['Ubuntu Single Sign On', 'You have been logged out']
296
297=== modified file 'u1testutils/sst/__init__.py'
298--- u1testutils/sst/__init__.py 2013-04-12 16:02:03 +0000
299+++ u1testutils/sst/__init__.py 2013-04-14 03:49:22 +0000
300@@ -73,10 +73,14 @@
301 self.assert_page_is_open()
302
303 @log_action(logging.info)
304- def open_page(self):
305+ def open_page(self, check=True):
306 """Open the page."""
307 assert self.url_path is not None
308- sst.actions.go_to(self.url_path)
309+ # We need to remove the \ used to escape the special characters of the
310+ # path.
311+ sst.actions.go_to(self.url_path.replace('\\', ''))
312+ if check:
313+ self.assert_page_is_open()
314 return self
315
316 def assert_page_is_open(self):
317@@ -117,7 +121,9 @@
318 current_url_path = urlparse.urlparse(current_url).path
319 # Make sure that there are no more characters at the end of the path.
320 url_path_regexp = self.url_path + '$'
321- assert re.match(url_path_regexp, current_url_path)
322+ assert re.match(url_path_regexp, current_url_path), \
323+ "The current URL path {0} doesn't match {1}".format(
324+ current_url_path, url_path_regexp)
325
326 def assert_headings1(self):
327 """Assert the h1 elements of the page."""
328
329=== modified file 'u1testutils/sst/selftests/unit/test_pages.py'
330--- u1testutils/sst/selftests/unit/test_pages.py 2013-04-12 16:02:03 +0000
331+++ u1testutils/sst/selftests/unit/test_pages.py 2013-04-14 03:49:22 +0000
332@@ -23,6 +23,12 @@
333
334 class PageTestCase(testtools.TestCase):
335
336+ def create_patch(self, name):
337+ patcher = mock.patch(name)
338+ thing = patcher.start()
339+ self.addCleanup(patcher.stop)
340+ return thing
341+
342 def test_assert_page_is_open_on_instantiation(self):
343 with mock.patch.object(Page, 'assert_page_is_open') as mock_assert:
344 Page()
345@@ -33,19 +39,42 @@
346 Page(check=False)
347 assert not mock_assert.called
348
349- def test_open_page(self):
350+ def test_open_page_goes_to_url_path(self):
351 page = Page(check=False)
352 page.url_path = '/test/path'
353 with mock.patch('sst.actions.go_to') as mock_action:
354- returned_page = page.open_page()
355+ returned_page = page.open_page(check=False)
356 mock_action.assert_called_with('/test/path')
357 self.assertEquals(page, returned_page)
358
359+ def test_open_page_asserts_page_is_opened(self):
360+ self.create_patch('sst.actions.go_to')
361+ with mock.patch.object(Page, 'assert_page_is_open') as mock_assert:
362+ page = Page(check=False)
363+ page.url_path = '/test/path'
364+ page.open_page()
365+ mock_assert.assert_called_once_with()
366+
367+ def test_open_page_wihtout_check(self):
368+ self.create_patch('sst.actions.go_to')
369+ with mock.patch.object(Page, 'assert_page_is_open') as mock_assert:
370+ page = Page(check=False)
371+ page.url_path = '/test/path'
372+ page.open_page(check=False)
373+ assert not mock_assert.called
374+
375 def test_open_page_without_path(self):
376 page = Page(check=False)
377 page.url_path = None
378 self.assertRaises(AssertionError, page.open_page)
379
380+ def test_open_page_with_special_character_in_url_path(self):
381+ page = Page(check=False)
382+ page.url_path = '/test/\+path'
383+ with mock.patch('sst.actions.go_to') as mock_action:
384+ page.open_page(check=False)
385+ mock_action.assert_called_with('/test/+path')
386+
387
388 class PageWithOnlyHeadingsAssertions(Page):
389

Subscribers

People subscribed via source and target branches

to all changes: