Merge lp:~elopio/canonical-identity-provider/refactory_with_u1testutils-1 into lp:canonical-identity-provider/release

Proposed by Leo Arias
Status: Merged
Approved by: Leo Arias
Approved revision: no longer in the source branch.
Merged at revision: 811
Proposed branch: lp:~elopio/canonical-identity-provider/refactory_with_u1testutils-1
Merge into: lp:canonical-identity-provider/release
Diff against target: 378 lines (+155/-72)
6 files modified
identityprovider/tests/acceptance/devices/add_device.py (+1/-4)
identityprovider/tests/acceptance/pages.py (+94/-0)
identityprovider/tests/acceptance/shared/helpers.py (+56/-64)
requirements/testing.txt (+2/-2)
scripts/acceptance-dev.sh (+1/-1)
scripts/run-acceptance-tests (+1/-1)
To merge this branch: bzr merge lp:~elopio/canonical-identity-provider/refactory_with_u1testutils-1
Reviewer Review Type Date Requested Status
Ricardo Kirkner (community) Approve
Review via email: mp+158722@code.launchpad.net

Commit message

Use page object on the common acceptance helpers.

Description of the change

This is the first safe point of the refactor. I haven't changed any API, so there are some things left TODO.
In the next branches we will be deprecating this helpers, in favor of base test cases that will do all the page navigation and the tests will need to focus only on one or two pages.

To post a comment you must log in.
Revision history for this message
Leo Arias (elopio) wrote :

$ ./scripts/run-acceptance-tests dev
[...]
----------------------------------------------------------------------
Ran 110 tests in 1628.942s

OK

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

$ ./scripts/run-acceptance-tests dev
----------------------------------------------------------------------
Ran 110 tests in 1308.872s

OK

Save again :)

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

l. 35,37: no need to have the extra whitespace
l. 53: we could be using the new data-qa-id attrs for looking up elements (for better disambiguation)
l. 365,378: why did you remove the extended=true param?

review: Needs Fixing
Revision history for this message
Ricardo Kirkner (ricardokirkner) wrote :

l. 19-20, we could replace this with helpers.logout_and_in()

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

I removed the extended=true because it prints the page on the test log. The htmls are huge, so it doesn't help understanding what's wrong. We get the html with screenshot=True. I filed a bug on SST to change the name of that parameter.

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

<elopio> pindonga: I was planning to add the data-qa-id's in next branches, as I wanted this just to be a reorg of the actions.
<elopio> can I leave it like this?
<elopio> pindonga: and I removed the extended=true because it prints the page on the test log.
<pindonga> yup, comment that on the mp though pls

Revision history for this message
Ricardo Kirkner (ricardokirkner) wrote :

Despite the resistance to nit-picking, LGTM. Many things are being changed in a subsequent MP according to elopio, so not worth changing right now.

review: Approve
Revision history for this message
Ricardo Kirkner (ricardokirkner) wrote :

LGTM

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (69.5 KiB)

The attempt to merge lp:~elopio/canonical-identity-provider/refactory_with_u1testutils-1 into lp:canonical-identity-provider failed. Below is the output from the failed tests.

Updating download cache at dir /mnt/tarmac/isd-download-cache
Using saved parent location: bzr+ssh://bazaar.launchpad.net/~canonical-isd-hackers/+junk/download-cache/
No revisions or tags to pull.
[localhost] local: which virtualenv
[localhost] local: /usr/bin/python /usr/bin/virtualenv --version
[localhost] local: /usr/bin/python /usr/bin/virtualenv --distribute --clear .env
Not deleting .env/bin
New python executable in .env/bin/python
Installing distribute.............................................................................................................................................................................................done.
Installing pip...............done.
[localhost] local: dpkg -l libpq-dev 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l libxml2-dev 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l libxslt1-dev 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l memcached 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l postgresql-plpython-9.1 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l python-dev 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l python-m2crypto 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l swig 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l config-manager 2> /dev/null | grep '^ii' | wc -l
[localhost] local: dpkg -l python-egenix-mx-base-dev 2> /dev/null | grep '^ii' | wc -l
[localhost] local: rm -rf M2Crypto*
[localhost] local: ln -s /usr/lib/python2.7/dist-packages/M2Crypto* .
[localhost] local: /usr/lib/config-manager/cm.py update /tmp/tmpqiWvt2
[localhost] local: . /mnt/tarmac/cache/canonical-identity-provider/.env/bin/activate && make install PACKAGES="-r /mnt/tarmac/cache/canonical-identity-provider/requirements.txt"
pip install --find-links=file:///mnt/tarmac/isd-download-cache --no-index pip==dev
Ignoring indexes: http://pypi.python.org/simple/
Downloading/unpacking pip==dev
  Running setup.py egg_info for package pip

    warning: no files found matching '*.html' under directory 'docs'
    warning: no previously-included files matching '*.txt' found under directory 'docs/_build'
    no previously-included directories found matching 'docs/_build/_sources'
Installing collected packages: pip
  Found existing installation: pip 1.1
    Uninstalling pip:
      Successfully uninstalled pip
  Running setup.py install for pip

    warning: no files found matching '*.html' under directory 'docs'
    warning: no previously-included files matching '*.txt' found under directory 'docs/_build'
    no previously-included directories found matching 'docs/_build/_sources'
    Installing pip script to /mnt/tarmac/cache/canonical-identity-provider/.env/bin
    Installing pip-2.7 script to /mnt/tarmac/cache/canonical-identity-provider/.env/bin
Successfully installed pip
Cleaning up...
pip install --find-links=. --no-index -r /mnt/tarmac/cache/canonical-identity-provider/requirements.txt
Ignoring indexes: http://pypi.python.org...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'identityprovider/tests/acceptance/devices/add_device.py'
--- identityprovider/tests/acceptance/devices/add_device.py 2013-01-24 17:02:52 +0000
+++ identityprovider/tests/acceptance/devices/add_device.py 2013-04-19 19:28:26 +0000
@@ -15,8 +15,6 @@
15 get_element,15 get_element,
16 go_to,16 go_to,
17 set_radio_value,17 set_radio_value,
18 start,
19 stop,
20 write_textfield,18 write_textfield,
21)19)
22from u1testutils.sst import config20from u1testutils.sst import config
@@ -126,8 +124,7 @@
126124
127# Stop the browser and restart to ensure 2F Flag is still set125# Stop the browser and restart to ensure 2F Flag is still set
128# Tests defect #930377126# Tests defect #930377
129stop()127helpers.logout()
130start()
131helpers.login()128helpers.login()
132go_to(urls.DEVICES)129go_to(urls.DEVICES)
133130
134131
=== added file 'identityprovider/tests/acceptance/pages.py'
--- identityprovider/tests/acceptance/pages.py 1970-01-01 00:00:00 +0000
+++ identityprovider/tests/acceptance/pages.py 2013-04-19 19:28:26 +0000
@@ -0,0 +1,94 @@
1# Copyright 2013 Canonical Ltd.
2# This software is licensed under the GNU Affero General Public License
3# version 3 (see the file LICENSE).
4
5import logging
6
7import sst.actions
8import u1testutils.sso.sst.pages
9
10from u1testutils.sst import log_action
11
12
13class YourEmailAddresses(u1testutils.sso.sst.pages.PageWithUserSubheader):
14
15 title = "{0}'s email addresses"
16 url_path = '/+emails'
17
18 def assert_title(self):
19 user_name = self.subheader.get_user_name()
20 sst.actions.assert_title(self.title.format(user_name))
21
22 @log_action(logging.info)
23 def add_email(self, email_address):
24 sst.actions.write_textfield('id_newemail', email_address)
25 sst.actions.click_button(sst.actions.get_element(name='continue'))
26
27 @log_action(logging.info)
28 def delete_email(self):
29 remove_link = sst.actions.get_element(tag='a', text='Delete')
30 sst.actions.click_link(remove_link)
31 return DeleteEmail()
32
33
34class EnterConfirmationCode(u1testutils.sso.sst.pages.PageWithUserSubheader):
35
36 title = 'Enter confirmation code'
37 url_path = '/+enter_token'
38
39 @log_action(logging.info)
40 def confirm(self, confirmation_code, email_address):
41 self._fill_confirmation_form(confirmation_code, email_address)
42 self._continue()
43 return u1testutils.sso.sst.pages.CompleteEmailValidation()
44
45 def _fill_confirmation_form(self, confirmation_code, email_address):
46 sst.actions.write_textfield('id_confirmation_code', confirmation_code)
47 sst.actions.write_textfield('id_email', email_address)
48
49 def _continue(self):
50 sst.actions.click_button(sst.actions.get_element(name='continue'))
51
52 @log_action(logging.info)
53 def confirm_with_error(self, confirmation_code, email_address):
54 self._fill_confirmation_form(confirmation_code, email_address)
55 self._continue()
56 return self
57
58
59class DeleteEmail(u1testutils.sso.sst.pages.PageWithUserSubheader):
60
61 title = 'Delete unverified email'
62 url_path = '/+remove-email'
63
64 @log_action(logging.info)
65 def confirm(self):
66 confirm_button = sst.actions.get_element(name='delete')
67 sst.actions.click_button(confirm_button)
68 user_name = self.subheader.get_user_name()
69 return YourEmailAddresses(user_name)
70
71
72class ResetPassword(u1testutils.sso.sst.pages.PageWithAnonymousSubheader):
73
74 title = 'Reset password'
75 url_path = '/+forgot_password'
76 headings1 = [
77 'Ubuntu Single Sign On',
78 'Reset your Ubuntu Single Sign On password'
79 ]
80
81 @log_action(logging.info)
82 def request_password_reset(self, email_address):
83 sst.actions.write_textfield('id_email', email_address)
84 # Even though the recaptcha field is ignored for our tests, we do
85 # want to verify that it is on the page.
86 sst.actions.write_textfield('recaptcha_response_field', 'ignored')
87 sst.actions.click_button(sst.actions.get_element(name='continue'))
88
89
90class LogInFromRedirect(u1testutils.sso.sst.pages.LogIn):
91
92 url_path = '/.*/\+decide'
93 is_url_path_regex = True
94 headings2 = ['Log in', 'Are you new?']
095
=== modified file 'identityprovider/tests/acceptance/shared/helpers.py'
--- identityprovider/tests/acceptance/shared/helpers.py 2013-04-12 16:27:10 +0000
+++ identityprovider/tests/acceptance/shared/helpers.py 2013-04-19 19:28:26 +0000
@@ -1,15 +1,15 @@
1import re1import re
2from urllib import quote2from urllib import quote
33
4import u1testutils.sso.sst.pages
5
4from django.conf import settings6from django.conf import settings
5from sst.actions import (7from sst.actions import (
6 assert_checkbox_value,8 assert_checkbox_value,
7 assert_text_contains,9 assert_text_contains,
8 assert_title,10 assert_title,
9 assert_title_contains,
10 assert_url,11 assert_url,
11 click_button,12 click_button,
12 click_link,
13 exists_element,13 exists_element,
14 get_base_url,14 get_base_url,
15 get_current_url,15 get_current_url,
@@ -19,13 +19,15 @@
19 set_radio_value,19 set_radio_value,
20 skip,20 skip,
21 wait_for,21 wait_for,
22 write_textfield,
23)22)
24from sst import config23from sst import config
25
26from u1testutils import mail24from u1testutils import mail
27from u1testutils.sso import mail as sso_mail25from u1testutils.sso import (
26 data,
27 mail as sso_mail
28)
2829
30from identityprovider.tests.acceptance import pages
29from identityprovider.tests.acceptance.shared import devices, urls31from identityprovider.tests.acceptance.shared import devices, urls
3032
3133
@@ -51,30 +53,34 @@
51 email_address = mail.make_unique_test_email_address()53 email_address = mail.make_unique_test_email_address()
5254
53 vcode = None55 vcode = None
54 go_to(urls.NEW_ACCOUNT)56
55 wait_for(assert_title, 'Create account')57 create_account = u1testutils.sso.sst.pages.CreateAccount(open_page=True)
56 fill_registration_form(email_address, displayname, password)58
57 click_button(get_element(name='continue'))59 user = data.User(displayname, email_address, password)
60 create_account.create_ubuntu_sso_account(user)
5861
59 vcode = None62 vcode = None
60 if 'allow_unverified' in config.flags:63 if 'allow_unverified' in config.flags:
61 wait_for(assert_title_contains, "%s's details" % displayname)64 u1testutils.sso.sst.pages.YourAccount(user.full_name)
62 # default is not to verify for ALLOW_UNVERIFIED65 # default is not to verify for ALLOW_UNVERIFIED
63 if verify is None:66 if verify is None:
64 verify = False67 verify = False
65 if verify:68 if verify:
66 vlink = sso_mail.get_verification_link_for_address(email_address)69 vlink = sso_mail.get_verification_link_for_address(email_address)
67 go_to(vlink)70 go_to(vlink)
68 click_button(get_element(css_class='btn'))71 validate_email = \
72 u1testutils.sso.sst.pages.CompleteEmailValidation()
73 validate_email.confirm()
69 else:74 else:
70 wait_for(assert_title_contains, 'Account creation mail sent')75 mail_sent = u1testutils.sso.sst.pages.AccountCreationMailSent()
71 # old flow requries verify, usually76 # old flow requries verify, usually
72 if verify is None:77 if verify is None:
73 verify = True78 verify = True
74 if verify:79 if verify:
75 vcode = sso_mail.get_verification_code_for_address(email_address)80 vcode = sso_mail.get_verification_code_for_address(email_address)
76 write_textfield(get_element(name='confirmation_code'), vcode)81 # TODO add the site not recognized parameter and use the right
77 click_button(get_element(css_class='btn'))82 # public method.
83 mail_sent._confirm_email(vcode)
7884
79 _LAST_EMAIL = email_address85 _LAST_EMAIL = email_address
80 _LAST_PASSWORD = password86 _LAST_PASSWORD = password
@@ -83,34 +89,24 @@
8389
8490
85def fill_registration_form(91def fill_registration_form(
86 email,92 email, displayname="My Name", password="Admin007", passwordconf=None):
87 displayname="My Name",
88 password="Admin007",
89 passwordconf=None):
9093
91 if passwordconf is None:94 user = data.User(displayname, email, password)
92 passwordconf = password95 create_account = u1testutils.sso.sst.pages.CreateAccount(open_page=True)
93 write_textfield('id_displayname', displayname)96 # TODO we either make the fill public, or call a public higher method,
94 write_textfield('id_email', email)97 # The latter sounds better.
95 write_textfield('id_password', password)98 create_account._fill_new_account_form(user, passwordconf)
96 write_textfield('id_passwordconfirm', passwordconf)
97 if exists_element(id='recaptcha_response_field'):
98 write_textfield('recaptcha_response_field', 'ignored')
9999
100100
101def add_email(address, verify=False):101def add_email(address, verify=False):
102 go_to(urls.EMAILS)102 your_email_addresses = pages.YourEmailAddresses(open_page=True)
103 wait_for(assert_title_contains, "'s email addresses")103 your_email_addresses.add_email(address)
104 write_textfield('id_newemail', address)
105 click_button(get_element(name='continue'))
106 code = sso_mail.get_verification_code_for_address(address)104 code = sso_mail.get_verification_code_for_address(address)
107 if verify:105 if verify:
108 go_to(urls.ENTER_TOKEN)106 enter_confirmation_code = pages.EnterConfirmationCode(open_page=True)
109 wait_for(write_textfield, 'id_confirmation_code', code)107 complete_email_validation = enter_confirmation_code.confirm(
110 write_textfield('id_email', address)108 code, address)
111 click_button(get_element(name='continue'))109 complete_email_validation.confirm()
112 assert_title('Complete email address validation')
113 click_button(get_element(name='continue'))
114 return code110 return code
115111
116112
@@ -154,21 +150,20 @@
154150
155151
156def delete_email():152def delete_email():
157 go_to(urls.EMAILS)153 your_email_addresses = pages.YourEmailAddresses(open_page=True)
158 remove_link = get_element(tag='a', text='Delete')154 delete_email_confirmation = your_email_addresses.delete_email()
159 click_link(remove_link)155 delete_email_confirmation.confirm()
160 confirm_button = get_element(name='delete')
161 click_button(confirm_button)
162156
163157
164def try_to_validate_email(address, code, finish_validation=True):158def try_to_validate_email(address, code, finish_validation=True):
165 go_to(urls.ENTER_TOKEN)159 # TODO implement the navigation and use the right public methods.
166 wait_for(write_textfield, 'id_confirmation_code', code)160 enter_confirmation_code = pages.EnterConfirmationCode(open_page=True)
167 write_textfield('id_email', address)161 enter_confirmation_code._fill_confirmation_form(
168 click_button(get_element(name='continue'))162 code, address)
163 enter_confirmation_code._continue()
169 if finish_validation:164 if finish_validation:
170 assert_title('Complete email address validation')165 complete = u1testutils.sso.sst.pages.CompleteEmailValidation()
171 click_button(get_element(name='continue'))166 complete.confirm()
172167
173168
174def login_or_register_account(device_cleanup=False):169def login_or_register_account(device_cleanup=False):
@@ -190,10 +185,12 @@
190 if email is None and password is None:185 if email is None and password is None:
191 email = _LAST_EMAIL186 email = _LAST_EMAIL
192 password = _LAST_PASSWORD187 password = _LAST_PASSWORD
193 go_to(urls.HOME)188 log_in = u1testutils.sso.sst.pages.LogIn(open_page=True)
194 write_textfield('id_email', email)189 # TODO we need the user name too.
195 write_textfield('id_password', password)190 user = data.User('TODO', email, password)
196 click_button(get_element(name='continue'))191 # TODO add the site not recognized parameter and use the right public
192 # method.
193 log_in._log_in(user)
197194
198195
199def logout_and_in():196def logout_and_in():
@@ -206,17 +203,13 @@
206203
207204
208def logout():205def logout():
209 go_to(urls.LOGOUT)206 u1testutils.sso.sst.pages.YouHaveBeenLoggedOut(open_page=True)
210207
211208
212def request_password_reset(email_address):209def request_password_reset(email_address):
213 logout()210 logout()
214 go_to(urls.FORGOT_PASSWORD)211 reset_password = pages.ResetPassword(open_page=True)
215 write_textfield('id_email', email_address)212 reset_password.request_password_reset(email_address)
216 # Even though the recaptcha field is ignored for our tests, we do
217 # want to verify that it is on the page.
218 write_textfield('recaptcha_response_field', 'ignored')
219 click_button(get_element(name='continue'))
220213
221214
222def login_to_test_account():215def login_to_test_account():
@@ -254,12 +247,11 @@
254247
255def login_from_redirect(email=settings.QA_ACCOUNT_EMAIL,248def login_from_redirect(email=settings.QA_ACCOUNT_EMAIL,
256 password=settings.QA_ACCOUNT_PASSWORD):249 password=settings.QA_ACCOUNT_PASSWORD):
257 wait_for(assert_title, 'Log in')250 log_in = pages.LogInFromRedirect()
258 write_textfield('id_email', email)251 # TODO we also need the user name.
259 write_textfield('id_password', password)252 user = data.User('TODO', email, password)
260 click_button(get_element(name='continue'))253 site_not_recognized = log_in.log_in_to_site_not_recognized(user)
261 wait_for(assert_title_contains, 'Authenticate to')254 site_not_recognized.yes_sign_me_in()
262 click_button(get_element(name='yes'))
263255
264256
265def check_2f_for_url(url):257def check_2f_for_url(url):
266258
=== modified file 'requirements/testing.txt'
--- requirements/testing.txt 2013-04-12 21:17:08 +0000
+++ requirements/testing.txt 2013-04-19 19:28:26 +0000
@@ -28,6 +28,6 @@
28zope.interface==4.0.128zope.interface==4.0.1
29zope.schema==4.2.029zope.schema==4.2.0
30zope.testbrowser==3.5.130zope.testbrowser==3.5.1
31bzr+http://bazaar.launchpad.net/~canonical-isd-qa/selenium-simple-test/trunk/@36231bzr+http://bazaar.launchpad.net/~canonical-isd-qa/selenium-simple-test/trunk/@376
32bzr+http://bazaar.launchpad.net/~canonical-isd-hackers/u1-test-utils/trunk@4832bzr+http://bazaar.launchpad.net/~canonical-isd-hackers/u1-test-utils/trunk@53
33bzr+ssh://bazaar.launchpad.net/~bloodearnest/+junk/test-email-server/33bzr+ssh://bazaar.launchpad.net/~bloodearnest/+junk/test-email-server/
3434
=== modified file 'scripts/acceptance-dev.sh'
--- scripts/acceptance-dev.sh 2013-04-09 12:35:33 +0000
+++ scripts/acceptance-dev.sh 2013-04-19 19:28:26 +0000
@@ -31,7 +31,7 @@
31sleep 10 # Time for the sso to start31sleep 10 # Time for the sso to start
3232
33# run tests33# run tests
34SST_BASE_URL="http://0.0.0.0:$PORT" fab acceptance:screenshot=true,report=xml,extended=true,flags="$SST_FLAGS"34SST_BASE_URL="http://0.0.0.0:$PORT" fab acceptance:screenshot=true,report=xml,flags="$SST_FLAGS"
3535
36# terminate sso server36# terminate sso server
37screen -X -S sso quit37screen -X -S sso quit
3838
=== modified file 'scripts/run-acceptance-tests'
--- scripts/run-acceptance-tests 2013-04-08 20:43:46 +0000
+++ scripts/run-acceptance-tests 2013-04-19 19:28:26 +0000
@@ -51,5 +51,5 @@
51 # dev is special: we need to start it up.51 # dev is special: we need to start it up.
52 ./scripts/acceptance-dev.sh52 ./scripts/acceptance-dev.sh
53else53else
54 SST_BASE_URL="$SST_BASE_URL" fab acceptance:screenshot=true,report=xml,extended=true,flags="$SST_FLAGS"54 SST_BASE_URL="$SST_BASE_URL" fab acceptance:screenshot=true,report=xml,flags="$SST_FLAGS"
55fi55fi