Merge lp:~elopio/u1-test-utils/update_sso_pages1-tests1 into lp:u1-test-utils

Proposed by Leo Arias
Status: Merged
Approved by: Leo Arias
Approved revision: 92
Merged at revision: 84
Proposed branch: lp:~elopio/u1-test-utils/update_sso_pages1-tests1
Merge into: lp:u1-test-utils
Diff against target: 397 lines (+250/-63)
8 files modified
fabfile/development.py (+6/-2)
requirements.txt (+1/-1)
u1testutils/sso/selftests/acceptance/test_sst_helpers.py (+151/-0)
u1testutils/sso/selftests/unit/test_sst_helpers.py (+0/-40)
u1testutils/sso/sst/__init__.py (+19/-0)
u1testutils/sso/sst/pages.py (+0/-20)
u1testutils/sst/__init__.py (+18/-0)
u1testutils/sst/selftests/acceptance/test_string_page.py (+55/-0)
To merge this branch: bzr merge lp:~elopio/u1-test-utils/update_sso_pages1-tests1
Reviewer Review Type Date Requested Status
Vincent Ladeuil (community) Approve
Review via email: mp+172749@code.launchpad.net

Commit message

Added acceptance tests for the SSO SST helpers, using fake string HTML pages.

Description of the change

Now that we are using data-qa-ids to identify the pages, the code necessary for the string HTML fakes is a lot less.
Also, the ubuntu one templates were released on SSO, so it will remain stable for a while and it's a good chance to add this tests.
It's a good time to focus on the error messages that we show when a test fails, and these kind of tests help a lot with this.
And finally, we are always striving for Vincent's happiness ;)

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

Second reading always makes more sense :)

So, yeah for data-qa-ids \o/ (thanks nessita ?)

> Added the SSO acceptance tests to the suite. TODO: use vila's runner, that's a lot better than this.

see sst trunk revno 421 file src/sst/__init__.py for a very close example.

Good job !

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'fabfile/development.py'
2--- fabfile/development.py 2013-07-02 16:34:57 +0000
3+++ fabfile/development.py 2013-07-03 07:55:33 +0000
4@@ -70,6 +70,10 @@
5
6
7 def _load_acceptance_tests(suite):
8- suite.addTest(
9- unittest.TestLoader().discover('u1testutils/sst/selftests/acceptance'))
10+ for path in (
11+ 'u1testutils/sst/selftests/acceptance',
12+ 'u1testutils/sso/selftests/acceptance',
13+ ):
14+ suite.addTest(
15+ unittest.TestLoader().discover(path))
16 return suite
17
18=== modified file 'requirements.txt'
19--- requirements.txt 2013-07-02 16:23:53 +0000
20+++ requirements.txt 2013-07-03 07:55:33 +0000
21@@ -7,5 +7,5 @@
22 Twisted
23 bzr+ssh://bazaar.launchpad.net/~bloodearnest/localmail/trunk@36
24 bzr+http://bazaar.launchpad.net/~ubuntuone-hackers/payclient/trunk@4
25-bzr+http://bazaar.launchpad.net/~canonical-isd-qa/selenium-simple-test/trunk@377
26+bzr+http://bazaar.launchpad.net/~canonical-isd-qa/selenium-simple-test/trunk@421
27 bzr+http://bazaar.launchpad.net/~canonical-isd-hackers/canonical-identity-provider/ssoclient@3
28
29=== added directory 'u1testutils/sso/selftests/acceptance'
30=== added file 'u1testutils/sso/selftests/acceptance/__init__.py'
31=== added file 'u1testutils/sso/selftests/acceptance/test_sst_helpers.py'
32--- u1testutils/sso/selftests/acceptance/test_sst_helpers.py 1970-01-01 00:00:00 +0000
33+++ u1testutils/sso/selftests/acceptance/test_sst_helpers.py 2013-07-03 07:55:33 +0000
34@@ -0,0 +1,151 @@
35+# Copyright 2013 Canonical Ltd.
36+#
37+# This program is free software: you can redistribute it and/or modify it
38+# under the terms of the GNU Lesser General Public License version 3, as
39+# published by the Free Software Foundation.
40+#
41+# This program is distributed in the hope that it will be useful, but
42+# WITHOUT ANY WARRANTY; without even the implied warranties of
43+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
44+# PURPOSE. See the GNU Lesser General Public License for more details.
45+#
46+# You should have received a copy of the GNU General Public License along
47+# with this program. If not, see <http://www.gnu.org/licenses/>.
48+
49+import os
50+import shutil
51+import tempfile
52+
53+from sst import cases
54+
55+import u1testutils.sst
56+from u1testutils import logging
57+from u1testutils.sso import (
58+ data,
59+ sst as sso_sst,
60+)
61+
62+
63+_LOGIN_FROM_REDIRECT_PAGE_SOURCE = (
64+ """
65+ <html data-qa-id="login">
66+ <head>
67+ <title>Log in</title>
68+ </head>
69+ <form data-qa-id="login_form" action="{0}" method="get" >
70+ <input id="id_email" type="email" />
71+ <input id="id_password" type="password" />
72+ <button data-qa-id="login_button" type="submit" />
73+ </form>
74+ </html>
75+ """
76+)
77+
78+_SITE_NOT_RECOGNIZED_PAGE_SOURCE = (
79+ """
80+ <html data-qa-id="decide">
81+ <div data-qa-id="info-items">
82+ <input type="checkbox"/>
83+ </div>
84+ <button data-qa-id="rp_confirm_login" />
85+ </html>
86+ """
87+)
88+
89+_WRONG_PAGE_SOURCE = (
90+ """
91+ <html data-qa-id="wrong">
92+ </html>
93+ """
94+)
95+
96+
97+class SignInTestCase(cases.SSTTestCase, logging.LogHandlerTestCase):
98+
99+ xserver_headless = True
100+
101+ def setUp(self):
102+ self.temp_directory = tempfile.mkdtemp()
103+ self.addCleanup(shutil.rmtree, self.temp_directory)
104+ self.base_url = 'file://' + self.temp_directory
105+ super(SignInTestCase, self).setUp()
106+
107+ def test_sign_in_to_wrong_page(self):
108+ page_path = os.path.join(self.temp_directory, 'wrong')
109+ u1testutils.sst.StringHTMLPage(
110+ _WRONG_PAGE_SOURCE, page_path, qa_anchor='wrong',
111+ open_page=True)
112+
113+ self.assertRaises(
114+ AssertionError, sso_sst.sign_in, user=None,
115+ is_site_recognized=False)
116+
117+ def test_sign_in_with_already_signed_user_to_site_recognized(self):
118+ # Sign in will do nothing.
119+ sso_sst.sign_in(user=None, is_site_recognized=True)
120+
121+ def test_sign_in_with_already_signed_user_to_site_not_recognized(self):
122+ self._write_fake_site_not_recognized_page(open_page=True)
123+ sso_sst.sign_in(user=None, is_site_recognized=False)
124+
125+ def _write_fake_site_not_recognized_page(self, open_page, token='token'):
126+ token_directory = os.path.join(self.temp_directory, token)
127+ os.mkdir(token_directory)
128+ site_not_recognized_page_path = os.path.join(
129+ token_directory, '+decide')
130+ u1testutils.sst.StringHTMLPage(
131+ _SITE_NOT_RECOGNIZED_PAGE_SOURCE, site_not_recognized_page_path,
132+ qa_anchor='decide', open_page=open_page)
133+ return site_not_recognized_page_path
134+
135+ def test_sign_in_to_site_recognized(self):
136+ self._write_fake_log_in_page(open_page=True)
137+ user = data.User.make_unique()
138+
139+ sso_sst.sign_in(user, is_site_recognized=True)
140+
141+ def _write_fake_log_in_page(
142+ self, open_page, token='token',
143+ site_not_recognized_page_path=None):
144+ log_in_page_source = _LOGIN_FROM_REDIRECT_PAGE_SOURCE
145+ if site_not_recognized_page_path is not None:
146+ log_in_page_source = log_in_page_source.format(
147+ site_not_recognized_page_path)
148+ token_directory = os.path.join(self.temp_directory, token)
149+ os.mkdir(token_directory)
150+ log_in_page_path = os.path.join(token_directory, '+decide')
151+ u1testutils.sst.StringHTMLPage(
152+ log_in_page_source, log_in_page_path, qa_anchor='login',
153+ open_page=open_page)
154+
155+ def test_sign_in_to_site_not_recognized(self):
156+ self._write_fake_log_in_to_site_not_recognized_pages(open_page=True)
157+ user = data.User.make_unique()
158+
159+ sso_sst.sign_in(user, is_site_recognized=False)
160+
161+ def _write_fake_log_in_to_site_not_recognized_pages(self, open_page):
162+ # We do not check the tokens, so the easiest thing is to have the
163+ # two pages in separate paths, to write both to HTML files and be able
164+ # to open the second from the first. In real life, the tokens are the
165+ # same. To check the token can be a future improvement.
166+ # -- elopio - 2013-07-03
167+ site_not_recognized_page_path = (
168+ self._write_fake_site_not_recognized_page(
169+ open_page=False, token='not_recognized'))
170+ self._write_fake_log_in_page(
171+ open_page=open_page, token='login',
172+ site_not_recognized_page_path=site_not_recognized_page_path)
173+
174+ def test_sign_in_with_unexpected_site_not_recognized(self):
175+ self._write_fake_log_in_to_site_not_recognized_pages(open_page=True)
176+ user = data.User.make_unique()
177+
178+ self.assertRaises(
179+ AssertionError, sso_sst.sign_in, user, is_site_recognized=True)
180+ self.assertLogLevelContains(
181+ 'ERROR',
182+ 'Please check that you are logging in from a server that is '
183+ 'trusted by SSO. Otherwise, the unexpected Site Not Recognized '
184+ 'page will be opened.'
185+ )
186
187=== removed file 'u1testutils/sso/selftests/unit/test_sst_helpers.py'
188--- u1testutils/sso/selftests/unit/test_sst_helpers.py 2013-05-06 21:02:29 +0000
189+++ u1testutils/sso/selftests/unit/test_sst_helpers.py 1970-01-01 00:00:00 +0000
190@@ -1,40 +0,0 @@
191-# Copyright 2013 Canonical Ltd.
192-#
193-# This program is free software: you can redistribute it and/or modify it
194-# under the terms of the GNU Lesser General Public License version 3, as
195-# published by the Free Software Foundation.
196-#
197-# This program is distributed in the hope that it will be useful, but
198-# WITHOUT ANY WARRANTY; without even the implied warranties of
199-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
200-# PURPOSE. See the GNU Lesser General Public License for more details.
201-#
202-# You should have received a copy of the GNU General Public License along
203-# with this program. If not, see <http://www.gnu.org/licenses/
204-
205-import mock
206-
207-import u1testutils.logging
208-from u1testutils.sso.sst import pages
209-
210-
211-class LogInFromRedirectTestCase(u1testutils.logging.LogHandlerTestCase):
212-
213- def test_site_without_rpconfig(self):
214- with mock.patch.object(pages.LogInFromRedirect, 'assert_page_is_open'):
215- page = pages.LogInFromRedirect()
216-
217- with mock.patch('sst.actions.get_elements') as mock_elements:
218- mock_elements.return_value = []
219- headings2 = ['Log in to Ubuntu Single Sign On', 'Are you new?']
220- for heading in headings2:
221- mock_heading_element = mock.Mock()
222- mock_heading_element.text = heading
223- mock_elements.return_value.append(mock_heading_element)
224- with self.assertRaises(AssertionError):
225- page.assert_headings2()
226- self.assertLogLevelContains(
227- 'ERROR',
228- 'Please check that you are logging in from a server with '
229- 'an rpconfig on SSO. Otherwise, the headings in the page '
230- 'will not be the ones we expect.')
231
232=== modified file 'u1testutils/sso/sst/__init__.py'
233--- u1testutils/sso/sst/__init__.py 2013-06-14 17:20:49 +0000
234+++ u1testutils/sso/sst/__init__.py 2013-07-03 07:55:33 +0000
235@@ -11,12 +11,18 @@
236 #
237 # You should have received a copy of the GNU General Public License along
238 # with this program. If not, see <http://www.gnu.org/licenses/>.
239+
240+import logging
241+
242 import sst.actions
243
244 from u1testutils.sso import environment, mail
245 from u1testutils.sso.sst import pages
246
247
248+logger = logging.getLogger('User test')
249+
250+
251 def create_new_account(user, is_site_recognized=True):
252 """Create a new account on Ubuntu Single Sign On.
253
254@@ -90,6 +96,7 @@
255 # User is already signed in so SSO will just redirect back to the
256 # main site.
257 pass
258+ _assert_site_not_recognized_page_not_opened()
259 else:
260 if user is not None:
261 log_in = pages.LogInFromRedirect()
262@@ -102,6 +109,18 @@
263 site_not_recognized.yes_sign_me_in()
264
265
266+def _assert_site_not_recognized_page_not_opened():
267+ try:
268+ sst.actions.fails(pages.SiteNotRecognized)
269+ except AssertionError:
270+ suggestion = (
271+ 'Please check that you are logging in from a server that is '
272+ 'trusted by SSO. Otherwise, the unexpected Site Not Recognized '
273+ 'page will be opened.')
274+ logger.error(suggestion)
275+ raise
276+
277+
278 def log_out():
279 """Log out from the Ubuntu Single Sign On site.
280
281
282=== modified file 'u1testutils/sso/sst/pages.py'
283--- u1testutils/sso/sst/pages.py 2013-06-14 17:20:49 +0000
284+++ u1testutils/sso/sst/pages.py 2013-07-03 07:55:33 +0000
285@@ -128,26 +128,6 @@
286 self._click_create_new_account()
287 return CreateAccountFromRedirect()
288
289- def assert_headings2(self):
290- """Assert the h2 elements of the page.
291-
292- This method wraps the one from the parent class in order to log
293- suggestions about the most common environment errors that make it fail.
294-
295- """
296- try:
297- super(LogInFromRedirect, self).assert_headings2()
298- except AssertionError:
299- heading2_without_rpconfig = 'Log in to Ubuntu Single Sign On'
300- if heading2_without_rpconfig in self._get_elements_text('h2'):
301- suggestion = (
302- 'Please check that you are logging in from a server with '
303- 'an rpconfig on SSO. Otherwise, the headings in the page '
304- 'will not be the ones we expect.'
305- )
306- logger.error(suggestion)
307- raise
308-
309
310 class PageWithAnonymousSubheader(u1testutils.sst.Page):
311
312
313=== modified file 'u1testutils/sst/__init__.py'
314--- u1testutils/sst/__init__.py 2013-05-16 18:16:06 +0000
315+++ u1testutils/sst/__init__.py 2013-07-03 07:55:33 +0000
316@@ -174,3 +174,21 @@
317 if sst.actions.exists_element(css_class='error'):
318 logger.error(
319 ', '.join(self._get_elements_text(css_class='error')))
320+
321+
322+class StringHTMLPage(Page):
323+ """Fake page for testing, with the source in a string attribute."""
324+
325+ def __init__(self, page_source, url_path, qa_anchor, open_page=False):
326+ # Do not call the super __init__ because it will assert that the page
327+ # is open. We will do that manually for the tests that require it.
328+ self.url_path = url_path
329+ self.page_source = page_source
330+ self.qa_anchor = qa_anchor
331+ self._make_temp_page()
332+ if open_page:
333+ self._open_page()
334+
335+ def _make_temp_page(self):
336+ with open(self.url_path, 'w') as page_file:
337+ page_file.write(self.page_source)
338
339=== added file 'u1testutils/sst/selftests/acceptance/test_string_page.py'
340--- u1testutils/sst/selftests/acceptance/test_string_page.py 1970-01-01 00:00:00 +0000
341+++ u1testutils/sst/selftests/acceptance/test_string_page.py 2013-07-03 07:55:33 +0000
342@@ -0,0 +1,55 @@
343+# Copyright 2013 Canonical Ltd.
344+#
345+# This program is free software: you can redistribute it and/or modify it
346+# under the terms of the GNU Lesser General Public License version 3, as
347+# published by the Free Software Foundation.
348+#
349+# This program is distributed in the hope that it will be useful, but
350+# WITHOUT ANY WARRANTY; without even the implied warranties of
351+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
352+# PURPOSE. See the GNU Lesser General Public License for more details.
353+#
354+# You should have received a copy of the GNU General Public License along
355+# with this program. If not, see <http://www.gnu.org/licenses/>.
356+
357+import os
358+import shutil
359+import tempfile
360+
361+from sst import actions, cases
362+
363+import u1testutils.sst
364+
365+
366+class StringPageTestCase(cases.SSTTestCase):
367+
368+ xserver_headless = True
369+ base_url = 'file://'
370+ page_source = (
371+ """
372+ <html data-qa-id='test-qa-anchor'>
373+ </html>
374+ """
375+ )
376+
377+ def setUp(self):
378+ super(StringPageTestCase, self).setUp()
379+ self.temp_directory = tempfile.mkdtemp()
380+ self.addCleanup(shutil.rmtree, self.temp_directory)
381+ self.page_url_path = os.path.join(self.temp_directory, 'test')
382+
383+ def test_assert_string_page_is_opened(self):
384+ page = u1testutils.sst.StringHTMLPage(
385+ self.page_source, self.page_url_path, qa_anchor='test-qa-anchor',
386+ open_page=True)
387+ page.assert_page_is_open()
388+
389+ def test_string_page_not_opened(self):
390+ page = u1testutils.sst.StringHTMLPage(
391+ self.page_source, self.page_url_path, qa_anchor='test-qa-anchor')
392+ # The page is not opened.
393+ actions.fails(page.assert_page_is_open)
394+ # But its file is created.
395+ with open(self.page_url_path) as page_file:
396+ page_source = page_file.read()
397+ self.assertEqual(page_source, self.page_source)

Subscribers

People subscribed via source and target branches

to all changes: