Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #2670 from mozilla/kapow

Kapow!
  • Loading branch information...
commit cec83da8629844bb91ecffd61ffdc9c9fa0c18ef 2 parents 3a4e816 + cb9bb4c
@6a68 6a68 authored
Showing with 3,532 additions and 2,913 deletions.
  1. +6 −3 .awsbox.json
  2. +2 −7 .gitignore
  3. +1 −0  .travis.yml
  4. 0  automation-tests/123done/mocks/__init__.py
  5. +0 −22 automation-tests/123done/mocks/mock_user.py
  6. +0 −4 automation-tests/123done/mozwebqa.cfg
  7. +0 −44 automation-tests/123done/page.py
  8. 0  automation-tests/123done/pages/__init__.py
  9. +0 −74 automation-tests/123done/pages/home.py
  10. 0  automation-tests/123done/restmail/__init__.py
  11. +0 −89 automation-tests/123done/restmail/restmail.py
  12. 0  automation-tests/123done/tests/__init__.py
  13. +0 −64 automation-tests/123done/tests/test_change_password.py
  14. +0 −22 automation-tests/123done/tests/test_logout.py
  15. +0 −33 automation-tests/123done/tests/test_new_user.py
  16. +0 −20 automation-tests/123done/tests/test_sign_in.py
  17. +86 −81 automation-tests/README.md
  18. +0 −4 automation-tests/browserid/.gitignore
  19. +0 −19 automation-tests/browserid/.travis.yml
  20. +0 −20 automation-tests/browserid/README.md
  21. +0 −1  automation-tests/browserid/__init__.py
  22. +0 −71 automation-tests/browserid/browser_id.py
  23. +0 −77 automation-tests/browserid/check_browser_id.py
  24. +0 −14 automation-tests/browserid/conftest.py
  25. 0  automation-tests/browserid/mocks/__init__.py
  26. +0 −21 automation-tests/browserid/mocks/user.py
  27. +0 −3  automation-tests/browserid/mozwebqa.cfg
  28. 0  automation-tests/browserid/pages/__init__.py
  29. +0 −76 automation-tests/browserid/pages/account_manager.py
  30. +0 −16 automation-tests/browserid/pages/base.py
  31. +0 −77 automation-tests/browserid/pages/complete_registration.py
  32. +0 −245 automation-tests/browserid/pages/sign_in.py
  33. +0 −2  automation-tests/browserid/requirements.txt
  34. +0 −2  automation-tests/browserid/setup.cfg
  35. 0  automation-tests/browserid/tests/__init__.py
  36. +0 −47 automation-tests/browserid/tests/base.py
  37. +0 −56 automation-tests/browserid/tests/check_add_email.py
  38. +0 −47 automation-tests/browserid/tests/check_change_password.py
  39. +0 −50 automation-tests/browserid/tests/check_reset_password.py
  40. +0 −104 automation-tests/browserid/tests/check_sign_in.py
  41. +0 −20 automation-tests/browserid/tests/conftest.py
  42. +0 −32 automation-tests/browserid/tests/restmail.py
  43. +65 −0 automation-tests/config/sauce-platforms.js
  44. +12 −0 automation-tests/config/tests-to-ignore.js
  45. +0 −37 automation-tests/credentials.yaml.example
  46. +10 −0 automation-tests/lib/asserts.js
  47. +0 −75 automation-tests/lib/convert_results.js
  48. +30 −0 automation-tests/lib/personatestuser.js
  49. +30 −0 automation-tests/lib/reporters/file-reporter.js
  50. +11 −0 automation-tests/lib/reporters/std-err-reporter.js
  51. +12 −0 automation-tests/lib/reporters/std-out-reporter.js
  52. +47 −0 automation-tests/lib/restmail.js
  53. +77 −0 automation-tests/lib/results-aggregator.js
  54. +31 −0 automation-tests/lib/runner.js
  55. +45 −0 automation-tests/lib/test-finder.js
  56. +197 −0 automation-tests/lib/test-setup.js
  57. +2 −0  automation-tests/lib/timeouts.js
  58. +41 −0 automation-tests/lib/toolbelt.js
  59. +37 −0 automation-tests/lib/urls.js
  60. +59 −0 automation-tests/lib/user.js
  61. +23 −0 automation-tests/lib/utils.js
  62. +68 −0 automation-tests/lib/vows_harness.js
  63. +259 −0 automation-tests/lib/wd-extensions.js
  64. +0 −4 automation-tests/myfavoritebeer/mozwebqa.cfg
  65. +0 −44 automation-tests/myfavoritebeer/page.py
  66. 0  automation-tests/myfavoritebeer/pages/__init__.py
  67. +0 −44 automation-tests/myfavoritebeer/pages/home.py
  68. 0  automation-tests/myfavoritebeer/tests/__init__.py
  69. +0 −21 automation-tests/myfavoritebeer/tests/test_logout.py
  70. +0 −20 automation-tests/myfavoritebeer/tests/test_sign_in.py
  71. +16 −0 automation-tests/package.json
  72. +84 −0 automation-tests/pages/css.js
  73. +30 −0 automation-tests/pages/dialog.js
  74. 0  automation-tests/persona_server/__init__.py
  75. 0  automation-tests/persona_server/pages/__init__.py
  76. +0 −115 automation-tests/persona_server/pages/account_manager.py
  77. +0 −35 automation-tests/persona_server/pages/base.py
  78. +0 −77 automation-tests/persona_server/pages/complete_registration.py
  79. +0 −41 automation-tests/persona_server/pages/home.py
  80. +0 −162 automation-tests/persona_server/pages/sign_in.py
  81. 0  automation-tests/persona_server/tests/__init__.py
  82. +0 −55 automation-tests/persona_server/tests/base.py
  83. +0 −11 automation-tests/persona_server/tests/conftest.py
  84. +0 −124 automation-tests/persona_server/tests/test_manage_account.py
  85. +0 −42 automation-tests/persona_server/tests/test_sign_in_unit.py
  86. +0 −11 automation-tests/requirements.txt
  87. +0 −154 automation-tests/run.py
  88. +0 −365 automation-tests/run_saucelabs
  89. +0 −8 automation-tests/sauce.yaml.example
  90. +78 −0 automation-tests/scripts/post-update.js
  91. +336 −0 automation-tests/scripts/run-all.js
  92. +104 −0 automation-tests/tests/add-primary-to-primary.js
  93. +95 −0 automation-tests/tests/add-primary-to-secondary.js
  94. +181 −0 automation-tests/tests/cancel-account.js
  95. +120 −0 automation-tests/tests/change-password-test.js
  96. +101 −0 automation-tests/tests/frontend-qunit-test.js
  97. +108 −0 automation-tests/tests/health-check-tests.js
  98. +130 −0 automation-tests/tests/new-user/new-user-primary-test.js
  99. +168 −0 automation-tests/tests/new-user/new-user-secondary-test.js
  100. +108 −0 automation-tests/tests/public-terminals.js
  101. +219 −0 automation-tests/tests/remove-email.js
  102. +101 −0 automation-tests/tests/reset-password-test.js
  103. +119 −0 automation-tests/tests/returning-user.js
  104. +89 −0 automation-tests/tests/sign-in-test.js
  105. +0 −1  package.json
  106. +48 −0 scripts/awsbox_local/post_create.js
  107. +30 −0 scripts/awsbox_local/scp.js
  108. 0  scripts/{awsbox → awsbox_remote}/post_create.sh
  109. +1 −0  scripts/{awsbox → awsbox_remote}/post_deploy.sh
  110. +6 −0 scripts/awsbox_remote/post_start.sh
  111. +5 −0 scripts/test
  112. +104 −0 scripts/test_selenium
View
9 .awsbox.json
@@ -12,9 +12,12 @@
"CONFIG_FILES": "$HOME/code/config/production.json,$HOME/code/config/aws.json,$HOME/config.json"
},
"hooks": {
- "postdeploy": "scripts/awsbox/post_deploy.sh",
- "poststart": "scripts/show_config.js",
- "postcreate": "scripts/awsbox/post_create.sh"
+ "postdeploy": "scripts/awsbox_remote/post_deploy.sh",
+ "poststart": "scripts/awsbox_remote/post_start.sh",
+ "postcreate": "scripts/awsbox_remote/post_create.sh"
+ },
+ "local_hooks": {
+ "postcreate": "node scripts/awsbox_local/post_create.js"
},
"packages": [
"mysql-server"
View
9 .gitignore
@@ -16,11 +16,6 @@
Thumbs.db
/locale
/resources/email_templates/email-test.html
-/automation-tests/bid_selenium
+/automation-tests/node_modules
/automation-tests/results
-/automation-tests/credentials.yaml
-/automation-tests/sauce.yaml
-automation-tests/persona_server/results/*
-/automation-tests/chromedriver.log
-/.coverage_data
-/cover_html
+/automation-tests/*.jar
View
1  .travis.yml
@@ -25,6 +25,7 @@ env:
- WHAT_TESTS=front MYSQL_USER=root
- WHAT_TESTS=back_mysql MYSQL_USER=root
- WHAT_TESTS=back
+ - WHAT_TESTS=selenium
mysql:
adapter: mysql2
View
0  automation-tests/123done/mocks/__init__.py
No changes.
View
22 automation-tests/123done/mocks/mock_user.py
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-class MockUser(dict):
-
- def __init__(self, **kwargs):
- # set your default values
- import time
-
- self['email'] = '123donetest_%s@restmail.net' % repr(time.time())
- self['password'] = 'Password12345'
-
- # update with any keyword arguments passed
- self.update(**kwargs)
-
- # allow getting items as if they were attributes
- def __getattr__(self, attr):
- return self[attr]
View
4 automation-tests/123done/mozwebqa.cfg
@@ -1,4 +0,0 @@
-[DEFAULT]
-api = webdriver
-baseurl = http://dev.123done.org
-tags = 123done
View
44 automation-tests/123done/page.py
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from unittestzero import Assert
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.common.exceptions import NoSuchElementException
-from selenium.common.exceptions import ElementNotVisibleException
-
-
-class Page(object):
-
- def __init__(self, testsetup):
- self.testsetup = testsetup
- self.base_url = testsetup.base_url
- self.selenium = testsetup.selenium
- self.timeout = testsetup.timeout
-
- @property
- def is_the_current_page(self):
- if self._page_title:
- WebDriverWait(self.selenium, self.timeout).until(lambda s: s.title)
-
- Assert.equal(self.selenium.title, self._page_title)
- return True
-
- def is_element_present(self, *locator):
- self.selenium.implicitly_wait(0)
- try:
- self.selenium.find_element(*locator)
- return True
- except NoSuchElementException:
- return False
- finally:
- # set back to where you once belonged
- self.selenium.implicitly_wait(self.testsetup.default_implicit_wait)
-
- def is_element_visible(self, *locator):
- try:
- return self.selenium.find_element(*locator).is_displayed()
- except NoSuchElementException, ElementNotVisibleException:
- return False
View
0  automation-tests/123done/pages/__init__.py
No changes.
View
74 automation-tests/123done/pages/home.py
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support.ui import WebDriverWait
-
-from page import Page
-
-
-class HomePage(Page):
-
- _page_title = '123done - your tasks, simplified'
-
- _sign_in_locator = (By.CSS_SELECTOR, '#loggedout > button')
- _logout_locator = (By.CSS_SELECTOR, '#loggedin > a')
- _logged_in_user_email_locator = (By.CSS_SELECTOR, '#loggedin > span')
- _loading_spinner_locator = (By.CSS_SELECTOR, "li.loading img")
-
- def go_to_home_page(self):
- self.selenium.get(self.base_url + '/')
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: not self.is_element_visible(*self._loading_spinner_locator),
- 'Timeout waiting for sign-in button to appear.')
- self.is_the_current_page
-
- def sign_in(self, user='default'):
- credentials = self.testsetup.credentials[user]
- browserid = self.click_sign_in()
- browserid.sign_in(credentials['email'], credentials['password'])
- self.wait_for_user_login()
-
- def logout(self):
- self.click_logout()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: self.is_element_visible(*self._sign_in_locator) and not \
- self.is_element_visible(*self._loading_spinner_locator),
- 'Timeout waiting for user to log out.')
-
- def click_sign_in(self, expect='new'):
- """Click the 'sign in' button.
-
- Keyword arguments:
- expect -- the expected resulting page
- 'new' for user that is not currently signed in (default)
- 'returning' for users already signed in or recently verified
-
- """
- self.selenium.find_element(*self._sign_in_locator).click()
- from browserid.pages.sign_in import SignIn
- return SignIn(self.selenium, self.timeout, expect=expect)
-
- def click_logout(self):
- self.selenium.find_element(*self._logout_locator).click()
-
- @property
- def is_logged_in(self):
- return self.is_element_visible(*self._logout_locator)
-
- @property
- def logged_in_user_email(self):
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: self.is_element_visible(*self._logged_in_user_email_locator)and not \
- self.is_element_visible(*self._loading_spinner_locator),
- "Timeout waiting for user's email to appear.")
- return self.selenium.find_element(*self._logged_in_user_email_locator).text
-
- def wait_for_user_login(self):
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: self.is_element_visible(*self._logout_locator) and not \
- self.is_element_visible(*self._loading_spinner_locator),
- 'Timeout waiting for user to login.')
View
0  automation-tests/123done/restmail/__init__.py
No changes.
View
89 automation-tests/123done/restmail/restmail.py
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import requests
-import json
-import re
-from time import sleep
-
-
-class RestmailInbox(object):
- """
- This wrapper loads restmail for the given email address.
- It will loop and wait for an email to arrive if there is not one present.
- find_by_* methods can be used to find an email and return it as Email() class.
- """
-
- _restmail_mail_server = "https://restmail.net/mail/"
-
- def __init__(self, email):
- self.email = email
- self.username = email.split('@')[0]
- self.json = self._wait_and_return_json_response(self.username)
-
- def _wait_and_return_json_response(self, username, timeout=60):
- # Loop for 60 attempts until the restmail json returned is not empty
-
- timer = 0
- response_json = []
-
- while timer < timeout:
- sleep(1)
- timer += 1
-
- response = requests.get(self._restmail_mail_server + self.username, verify=False)
- response_json = json.loads(response.content)
- if response_json != []:
- return response_json
-
- raise Exception("Failed to find an email before timeout")
-
- def delete_all_mail(self):
- # Delete all of the mail in the inbox
-
- requests.delete(self._restmail_mail_server + self.username, verify=False)
-
- def find_by_index(self, index):
- return Email(self.json[index])
-
- def find_by_sender(self, sender):
- # Loop through the address and name objects for each sender and match at least one
-
- for json_object in self.json:
- for from_source in json_object['from']:
- if from_source['address'] == sender or from_source['name'] == sender:
- return Email(json_object)
- else:
- raise Exception("Sender not found")
-
-
-class Email():
- """
- This returns a class representation of an email from restmail inbox
- """
-
- def __init__(self, json):
- self.json = json
-
- @property
- def body(self):
- return(self.json['text'])
-
- @property
- def verify_user_link(self):
- # This returns the link for verifying the email address of a new account
- regex = 'https:\/\/.*verify_email_address\?token=.{48}'
-
- verify_link = re.search(regex, self.body).group(0)
- return verify_link
-
- @property
- def add_email_address_link(self):
- # This returns the link for adding the email address of a new account
- regex = 'https:\/\/.*confirm\?token=.{48}'
-
- add_email_link = re.search(regex, self.body).group(0)
- return add_email_link
View
0  automation-tests/123done/tests/__init__.py
No changes.
View
64 automation-tests/123done/tests/test_change_password.py
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from pages.home import HomePage
-from restmail.restmail import RestmailInbox
-from mocks.mock_user import MockUser
-from unittestzero import Assert
-
-import pytest
-
-
-class TestChangePassword:
-
- def _persona_server_url(self, mozwebqa):
- server = None
- if 'dev' in mozwebqa.base_url:
- server = 'https://login.dev.anosrep.org'
- elif 'beta' in mozwebqa.base_url:
- server = 'https://login.anosrep.org'
- else:
- server = 'https://login.persona.org'
- return server
-
- def test_can_change_user_password(self, mozwebqa):
- user = MockUser()
- home_pg = HomePage(mozwebqa)
-
- home_pg.go_to_home_page()
- bid_login = home_pg.click_sign_in()
- bid_login.sign_in_new_user(user['email'], user['password'])
-
- # Open restmail inbox, find the email
- inbox = RestmailInbox(user['email'])
- email = inbox.find_by_index(0)
-
- # Load the BrowserID link from the email in the browser
- from browserid.pages.complete_registration import CompleteRegistration
- CompleteRegistration(mozwebqa.selenium, mozwebqa.timeout, email.verify_user_link)
-
- mozwebqa.selenium.get(self._persona_server_url(mozwebqa))
- from browserid.pages.account_manager import AccountManager
- account_manager = AccountManager(mozwebqa.selenium, mozwebqa.timeout)
-
- Assert.contains(user['email'], account_manager.emails)
-
- account_manager.click_edit_password()
- account_manager.old_password = user['password']
- new_password = "newpass12345"
- account_manager.new_password = new_password
- account_manager.click_password_done()
-
- account_manager.click_sign_out()
- mozwebqa.selenium.execute_script('localStorage.clear()')
-
- home_pg.go_to_home_page()
-
- bid_login = home_pg.click_sign_in()
- bid_login.sign_in(user['email'], new_password)
-
- home_pg.wait_for_user_login()
- Assert.true(home_pg.is_logged_in)
View
22 automation-tests/123done/tests/test_logout.py
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from pages.home import HomePage
-from unittestzero import Assert
-
-import pytest
-
-
-class TestLogout:
-
- @pytest.mark.nondestructive
- def test_that_user_can_logout(self, mozwebqa):
- home_pg = HomePage(mozwebqa)
- home_pg.go_to_home_page()
- home_pg.sign_in()
-
- home_pg.logout()
- Assert.false(home_pg.is_logged_in)
View
33 automation-tests/123done/tests/test_new_user.py
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from pages.home import HomePage
-from restmail.restmail import RestmailInbox
-from mocks.mock_user import MockUser
-from unittestzero import Assert
-
-import pytest
-
-
-class TestNewAccount:
-
- def test_can_create_new_user_account(self, mozwebqa):
- user = MockUser()
- home_pg = HomePage(mozwebqa)
-
- home_pg.go_to_home_page()
- bid_login = home_pg.click_sign_in()
- bid_login.sign_in_new_user(user['email'], user['password'])
-
- # Open restmail inbox, find the email
- inbox = RestmailInbox(user['email'])
- email = inbox.find_by_index(0)
-
- # Load the BrowserID link from the email in the browser
- from browserid.pages.complete_registration import CompleteRegistration
- complete_registration = CompleteRegistration(mozwebqa.selenium, mozwebqa.timeout, email.verify_user_link)
-
- Assert.equal(home_pg.logged_in_user_email, user['email'])
View
20 automation-tests/123done/tests/test_sign_in.py
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from pages.home import HomePage
-from unittestzero import Assert
-
-import pytest
-
-
-class TestSignIn:
-
- @pytest.mark.nondestructive
- def test_that_user_can_sign_in(self, mozwebqa):
- home_pg = HomePage(mozwebqa)
- home_pg.go_to_home_page()
- home_pg.sign_in()
- Assert.true(home_pg.is_logged_in)
View
167 automation-tests/README.md
@@ -1,125 +1,130 @@
-getting started
-===============
+o hai!
-# I'm super impatient. Let's get going in 10 sec or less. (But I don't run Windows)
+## Getting started
-TL;DR: just execute ```./run.py``` from inside the automation-tests directory.
+#### Install deps:
-If you're missing pip or virtualenv, it'll tell you what to do.
+ ```npm install```
-If you're missing test dependencies, it'll install them for you.
+#### You need the selenium-server-standalone jar to run tests locally:
-If all that is OK, it'll connect to dev.123done.org and try to create a fake user, login, and logout.
+ ```curl http://selenium.googlecode.com/files/selenium-server-standalone-2.25.0.jar > selenium-server-standalone-2.25.0.jar```
-If you want to run that single test against your ephemeral instance called 'foo', just do ```run.py --target=foo```.
+#### Fire up selenium:
-If you want to run all the tests, create a dummy user, put its info in credentials.yaml, then do ```run.py --all``` to run all the tests, including 123done and myfavoritebeer tests.
+ ```java -jar selenium-server-standalone-2.25.0.jar```
-If you want to run all the tests against all the browsers, using any browsers the script can find locally, then do ```run.py --everywhere```.
+#### run some tests locally
-# I've got time. Tell me more!
+There isn't a test runner yet, but you can do this for each test under `tests`:
-OK, sure...
+ PERSONA_ENV=stage node tests/change-password-test.js
-## how to run selenium tests inside the automation-tests directory against ephemeral, stage, or prod environments
+`PERSONA_ENV` sets the target you want to test. **stage** is the most stable environment at present, so run your tests against it.
-Node bindings aren't as mature as python for Selenium 2 API (webdriver), so we're using python bindings instead. This requires some python-centric setup, but it shouldn't take more than 15 minutes or so to get up and running, unless you're running Windows. See the bottom of this page for Windows setup instructions.
+#### run some tests against sauce
-These tests currently only hit myfavoritebeers and 123done domains. For example, to test an ephemeral install named foo.personatest.org, you can pass 'foo.123done.org' into the py.test baseurl parameter (this is covered again in the examples section).
+Set some more environment variables:
-### check system-wide python requirements
+ * specify sauce username as `PERSONA_SAUCE_USER` (in persona-secrets bundle for mozilla identity devs)
+ * specify sauce api key as `PERSONA_SAUCE_APIKEY` (in persona-secrets bundle for mozilla identity devs)
+ * specify your sauce browser and OS combo as `PERSONA_BROWSER`
+ * current list: `linux_firefox_13`, `linux_opera_12`, `osx_firefox_14`, `vista_chrome`, `vista_firefox_13`, `vista_ie_9`, `xp_ie_8`
+ * the list is in config/sauce-platforms.js
+ * You can temporarily force a local browser run with `PERSONA_NO_SAUCE`. If you do this, make sure `PERSONA_BROWSER` is set to something that can be run locally.
-You should have python 2.7 on your system (check python --version).
+Then run the tests just like you would locally:
-We have to install a bunch of python libraries. pip fetches packages; virtualenv sandboxes them. If pip and virtualenv aren't on your system already, you'll need to do this once (once per computer, not once per repo):
+ PERSONA_ENV=stage node tests/change-password-test.js
- # only do this if pip and virtualenv aren't on your computer already
- # might need to use sudo
- easy_install pip
- pip install virtualenv
+#### run all the tests
+It is possible to run all of the available tests either locally or against
+Sauce.
-### build a sandboxed python test environment
+To run all the tests locally against one browser:
-From the automated-tests directory, create a sandboxed python environment to install python dependencies (only need to do this once per clone):
+ scripts/run-all.js --local --platform=osx_firefox_15 --env=stage
- # only do this once per clone
- virtualenv bid_selenium
+To run all the tests on Sauce in parallel against one browser:
-Be sure you do not accidentally add the virtualenv directory (here, bid_selenium) to git.
+ scripts/run-all.js --parallel=15 --platform=osx_firefox_15 --env=stage
-You can activate the sandbox, meaning link installed programs, via:
+To run all the tests on Sauce against all supported browsers:
- . bid_selenium/bin/activate
+ scripts/run-all.js --parallel=15 --platform=all --env=stage
-And when you want to stop using the sandbox, you can exit via ```deactivate```. Deactivating the virtualenv doesn't destroy it.
+For help with other run-all.js options:
+ scripts/run-all.js --help
-In order to install python dependencies into the sandbox, activate the virtualenv, then install the python requirements in requirements.txt:
+#### disabling tests
+Tests can be disabled by adding the name of the test file to
+config/tests-to-ignore.js. This is useful while developing new test suites that
+are not yet ready to be consumed by all browsers.
- pip install -Ur requirements.txt
+ exports.tests_to_ignore = [
+ "public-terminals.js"
+ ];
-Sweet. Your environment is now ready.
+This ignores the tests in public-terminals.js
-### create a test user in credentials.yaml
-Some of the automation tests verify that existing accounts work, so create a test account, and put the info into credentials.yaml.
+## Test Setup
-### run the tests
+* To get common test fixtures (personatestusers, restmail emails, eyedee.me emails, or browser sessions), use TestSetup.setup:
-When you want to run the tests, make sure the virtualenv is active:
+```testSetup.setup({ browsers: 2, restmails: 1, eyedeemails: 1, personatestusers: 2 }, cb)```
- . bid_selenium/bin/activate
+* You can also use a less verbose syntax:
-Then, run the tests by calling py.test on the command line with some options. [Here](https://github.com/davehunt/pytest-mozwebqa) is the most relevant documentation: command-line options added to py.test by the mozwebqa plugin, which is awesome. [Here](http://pytest.org/latest/usage.html) is the documentation for the upstream pytest project.
+```testSetup.setup({b:2, r:1, e:1, p:2}, cb)```
-#### examples
+* Your callback should take an error function and an object that holds all the test fixtures you asked for:
-Use local Firefox to run the 123done tests (in the 123done directory) against dev.123done.org:
+```
+ function(err, fixtures) {
+ browser = fixtures.browsers[0];
+ secondBrowser = fixtures.browsers[1];
+ theEmail = fixtures.restmails[0];
+ eyedeemail = fixtures.eyedeemails[0];
+ firstUser = fixtures.personatestusers[0];
+ secondUser = fixtures.personatestusers[1];
+ }
+```
- python -m py.test --destructive --credentials=credentials.yaml \
- --baseurl=http://dev.123done.org \
- --driver=firefox \
- -q 123done
-Use local Chrome (assuming you've downloaded [Chromedriver](http://code.google.com/p/selenium/wiki/ChromeDriver) to /usr/local/bin/chromedriver) to run just one of the the myfavoritebeer tests against myfavoritebeer.org:
+## Reference: Extensions to wd's API
- python -m py.test --destructive --credentials=credentials.yaml \
- --baseurl=http://www.myfavoritebeer.org \
- --driver=chrome --chromepath=/usr/local/bin/chromedriver \
- -q myfavoritebeer/tests/test_logout.py
+This code lives in lib/wd-extensions.js
-Use Sauce Labs (assuming you've got credentials in saucelabs.yaml) to run IE 8 against an ephemeral instance called 'foo':
+### wait-API: wait, then do X. super useful.
- python -m py.test --destructive --credentials=credentials.yaml \
- --baseurl=http://foo.123done.org \
- --platform=XP --browsername="internet explorer" --browserver=8 \
- --saucelabs=saucelabs.yaml \
- -q 123done
+* `wfind(selector, cb(err, el))`: wait until the specified element is displayed, then pass it to cb. Alias for custom extension `waitForDisplayed`.
+* `wclick(selector, cb(err))`: wait until the specified element is displayed, then click it
+* `wwin(windowName, cb(err))`: wait until the specified window is displayed, then switch to it. Aslias for custom extension `waitForWindow`.
+* `wclickIfExists(selector, cb(err))`: wait for a maximum of one second to see if the specified element is displayed, then click it. If element does not exist, continue without an error.
+ * calling `wwin()` with no arguments will switch to the main window--not true of `waitForWindow`.
+* `wtype(selector, text, cb(err))`: wait until the specified element is displayed, then type into it
+ * warning: wd.type() takes an element, not a selector!
+* `wtext(selector, cb(err, text))`: wait until the specified element is displayed, then pass its text content to cb
+* `wgetAttribute(selector, attrName, cb(err, value))`: wait until the specified element is displayed, then get an attribute value
+* `wclear(selector, cb(err))`: wait until the specified element is displayed, then clear it
-note, your saucelabs.yaml file should be of the form:
+### other extensions
- # example sauce_labs.yaml config file
- username: <username>
- password: <password>
- api-key: <api-key>
+* `find(selector, cb(err, el))`: find specified element and pass it to cb. Alias for `elementByCss`.
+* `click(selector, cb(err))`: click the specified element. Alias for `clickElement`.
+* `waitForDisplayed(opts, cb(err, el))`: wait for element to become visible, then switch to it.
+ * `opts` can be just the selector, or an object with name, poll, and timeout props.
+* `waitForWindow(opts, cb(err))`: wait for window to become visible, then switch to it.
+ * `opts` can be just the name, or an object with name, poll, and timeout props.
+* `waitForElementText(opts, cb(err, el))`: wait for specified el to have a non-empty text value
+ * `opts` can be just the selector, or an object with name, poll, and timeout props.
+* `closeCurrentBrowserWindow(cb(err))`: close the currently open browser window and switch to one of the remaining
+* `newSession(cb(err))`: allocate a new browser session and sets implicit wait timeout
+* `delay(timeout, cb(err))`: delay for the specified amount of time before continuing
-#### Check out your results
-
-The tests create a /results directory, which contains an index.html file with test results, screenshots, and videos if you used sauce labs. In case of a failure, you'll also see the backtrace. Totally sweet.
-
-## writing automation tests
-
-TODO: some idioms from the existing test code to help people quickly express "find this" and "click this" idiomatically.
-
-Refer to [mozilla's pytest_mozwebqa](https://github.com/davehunt/pytest-mozwebqa#writing-tests-for-pytest_mozwebqa) documentation on writing tests for the time being.
-
-A note about upstreaming bidpom changes: this codebase contains [mozilla's bidpom](https://github.com/mozilla/bidpom) as [git-subtree](https://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt). This allows us to pull in changes from upstream, while easily tracking the bidpom code to branches. It's unlikely that we'll need to push or pull to upstream frequently, but for details on doing so, see also apenwarr's [blog post](http://apenwarr.ca/log/?m=200904#30).
-
-## Setting up Python in a Windows Environment
-
-Note: this post talks about python 2.5, but you need to install 2.6 or 2.7, and not 3.x.
-
-http://blog.sadphaeton.com/2009/01/20/python-development-windows-part-1installing-python.html
-http://blog.sadphaeton.com/2009/01/20/python-development-windows-part-2-installing-easyinstallcould-be-easier.html
-
-Alternately, think about running under cygwin instead.
+## Refs
+* [admc/wd](https://github.com/admc/wd) is our webdriver library
+* WebDriver's [JSON wire protocol](http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/timeouts/implicit_wait) is what lives under the language bindings
+* we keep a list of tests to write in an [etherpad](https://id.etherpad.mozilla.org/test-automation-spec).
View
4 automation-tests/browserid/.gitignore
@@ -1,4 +0,0 @@
-*.pyc
-*.komodoproject
-build
-results
View
19 automation-tests/browserid/.travis.yml
@@ -1,19 +0,0 @@
-before_script:
- - sh -e /etc/init.d/xvfb start
-
-language: python
-python:
- - 2.6
- - 2.7
-
-script: py.test --baseurl=http://dev.123done.org --driver=firefox -m travis tests
-
-env:
- - DISPLAY=':99.0'
-
-notifications:
- email:
- - dave.hunt@gmail.com
- irc:
- - "irc.mozilla.org#automation"
- - "irc.mozilla.org#identity"
View
20 automation-tests/browserid/README.md
@@ -1,20 +0,0 @@
-**B**rowser**ID** **P**age **O**bject **M**odel
-===============================================
-Selenium compatible page object model for Mozilla's BrowserID.
-
-Documentation
--------------
-See the project's [wiki](https://github.com/mozilla/bidpom/wiki).
-
-Running BIDPOM's Tests
-----------------------
-* if running against a remote selenium server, add --capabilities={"avoid-proxy":true} to the command line
-* if experiencing TimeoutErrors from WebDriverWait, add the --webqatimeout=90 to the command line
-
-License
--------
-This software is licensed under the [MPL](http://www.mozilla.org/MPL/2.0/) 2.0:
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
View
1  automation-tests/browserid/__init__.py
@@ -1 +0,0 @@
-from browser_id import BrowserID
View
71 automation-tests/browserid/browser_id.py
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import urllib2
-import json
-
-import selenium
-
-
-class BrowserID(object):
-
- VERIFY_URL_REGEX = 'https?:\/\/(\S+)\/verify_email_address\?token=(.{48})'
- CONFIRM_URL_REGEX = 'https?:\/\/(\S+)\/confirm\?token=(.{48})'
- RESET_URL_REGEX = 'https?:\/\/(\S+)\/reset_password\?token=(.{48})'
- INCLUDE_URL_REGEX = '(https?:\/\/(\S+))\/include\.js'
-
- def __init__(self, selenium, timeout=60):
- self.selenium = selenium
- self.timeout = timeout
-
- def sign_in(self, email, password):
- """Signs in using the specified email address and password."""
- from pages.sign_in import SignIn
- sign_in = SignIn(self.selenium, timeout=self.timeout, expect='new')
- sign_in.sign_in(email, password)
-
- def persona_test_user(self, verified=True, env='prod'):
- '''
- Create a test user.
-
- ::Args::
- - verified - boolean True/False should the user be verified
- - env - string dev/stage/prod instance of persona.org used by
- the system under test(default prod)
-
- ::Returns::
- A dictionary that combines the values returned by the personatestuser API
- and the values returned by browserid.mocks.MockUser.
-
- {
- 'email': 'lopez401@personatestuser.org'
- 'primary_email': 'lopez401@personatestuser.org',
- 'pass': 'SOaUo9qJqYyBl1sN',
- 'password': 'SOaUo9qJqYyBl1sN',
- 'expires': '1346445745',
- 'verifier': 'https://verifier.dev.anosrep.org',
- 'browserid': 'https://login.dev.anosrep.org',
- 'token': 'U6bFrRZJrZggwkJ0gkpvC9tuNNaIXpvEZM11gzLnw9l4o4UK', # for verified=False only
- 'env': 'dev',
- }
-
- '''
- command = ''
- if verified:
- command = 'email'
- else:
- command = 'unverified_email'
-
- response = urllib2.urlopen(
- 'http://personatestuser.org/%s/%s' %
- (command, env), timeout=self.timeout)
-
- user = json.loads(response.read())
- user['password'] = user['pass']
- user['primary_email'] = user['email']
- user.pop('events')
- print user
- return user
View
77 automation-tests/browserid/check_browser_id.py
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import pytest
-
-from browser_id import BrowserID
-
-@pytest.mark.nondestructive
-class TestBrowserID(object):
-
- @pytest.mark.travis
- @pytest.mark.skip_selenium
- def test_persona_test_user_verified_prod(self, mozwebqa):
-
- user = BrowserID(mozwebqa.selenium, mozwebqa.timeout).persona_test_user()
- assert user['email']
- assert user['password']
- assert user['browserid'] == 'https://login.persona.org'
- assert user['verifier'] == 'https://login.persona.org/verify'
- assert not user.has_key('token')
-
- @pytest.mark.travis
- @pytest.mark.skip_selenium
- def test_persona_test_user_verified_stage(self, mozwebqa):
-
- user = BrowserID(mozwebqa.selenium, mozwebqa.timeout).persona_test_user(env='stage')
- assert user['email']
- assert user['password']
- assert user['browserid'] == 'https://login.anosrep.org'
- assert not user.has_key('token')
-
- @pytest.mark.travis
- @pytest.mark.skip_selenium
- def test_persona_test_user_verified_dev(self, mozwebqa):
-
- user = BrowserID(mozwebqa.selenium, mozwebqa.timeout).persona_test_user(env='dev')
- assert user['email']
- assert user['password']
- assert user['browserid'] == 'https://login.dev.anosrep.org'
- assert not user.has_key('token')
-
- @pytest.mark.travis
- @pytest.mark.skip_selenium
- def test_persona_test_user_unverified_prod(self, mozwebqa):
-
- user = BrowserID(mozwebqa.selenium, mozwebqa.timeout).persona_test_user(verified=False)
- assert user['email']
- assert user['password']
- assert user['browserid'] == 'https://login.persona.org'
- assert user['verifier'] == 'https://login.persona.org/verify'
- assert user.has_key('token')
-
- @pytest.mark.travis
- @pytest.mark.skip_selenium
- def test_persona_test_user_unverified_stage(self, mozwebqa):
-
- user = BrowserID(mozwebqa.selenium, mozwebqa.timeout).persona_test_user(verified=False, env='stage')
- assert user['email']
- assert user['password']
- assert user['browserid'] == 'https://login.anosrep.org'
- assert user['verifier'] == 'https://login.anosrep.org/verify'
- assert user.has_key('token')
-
- @pytest.mark.travis
- @pytest.mark.skip_selenium
- def test_persona_test_user_unverified_dev(self, mozwebqa):
-
- user = BrowserID(mozwebqa.selenium, mozwebqa.timeout).persona_test_user(verified=False, env='dev')
- assert user['email']
- assert user['password']
- assert user['browserid'] == 'https://login.dev.anosrep.org'
- assert user['verifier'] == 'https://verifier.dev.anosrep.org'
- assert user.has_key('token')
-
View
14 automation-tests/browserid/conftest.py
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import py
-
-
-def pytest_runtest_setup(item):
- pytest_mozwebqa = py.test.config.pluginmanager.getplugin('mozwebqa')
-
-def pytest_funcarg__mozwebqa(request):
- return request.getfuncargvalue('mozwebqa')
View
0  automation-tests/browserid/mocks/__init__.py
No changes.
View
21 automation-tests/browserid/mocks/user.py
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import uuid
-
-
-class MockUser(dict):
-
- def __init__(self, **kwargs):
- self['id'] = 'bidpom_%s' % uuid.uuid1()
- self['primary_email'] = '%s@restmail.net' % self.id
- self['password'] = 'password'
- self['additional_emails'] = []
-
- self.update(**kwargs)
-
- def __getattr__(self, attr):
- return self[attr]
View
3  automation-tests/browserid/mozwebqa.cfg
@@ -1,3 +0,0 @@
-[DEFAULT]
-baseurl = http://123done.org
-tags = bidpom
View
0  automation-tests/browserid/pages/__init__.py
No changes.
View
76 automation-tests/browserid/pages/account_manager.py
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from base import Base
-
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support.ui import WebDriverWait
-
-
-class AccountManager(Base):
-
- _emails_locator = (By.CSS_SELECTOR, '#emailList .email')
- _edit_password_button_locator = (By.CSS_SELECTOR, '#edit_password button.edit')
- _old_password_field_locator = (By.ID, 'old_password')
- _new_password_field_locator = (By.ID, 'new_password')
- _change_password_done_locator = (By.ID, 'changePassword')
- _sign_in_locator = (By.CSS_SELECTOR, 'a.signIn')
- _sign_out_locator = (By.CSS_SELECTOR, 'a.signOut')
-
- def __init__(self, selenium, timeout):
- Base.__init__(self, selenium, timeout)
-
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._emails_locator).is_displayed())
-
- @property
- def signed_in(self):
- return not self.selenium.find_element(By.CSS_SELECTOR, 'body.not_authenticated')
-
- @property
- def emails(self):
- return [element.text for element in self.selenium.find_elements(*self._emails_locator)]
-
- def click_edit_password(self):
- """Click edit password to show the new/old password fields"""
- self.selenium.find_element(*self._edit_password_button_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._old_password_field_locator).is_displayed())
-
- @property
- def old_password(self):
- """Get the value of the old password field."""
- return self.selenium.find_element(*self._old_password_field_locator).get_attribute('value')
-
- @old_password.setter
- def old_password(self, value):
- """Set the value of the old password field."""
- password = self.selenium.find_element(*self._old_password_field_locator)
- password.clear()
- password.send_keys(value)
-
- @property
- def new_password(self):
- """Get the value of the new password field."""
- return self.selenium.find_element(*self._new_password_field_locator).get_attribute('value')
-
- @new_password.setter
- def new_password(self, value):
- """Set the value of the new password field."""
- password = self.selenium.find_element(*self._new_password_field_locator)
- password.clear()
- password.send_keys(value)
-
- def click_password_done(self):
- """Click password done to save the new password."""
- self.selenium.find_element(*self._change_password_done_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._edit_password_button_locator).is_displayed())
-
- def click_sign_out(self):
- self.selenium.find_element(*self._sign_out_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: not self.signed_in)
View
16 automation-tests/browserid/pages/base.py
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-class Base(object):
-
- def __init__(self, selenium, timeout=60):
- self.selenium = selenium
- self.timeout = timeout
- self._main_window_handle = self.selenium.current_window_handle
-
- def switch_to_main_window(self):
- self.selenium.switch_to_window(self._main_window_handle)
View
77 automation-tests/browserid/pages/complete_registration.py
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from base import Base
-
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support.ui import WebDriverWait
-
-
-class CompleteRegistration(Base):
-
- _page_title = 'Mozilla Persona: Complete Registration'
- _email_locator = (By.ID, 'email')
- _password_locator = (By.ID, 'password')
- _finish_locator = (By.CSS_SELECTOR, 'div.submit > button')
- _thank_you_locator = (By.ID, 'congrats')
-
- def __init__(self, selenium, timeout, url, expect='redirect'):
- """
- class init method
- :Args:
- - url - the confirmation url from the email
- - expect - redirect/success/reset/verify (default redirect)
- """
- Base.__init__(self, selenium, timeout)
- print "the url" + url
- self.selenium.get(url)
-
- if expect == 'redirect':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.title != self._page_title,
- "Complete Registration page did not redirect")
- elif expect == 'success':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: 'Thank you' in s.find_element(*self._thank_you_locator).text,
- "Complete Registration did not succeed")
- elif expect == 'reset':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: 'verified' in s.find_element(*self._thank_you_locator).text,
- "Complete Registration did not succeed")
- elif expect == 'verify':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._password_locator).is_displayed(),
- "password field did not become visible")
- else:
- raise Exception('Unknown expect value: %s' % expect)
-
- @property
- def email(self):
- """Get the value of the email field."""
- return self.selenium.find_element(*self._email_locator).text
-
- @property
- def password(self):
- """Get the value of the password field."""
- return self.selenium.find_element(*self._password_locator).text
-
- @password.setter
- def password(self, value):
- """Set the value of the password field."""
- password = self.selenium.find_element(*self._password_locator)
- password.clear()
- password.send_keys(value)
-
- def click_finish(self):
- """Clicks the 'finish' button."""
- self.selenium.find_element(*self._finish_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._thank_you_locator).is_displayed())
-
- @property
- def thank_you(self):
- """Returns the 'thank you' message."""
- return self.selenium.find_element(*self._thank_you_locator).text
View
245 automation-tests/browserid/pages/sign_in.py
@@ -1,245 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from base import Base
-
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support.ui import WebDriverWait
-
-
-class SignIn(Base):
-
- _this_is_not_me_locator = (By.ID, 'thisIsNotMe')
- _signed_in_email_locator = (By.CSS_SELECTOR, 'label[for=email_0]')
- _emails_locator = (By.CSS_SELECTOR, 'label[for^=email_]')
- _email_locator = (By.ID, 'email')
- _password_locator = (By.ID, 'password')
- _verify_password_locator = (By.ID, 'vpassword')
- _next_locator = (By.CSS_SELECTOR, 'button.start')
- _sign_in_locator = (By.CSS_SELECTOR, 'button.returning')
- _sign_in_returning_user_locator = (By.ID, 'signInButton')
- _verify_email_locator = (By.ID, 'verify_user')
- _forgot_password_locator = (By.ID, 'forgotPassword')
- _reset_password_locator = (By.ID, 'password_reset')
- _check_email_at_locator = (By.CSS_SELECTOR, '#wait .contents h2 + p strong')
- _add_another_email_locator = (By.ID, 'useNewEmail')
- _new_email_locator = (By.ID, 'newEmail')
- _add_new_email_locator = (By.ID, 'addNewEmail')
- _your_computer_content_locator = (By.ID, 'your_computer_content')
- _this_is_my_computer_locator = (By.ID, 'this_is_my_computer')
- _this_is_not_my_computer_locator = (By.ID, 'this_is_not_my_computer')
-
- def __init__(self, selenium, timeout, expect='new'):
- Base.__init__(self, selenium, timeout)
-
- # wait for second window to open
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.window_handles > 1)
- selenium.switch_to_window('__persona_dialog')
-
- if expect == 'new':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._email_locator).is_displayed())
- elif expect == 'returning':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._sign_in_returning_user_locator).is_displayed())
- import time
- time.sleep(2) # TODO: Remove this sleep
- else:
- raise Exception('Unknown expect value: %s' % expect)
-
- def close_window(self):
- try: # race condition with window closing by itself
- self.selenium.close()
- except:
- # if it fails, the framework will capture a screenshot
- pass
-
- @property
- def signed_in_email(self):
- """Get the value of the email that is currently signed in."""
- return self.selenium.find_element(*self._signed_in_email_locator).get_attribute('value')
-
- def click_this_is_not_me(self):
- """Clicks the 'This is not me' button."""
- self.selenium.find_element(*self._this_is_not_me_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(*self._email_locator).is_displayed())
-
- @property
- def emails(self):
- """Get the emails for the returning user."""
- return [element.text for element in
- self.selenium.find_elements(*self._emails_locator)]
-
- @property
- def email(self):
- """Get the value of the email field."""
- return self.selenium.find_element(*self._email_locator).get_attribute('value')
-
- @email.setter
- def email(self, value):
- """Set the value of the email field."""
- email = self.selenium.find_element(*self._email_locator)
- email.clear()
- email.send_keys(value)
-
- @property
- def new_email(self):
- """Get the value of the new email field."""
- return self.selenium.find_element(*self._new_email_locator).get_attribute('value')
-
- @new_email.setter
- def new_email(self, value):
- """Set the value of the new email field."""
- email = self.selenium.find_element(*self._new_email_locator)
- email.clear()
- email.send_keys(value)
-
- @property
- def selected_email(self):
- """Return the value of the selected email of returning user's multiple emails"""
- for email in self.selenium.find_elements(*self._emails_locator):
- if email.find_element(By.TAG_NAME, 'input').is_selected():
- return email.text
-
- def select_email(self, value):
- """Select email from the returning user's multiple emails."""
- for email in self.selenium.find_elements(*self._emails_locator):
- if email.text == value:
- email.click()
- break
- else:
- raise Exception('Email not found: %s' % value)
-
- @property
- def password(self):
- """Get the value of the password field."""
- return self.selenium.find_element(*self._password_locator).get_attribute('value')
-
- @password.setter
- def password(self, value):
- """Set the value of the password field."""
- password = self.selenium.find_element(*self._password_locator)
- password.clear()
- password.send_keys(value)
-
- @property
- def verify_password(self):
- """Get the value of the verify password field."""
- return self.selenium.find_element(*self._verify_password_locator).get_attribute('value')
-
- @verify_password.setter
- def verify_password(self, value):
- """Set the value of the verify password field."""
- password = self.selenium.find_element(*self._verify_password_locator)
- password.clear()
- password.send_keys(value)
-
- @property
- def check_email_at_address(self):
- """Get the value of the email address for confirmation."""
- return self.selenium.find_element(*self._check_email_at_locator).text
-
- def click_next(self, expect='password'):
- """Clicks the 'next' button."""
- self.selenium.find_element(*self._next_locator).click()
- if expect == 'password':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._password_locator).is_displayed())
- elif expect == 'verify':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._verify_email_locator).is_displayed())
- else:
- raise Exception('Unknown expect value: %s' % expect)
-
- def click_sign_in(self):
- """Clicks the 'sign in' button."""
- self.selenium.find_element(*self._sign_in_locator).click()
- self.switch_to_main_window()
-
- def click_sign_in_returning_user(self, expect='login'):
- """Clicks the 'sign in' button."""
- self.selenium.find_element(
- *self._sign_in_returning_user_locator).click()
-
- if expect == 'login':
- self.switch_to_main_window()
- elif expect == 'remember':
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._your_computer_content_locator).is_displayed())
- else:
- raise Exception('Unknown expect value: %s' % expect)
-
- def click_verify_email(self):
- """Clicks 'verify email' button."""
- self.selenium.find_element(*self._verify_email_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._check_email_at_locator).is_displayed())
-
- def click_forgot_password(self):
- """Clicks 'forgot password' link (visible after entering a valid email)"""
- self.selenium.find_element(*self._forgot_password_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._reset_password_locator).is_displayed())
-
- def click_reset_password(self):
- """Clicks 'reset password' after forgot password and new passwords entered"""
- self.selenium.find_element(*self._reset_password_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._check_email_at_locator).is_displayed())
-
- def click_add_another_email_address(self):
- """Clicks 'add another email' button."""
- self.selenium.find_element(*self._add_another_email_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._add_new_email_locator).is_displayed())
-
- def click_add_new_email(self):
- """Clicks 'Add' button to insert new email address."""
- self.selenium.find_element(*self._add_new_email_locator).click()
- WebDriverWait(self.selenium, self.timeout).until(
- lambda s: s.find_element(
- *self._check_email_at_locator).is_displayed())
-
- def click_i_trust_this_computer(self):
- """Clicks 'I trust this computer' and signs in """
- self.selenium.find_element(*self._this_is_my_computer_locator).click()
- self.switch_to_main_window()
-
- def click_this_is_not_my_computer(self):
- """Clicks 'I trust this computer' and signs in for a public computer"""
- self.selenium.find_element(*self._this_is_not_my_computer_locator).click()
- self.switch_to_main_window()
-
- def sign_in(self, email, password):
- """Signs in using the specified email address and password."""
- self.email = email
- self.click_next(expect='password')
- self.password = password
- self.click_sign_in()
-
- def sign_in_new_user(self, email, password):
- """Requests verification email using the specified email address."""
- self.email = email
- self.click_next(expect='verify')
- self.password = password
- self.verify_password = password
- self.click_verify_email()
- self.close_window()
- self.switch_to_main_window()
-
- def sign_in_returning_user(self):
- """Signs in with the stored user."""
- self.click_sign_in_returning_user()
View
2  automation-tests/browserid/requirements.txt
@@ -1,2 +0,0 @@
-pytest-mozwebqa==1.0
-requests==0.13.3
View
2  automation-tests/browserid/setup.cfg
@@ -1,2 +0,0 @@
-[pytest]
-python_files=check_*.py
View
0  automation-tests/browserid/tests/__init__.py
No changes.
View
47 automation-tests/browserid/tests/base.py
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import re
-
-import requests
-from selenium.webdriver.support.ui import WebDriverWait
-
-from .. import BrowserID
-from .. mocks.user import MockUser
-import restmail
-
-
-class BaseTest(object):
-
- def browserid_url(self, base_url):
- response = requests.get('%s/' % base_url, verify=False)
- match = re.search(BrowserID.INCLUDE_URL_REGEX, response.content)
- if match:
- return match.group(1)
- else:
- raise Exception('Unable to determine BrowserID URL from %s.' % base_url)
-
- def log_out(self, selenium, timeout):
- WebDriverWait(selenium, timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
- selenium.find_element_by_css_selector('#loggedin a').click()
- WebDriverWait(selenium, timeout).until(
- lambda s: s.find_element_by_css_selector('#loggedout button').is_displayed())
-
- def create_verified_user(self, selenium, timeout):
- user = MockUser()
- from .. pages.sign_in import SignIn
- signin = SignIn(selenium, timeout, expect='new')
- signin.sign_in_new_user(user.primary_email, user.password)
- mail = restmail.get_mail(user.primary_email, timeout=timeout)
- verify_url = re.search(BrowserID.VERIFY_URL_REGEX,
- mail[0]['text']).group(0)
-
- from .. pages.complete_registration import CompleteRegistration
- complete_registration = CompleteRegistration(selenium,
- timeout, verify_url,
- expect='redirect')
- return user
View
56 automation-tests/browserid/tests/check_add_email.py
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import re
-
-import pytest
-
-from .. import BrowserID
-from base import BaseTest
-import restmail
-
-
-@pytest.mark.nondestructive
-class TestAddEmail(BaseTest):
-
- @pytest.mark.travis
- def test_add_email(self, mozwebqa):
- user = self.create_verified_user(mozwebqa.selenium, mozwebqa.timeout)
- user.additional_emails.append('%s_1@restmail.net' % user.id)
-
- # log out
- mozwebqa.selenium.get('%s/' % mozwebqa.base_url)
- self.log_out(mozwebqa.selenium, mozwebqa.timeout)
-
- # initiate add email
- mozwebqa.selenium.find_element_by_css_selector('#loggedout button').click()
- from .. pages.sign_in import SignIn
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='returning')
-
- signin.click_add_another_email_address()
- signin.new_email = user.additional_emails[0]
- assert signin.new_email == user.additional_emails[0], "new email getter failed"
- signin.click_add_new_email()
- signin.close_window()
- signin.switch_to_main_window()
-
- mail = restmail.get_mail(user.additional_emails[0],
- timeout=mozwebqa.timeout)
- assert 'Click to confirm this email address' in mail[0]['text']
- confirm_url = re.search(BrowserID.CONFIRM_URL_REGEX,
- mail[0]['text']).group(0)
-
- from .. pages.complete_registration import CompleteRegistration
- complete_registration = CompleteRegistration(mozwebqa.selenium,
- mozwebqa.timeout, confirm_url, expect='redirect')
-
- self.log_out(mozwebqa.selenium, mozwebqa.timeout)
-
- mozwebqa.selenium.find_element_by_css_selector('#loggedout button').click()
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='returning')
-
- assert user.additional_emails[0] in signin.emails
- assert signin.selected_email == user.additional_emails[0]
View
47 automation-tests/browserid/tests/check_change_password.py
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import pytest
-from selenium.webdriver.support.ui import WebDriverWait
-
-from .. import BrowserID
-from base import BaseTest
-
-
-@pytest.mark.nondestructive
-class TestChangePassword(BaseTest):
-
- @pytest.mark.travis
- def test_change_password(self, mozwebqa):
- user = self.create_verified_user(mozwebqa.selenium, mozwebqa.timeout)
-
- mozwebqa.selenium.get(self.browserid_url(mozwebqa.base_url))
- from .. pages.account_manager import AccountManager
- account_manager = AccountManager(mozwebqa.selenium, mozwebqa.timeout)
-
- assert user.primary_email in account_manager.emails
-
- account_manager.click_edit_password()
- account_manager.old_password = user.password
- assert account_manager.old_password == user.password, "old password getter failed"
- user.password += '_new'
- account_manager.new_password = user.password
- assert account_manager.new_password == user.password, "new password getter failed"
- account_manager.click_password_done()
- account_manager.click_sign_out()
-
- mozwebqa.selenium.get('%s/' % mozwebqa.base_url)
-
- login_locator = '#loggedout button'
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_css_selector(login_locator).is_displayed())
- mozwebqa.selenium.find_element_by_css_selector(login_locator).click()
-
- browser_id = BrowserID(mozwebqa.selenium, mozwebqa.timeout)
- browser_id.sign_in(user.primary_email, user.password)
-
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
View
50 automation-tests/browserid/tests/check_reset_password.py
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import re
-
-import pytest
-
-from .. import BrowserID
-from base import BaseTest
-import restmail
-
-
-@pytest.mark.nondestructive
-class TestResetPassword(BaseTest):
-
- @pytest.mark.travis
- def test_reset_password(self, mozwebqa):
- user = self.create_verified_user(mozwebqa.selenium, mozwebqa.timeout)
- mozwebqa.selenium.get('%s/' % mozwebqa.base_url)
- self.log_out(mozwebqa.selenium, mozwebqa.timeout)
- mozwebqa.selenium.find_element_by_css_selector('#loggedout button').click()
-
- from .. pages.sign_in import SignIn
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='returning')
- signin.click_this_is_not_me()
- signin.email = user.primary_email
- signin.click_next()
- signin.click_forgot_password()
- user.password += '_new'
- signin.password = user.password
- signin.verify_password = user.password
- signin.click_reset_password()
- assert signin.check_email_at_address == user.primary_email
-
- signin.close_window()
- signin.switch_to_main_window()
- mail = restmail.get_mail(user.primary_email,
- message_count=2,
- timeout=mozwebqa.timeout)
- assert 'Click to reset your password' in mail[1]['text']
-
- reset_url = re.search(BrowserID.RESET_URL_REGEX,
- mail[1]['text']).group(0)
-
- from .. pages.complete_registration import CompleteRegistration
- complete_registration = CompleteRegistration(mozwebqa.selenium,
- mozwebqa.timeout, reset_url, expect='redirect')
View
104 automation-tests/browserid/tests/check_sign_in.py
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import pytest
-import time
-from selenium.webdriver.support.ui import WebDriverWait
-
-from .. import BrowserID
-from .. mocks.user import MockUser
-from base import BaseTest
-import restmail
-
-
-@pytest.mark.nondestructive
-class TestSignIn(BaseTest):
-
- @pytest.mark.travis
- def test_sign_in_helper(self, mozwebqa):
- credentials = mozwebqa.credentials['default']
- browser_id = BrowserID(mozwebqa.selenium, mozwebqa.timeout)
- browser_id.sign_in(credentials['email'], credentials['password'])
-
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
-
- @pytest.mark.travis
- def test_sign_in(self, mozwebqa):
- credentials = mozwebqa.credentials['default']
- from .. pages.sign_in import SignIn
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='new')
- signin.email = credentials['email']
- assert signin.email == credentials['email'], "email getter failed"
- signin.click_next(expect='password')
- signin.password = credentials['password']
- assert unicode(signin.password) == unicode(credentials['password']), "password getter failed"
- signin.click_sign_in()
-
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
-
- @pytest.mark.travis
- def test_sign_in_new_user_helper(self, mozwebqa):
- user = MockUser()
- from .. pages.sign_in import SignIn
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='new')
- print 'signing in as %s' % user.primary_email
- signin.sign_in_new_user(user.primary_email, 'password')
- mail = restmail.get_mail(user.primary_email, timeout=mozwebqa.timeout)
- assert 'Click to confirm this email address' in mail[0]['text']
-
- @pytest.mark.travis
- def test_sign_in_new_user(self, mozwebqa):
- user = MockUser()
- from .. pages.sign_in import SignIn
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='new')
- print 'signing in as %s' % user.primary_email
- signin.email = user.primary_email
- signin.click_next(expect='verify')
- signin.password = user.password
- signin.verify_password = user.password
- assert signin.verify_password == user.password, 'verify password getter failed'
- signin.click_verify_email()
- assert signin.check_email_at_address == user.primary_email
-
- signin.close_window()
- signin.switch_to_main_window()
- mail = restmail.get_mail(user.primary_email, timeout=mozwebqa.timeout)
- assert 'Click to confirm this email address' in mail[0]['text']
-
- @pytest.mark.travis
- def test_sign_in_returning_user(self, mozwebqa):
- self.create_verified_user(mozwebqa.selenium, mozwebqa.timeout)
- mozwebqa.selenium.get('%s/' % mozwebqa.base_url)
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
-
- @pytest.mark.travis
- def test_sign_in_is_this_your_computer(self, mozwebqa):
- credentials = mozwebqa.credentials['default']
- browser_id = BrowserID(mozwebqa.selenium, mozwebqa.timeout)
- browser_id.sign_in(credentials['email'], credentials['password'])
-
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
- login_time = time.time()
-
- self.log_out(mozwebqa.selenium, mozwebqa.timeout)
-
- while time.time() < (login_time + 60):
- time.sleep(15)
- mozwebqa.selenium.find_element_by_css_selector('#loggedout button')
-
- mozwebqa.selenium.find_element_by_css_selector('#loggedout button').click()
-
- from .. pages.sign_in import SignIn
- signin = SignIn(mozwebqa.selenium, mozwebqa.timeout, expect='returning')
- signin.click_sign_in_returning_user(expect='remember')
- signin.click_i_trust_this_computer()
-
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_id('loggedin').is_displayed())
View
20 automation-tests/browserid/tests/conftest.py
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from selenium.webdriver.support.ui import WebDriverWait
-
-
-def pytest_runtest_setup(item):
- item.config.option.api = 'webdriver'
-
-
-def pytest_funcarg__mozwebqa(request):
- mozwebqa = request.getfuncargvalue('mozwebqa')
- mozwebqa.selenium.get('%s/' % mozwebqa.base_url)
- WebDriverWait(mozwebqa.selenium, mozwebqa.timeout).until(
- lambda s: s.find_element_by_css_selector('#loggedout button').is_displayed())
- mozwebqa.selenium.find_element_by_css_selector('#loggedout button').click()
- return mozwebqa
View
32 automation-tests/browserid/tests/restmail.py
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import json
-import time
-
-import requests
-
-
-def get_mail(username, message_count=1, timeout=60):
- username = username.partition('@restmail.net')[0]
- end_time = time.time() + timeout
- while(True):
- response = requests.get(
- 'https://restmail.net/mail/%s' % username,
- verify=False)
- restmail = json.loads(response.content)
- if len(restmail) == message_count:
- return restmail
- time.sleep(0.5)
- if(time.time() > end_time):
- break
- raise Exception('Timeout after %(TIMEOUT)s seconds getting restmail for '
- '%(USERNAME)s. Expected %(EXPECTED_MESSAGE_COUNT)s '
- 'messages but there were %(ACTUAL_MESSAGE_COUNT)s.' % {
- 'TIMEOUT': timeout,
- 'USERNAME': username,
- 'EXPECTED_MESSAGE_COUNT': message_count,
- 'ACTUAL_MESSAGE_COUNT': len(restmail)})
View
65 automation-tests/config/sauce-platforms.js
@@ -0,0 +1,65 @@
+// platforms supported by sauce that we test
+const platforms = {
+ /*
+ "linux_firefox_16": {
+ platform: 'LINUX',
+ browserName: 'firefox',
+ version: '16'
+ },
+ "linux_opera_12": {
+ platform: 'LINUX',
+ browserName: 'opera',
+ version: '12'
+ },
+ "osx_firefox_14": {
+ platform: 'MAC',
+ browserName:'firefox',
+ version:'14'
+ },
+ "vista_chrome": {
+ platform:'VISTA',
+ browserName:'chrome'
+ },*/
+ "vista_firefox_16": {
+ platform:'VISTA',
+ browserName:'firefox',
+ version:'16'
+ }/*,
+ "vista_ie_9": {
+ platform:'VISTA',
+ browserName:'internet explorer',
+ version:'9'
+ },
+ "win8_ie_10": {
+ platform: 'Windows 2012',
+ browserName: 'internet explorer',
+ version: '10'
+ },
+ "xp_ie_8": {
+ platform:'XP',
+ browserName: 'internet explorer',
+ version:'8'
+ },
+ "osx_safari_5": {
+ platform:'Mac 10.6',
+ browserName: 'safari',
+ version:'5'
+ }*/
+};
+
+// see http://saucelabs.com/docs/ondemand/additional-config for other opts
+const defaultCapabilities = {
+ // the proxy leads to bugginess/sadness, avoid unless opera/IE
+ avoidProxy: true,
+ // make tests public by default. set public:false in desiredCapabilities to override this.
+ public: true,
+ // timeout if no command received. if you juggle 2 browser sessions,
+ // one will possibly hit this, so don't be too conservative.
+ 'idle-timeout': 90,
+ // timeout global time used by a test. should avoid runaway tests eating
+ // 10 min of sauce time. setting to 3 min for now, relax if needed.
+ 'max-session': 180
+};
+
+exports.platforms = platforms;
+exports.defaultCapabilities = defaultCapabilities;
View
12 automation-tests/config/tests-to-ignore.js
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// These are tests to ignore
+
+exports.tests_to_ignore = [
+ "add-primary-to-secondary.js",
+ "public-terminals.js",
+ "remove-email.js",
+ "returning-user.js"
+];
View
37 automation-tests/credentials.yaml.example
@@ -1,37 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# File contains users data.
-#
-# Each user is a section named with its role
-# and any number of values. At least email,
-# password and name should be present.
-#
-# Example:
-# admin:
-# email: email@site.com
-# password: password
-# name: Test User
-#
-# Still, you are free to add any more data you wish. It will be kept
-# in the same dictionary.
-#
-# Example:
-# admin:
-# email: email@site.com
-# password: password
-# name: Test User
-# username: testuser
-# some_user_data: data
-#
-# The contents of this file are accessible via the pytest-mozwebqa plugin:
-#
-# Example:
-# credentials = mozwebqa.credentials['default']
-# credentials['email']
-
-default:
- email: <value>
- password: <value>
- name: <value>
View
10 automation-tests/lib/asserts.js
@@ -0,0 +1,10 @@
+// desc is optional textual description of the error
+exports.ok = function(fact, desc) {
+ var defaultMsg = "assertion failed: '" + fact + "' is not truthy"
+ if (!fact) return desc || defaultMsg;
+}
+exports.equal = function(lhs, rhs, desc) {
+ var defaultMsg = "assertion failed: actual '" + lhs
+ + "' does not equal expected '" + rhs + "'";
+ if (lhs != rhs) return desc || defaultMsg;
+}
View
75 automation-tests/lib/convert_results.js
@@ -1,75 +0,0 @@
-#!/usr/bin/env node
-/*
- * Converts html reports into nice, machine readable JSON
- * Run: $ ./convert_result.js result/index.html
- */
-
-const fs = require('fs'),
- path = require('path'),
- jsonselect = require('JSONSelect'),
- htmlparser = require('htmlparser');
-
-
-function main (args) {
- var file = fs.readFile(path.resolve(args[2]), "utf8", function (err, html) {
- if (err) throw err;
- parseReport(html);
- });
-}
-
-function parseReport (html) {
- var report = {};
- var handler = new htmlparser.DefaultHandler(function(err, dom) {
- if (err) {
- console.error("Error: " + err);
- } else {
- var results = jsonselect.match(':has(:root > .attribs > .id:val("results")) .children :has(:root > .name:val("tr"))', dom);
-
- // remove header row
- results.shift();
-
- results.forEach(function (node, i, array) {
- var url;
- var result = node.children[1].attribs.class;
-
- // skip traceback rows
- if (!result) return;
-
- try {
- url = result === 'error' ?
- findJobUrl(array[i+1].children[1].children[1].children) :
- node.children[9].children[0].attribs.href;
- } catch (e) {
- url = '';
- }
-
- var name = node.children[5].children[0].data;
-
- report[name] = {
- success: result === 'passed',
- class: node.children[3].children[0].data,
- duration: node.children[7].children[0].data,
- url: url
- };
- });
- }
- });
-
- var parser = new htmlparser.Parser(handler);
- parser.parseComplete(html);
- return report;
-}
-
-// extract saucelab url from error report
-function findJobUrl (children) {
- var result;
- children.forEach(function (node) {
- var match = node.raw.match(/https:\/\/saucelabs.com\/jobs\/[a-f0-9]+/);
- if (match) result = match[0];
- });
- return result;
-}
-
-exports.parseReport = parseReport;
-
-if (process.argv[1] === __filename) main(process.argv);
View
30 automation-tests/lib/personatestuser.js
@@ -0,0 +1,30 @@
+const utils = require("./utils.js"),
+request = require('request');
+
+// TODO factor out common bits with lib/restmail
+// TODO accept all the personatestuser arguments
+
+const DEFAULT_TIMEOUT = 40000;
+
+// grab user creds from personatestuser.org.
+// args include .timeout (optional), .env (optional)
+// callback is cb(error, {email, password}, fullResponse)
+exports.getVerifiedUser = function(args, cb) {
+ if (arguments.length == 1) {
+ cb = args;
+ args = {};
+ }
+ var timeout = args.timeout || DEFAULT_TIMEOUT;
+ var env = args.env || process.env['PERSONA_ENV'] || 'dev';
+ var url = 'http://personatestuser.org/email/' + env;
+
+ request({ url: url, timeout: timeout, json:true}, function (error, response, body) {
+ if (!error && response.statusCode == 200) {
+ if (!body.email) { return cb(new Error('funky getVerifiedUser response')) }
+ cb(error, {email: body.email, pass: body.pass}, body);
+ } else {
+ cb(error || response.body);
+ }
+ });
+};
+
View
30 automation-tests/lib/reporters/file-reporter.js
@@ -0,0 +1,30 @@
+const fs = require('fs'),
+ mkdirp = require('mkdirp'),
+ path = require('path'),
+ existsSync = fs.existsSync || path.existsSync;
+
+function FileReporter(config) {
+ var fileName = config.output_path;
+ this.fileName = fileName;
+
+ try {
+ mkdirp.sync(path.dirname(fileName));
+ }
+ catch(e) {
+ console.log("error:", this.fileName, String(e));
+ }
+}
+FileReporter.prototype.report = function(msg) {
+ try {
+ var fd = fs.openSync(this.fileName, "w");
+ fs.writeSync(fd, msg, 0, msg.length, null);
+ fs.closeSync(fd);
+ }
+ catch(e) {
+ console.log("error:", this.fileName, String(e));
+ }
+};
+FileReporter.prototype.done = function() {
+};
+
+module.exports = FileReporter;
View
11 automation-tests/lib/reporters/std-err-reporter.js
@@ -0,0 +1,11 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function StdErrReporter() { }
+StdErrReporter.prototype.report = function(msg) {
+ process.stderr.write(msg);
+};
+StdErrReporter.prototype.done = function() {};
+
+module.exports = StdErrReporter;
View
12 automation-tests/lib/reporters/std-out-reporter.js
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function StdOutReporter() { }
+StdOutReporter.prototype.report = function(msg) {
+ process.stdout.write(msg);
+};
+StdOutReporter.prototype.done = function() {};
+
+module.exports = StdOutReporter;
+
View
47 automation-tests/lib/restmail.js
@@ -0,0 +1,47 @@
+const utils = require("./utils.js"),
+request = require('request');
+
+const DEFAULT_POLL = 1000;
+const DEFAULT_TIMEOUT = 20000;
+
+// get a randomly generated restmail email
+exports.randomEmail = function(chars, domain) {
+ var str = "";
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+ for (var i=0; i < chars; i++) {
+ str += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
+ }
+
+ // Until GH-2551 is fixed, use lowercase alphanum for email
+ str = str.toLowerCase();
+
+ return str + '@' + (domain ? domain : 'restmail.net');
+};
+
+// poll restmail to attempt to fetch a verification link,
+// args include .timeout (optional), .poll (optional), .index (optional)
+// and .email (required)
+// callback is cb(error, verificationURL, fullEmail)
+exports.getVerificationLink = function(args, cb) {
+ var poll = args.poll || DEFAULT_POLL;
+ var timeout = args.timeout || DEFAULT_TIMEOUT;
+ var email = args.email;
+ var index = args.index || 0;
+ var url = 'http://restmail.net/mail/' + email.split('@')[0];
+
+ utils.waitFor(poll, timeout, function(doneCB) {
+ request(url, function (error, response, body) {
+ if (!error && response.statusCode == 200) {
+ var b = JSON.parse(body);
+ var message = b[index];
+ if (message && message.headers['x-browserid-verificationurl']) {
+ doneCB(true, error, message.headers['x-browserid-verificationurl'], message);
+ }
+ else doneCB(false);
+ } else {
+ doneCB(false);
+ }
+ })
+ }, cb);
+};
View
77 automation-tests/lib/results-aggregator.js
@@ -0,0 +1,77 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var utils = require('util'),
+ events = require('events');
+
+function ResultsAggregator() {
+ // tests which have completed successfully
+ this.successes = [];
+ // tests which have failed
+ this.failures = [];
+ // interesting (saucelabs) urls dropped along the way
+ this.urls = [];
+ // strange non-json messages that we could not understand emitted by the test.
+ this.oddballMessages = [];
+ // information about the current test
+ this.current = { };
+}
+
+utils.inherits(ResultsAggregator, events.EventEmitter);
+
+ResultsAggregator.prototype.parseLine = function(msg) {
+ var self = this;
+ msg.split("\n").forEach(function(msg) {
+ msg = msg.trim();
+ if (msg.length === 0) return;
+ try {
+ msg = JSON.parse(msg);
+ } catch(e) {
+ self.oddballMessages.push(msg.trim());
+ return;
+ }
+ // now handle the message
+ if (msg["0"] === 'context') {
+ self.current.name = msg["1"];
+ } else if (msg["0"] === 'end') {
+ if (self.current.errors) {
+ self.failures.push