This commit is contained in:
Dave Hunt 2016-06-27 09:30:28 +01:00
Родитель 1bce407fa1
Коммит fefca816a0
11 изменённых файлов: 235 добавлений и 3 удалений

60
tests/ui/conftest.py Normal file
Просмотреть файл

@ -0,0 +1,60 @@
import datetime
import os
import urlparse
from fxapom.fxapom import DEV_URL, PROD_URL, FxATestAccount
import jwt
import pytest
import requests
@pytest.fixture
def fxa_account(base_url):
url = DEV_URL if 'dev' in base_url else PROD_URL
return FxATestAccount(url)
@pytest.fixture(scope='session')
def jwt_issuer(base_url, variables):
try:
hostname = [urlparse.urlsplit(base_url).hostname]
return variables['api'][hostname]['jwt_issuer']
except KeyError:
return os.getenv('JWT_ISSUER')
@pytest.fixture(scope='session')
def jwt_secret(base_url, variables):
try:
hostname = [urlparse.urlsplit(base_url).hostname]
return variables['api'][hostname]['jwt_secret']
except KeyError:
return os.getenv('JWT_SECRET')
@pytest.fixture
def jwt_token(base_url, jwt_issuer, jwt_secret):
payload = {
'iss': jwt_issuer,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=30)}
return jwt.encode(payload, jwt_secret, algorithm='HS256')
@pytest.fixture
def user(base_url, fxa_account, jwt_token):
user = {
'email': fxa_account.email,
'password': fxa_account.password,
'username': fxa_account.email.split('@')[0]}
url = '{base_url}/api/v3/accounts/super-create/'.format(base_url=base_url)
params = {
'email': user['email'],
'username': user['username'],
'password': user['password'],
'fxa_id': fxa_account.session.uid}
headers = {'Authorization': 'JWT {token}'.format(token=jwt_token)}
r = requests.post(url, data=params, headers=headers)
assert requests.codes.created == r.status_code
user.update(r.json())
return user

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,50 @@
from pypom import Page, Region
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
class Base(Page):
_url = '{base_url}/{locale}'
def __init__(self, selenium, base_url, locale='en-US', **kwargs):
super(Base, self).__init__(selenium, base_url, locale=locale, **kwargs)
@property
def header(self):
return self.Header(self)
@property
def logged_in(self):
"""Returns True if a user is logged in"""
return self.is_element_displayed(*self.header._user_locator)
def login(self, email, password):
login_page = self.header.click_login()
login_page.login(email, password)
def logout(self):
self.header.click_logout()
class Header(Region):
_root_locator = (By.CLASS_NAME, 'amo-header')
_login_locator = (By.CSS_SELECTOR, '#aux-nav .account a:nth-child(2)')
_logout_locator = (By.CSS_SELECTOR, '.logout > a')
_user_locator = (By.CSS_SELECTOR, '#aux-nav .account .user')
def click_login(self):
self.find_element(*self._login_locator).click()
from pages.desktop.login import Login
return Login(self.selenium, self.page.base_url)
def click_logout(self):
user = self.find_element(*self._user_locator)
logout = self.find_element(*self._logout_locator)
action = ActionChains(self.selenium)
action.move_to_element(user)
action.move_to_element(logout)
action.click()
action.perform()
self.wait.until(lambda s: self.is_element_displayed(
*self._login_locator))

Просмотреть файл

@ -0,0 +1,41 @@
from pypom import Region
from selenium.webdriver.common.by import By
from base import Base
class Home(Base):
@property
def most_popular(self):
return self.MostPopular(self)
class MostPopular(Region):
"""Most popular extensions region"""
_root_locator = (By.ID, 'popular-extensions')
_extension_locator = (By.CSS_SELECTOR, '.toplist li')
@property
def extensions(self):
return [self.Extension(self.page, el) for el in self.find_elements(
*self._extension_locator)]
class Extension(Region):
_name_locator = (By.CLASS_NAME, 'name')
_users_locator = (By.TAG_NAME, 'small')
def __repr__(self):
return '{0.name} ({0.users:,} users)'.format(self)
@property
def name(self):
"""Extension name"""
return self.find_element(*self._name_locator).text
@property
def users(self):
"""Number of users that have downloaded the extension"""
users_str = self.find_element(*self._users_locator).text
return int(users_str.split()[0].replace(',', ''))

Просмотреть файл

@ -0,0 +1,21 @@
from selenium.webdriver.common.by import By
from pages.desktop.base import Base
class Login(Base):
_email_locator = (By.ID, 'id_username')
_continue_locator = (By.CSS_SELECTOR, '#normal-login .login-source-button')
def login(self, email, password):
self.find_element(*self._email_locator).send_keys(email)
self.find_element(*self._continue_locator).click()
from fxapom.pages.sign_in import SignIn
sign_in = SignIn(self.selenium)
# TODO https://github.com/mozilla/fxapom/issues/33
self.wait.until(lambda s: self.is_element_displayed(
*sign_in._email_input_locator))
sign_in.login_password = password
sign_in.click_sign_in()
self.wait.until(lambda s: self.logged_in)

Просмотреть файл

@ -0,0 +1,8 @@
fxapom==1.8.0
PyJWT==1.4.0
PyPOM==1.0
pytest==2.9.2
pytest-instafail==0.3.0
pytest-selenium==1.2.1
pytest-variables==1.4
pytest-xdist==1.14

5
tests/ui/setup.cfg Normal file
Просмотреть файл

@ -0,0 +1,5 @@
[pytest]
addopts = -r=a --verbose
base_url = https://addons-dev.allizom.org
sensitive_url = mozilla\.(com|org)
xfail_strict = true

19
tests/ui/test_home.py Normal file
Просмотреть файл

@ -0,0 +1,19 @@
import pytest
from pages.desktop.home import Home
@pytest.mark.nondestructive
def test_there_are_ten_most_popular_extensions(base_url, selenium):
"""Ten most popular add-ons are listed"""
page = Home(selenium, base_url).open()
assert len(page.most_popular.extensions) == 10
@pytest.mark.nondestructive
def test_most_popular_extensions_are_sorted_by_users(base_url, selenium):
"""Most popular add-ons are sorted by popularity"""
page = Home(selenium, base_url).open()
extensions = page.most_popular.extensions
sorted_by_users = sorted(extensions, key=lambda e: e.users, reverse=True)
assert sorted_by_users == extensions

23
tests/ui/test_login.py Normal file
Просмотреть файл

@ -0,0 +1,23 @@
import pytest
from pages.desktop.home import Home
@pytest.mark.skip(
reason='https://github.com/mozilla/addons-server/issues/2462')
def test_login(base_url, selenium, user):
"""User can login"""
page = Home(selenium, base_url).open()
assert not page.logged_in
page.login(user['email'], user['password'])
assert page.logged_in
@pytest.mark.skip(
reason='https://github.com/mozilla/addons-server/issues/2462')
def test_logout(base_url, selenium, user):
"""User can logout"""
page = Home(selenium, base_url).open()
page.login(user['email'], user['password'])
page.logout()
assert not page.logged_in

11
tox.ini
Просмотреть файл

@ -1,5 +1,5 @@
[tox]
envlist = es, addons, devhub, editors, main, flake8, docs, assets
envlist = es, addons, devhub, editors, main, ui-tests, flake8, docs, assets
[testenv]
basepython = python2.7
@ -16,7 +16,7 @@ whitelist_externals =
commands =
make update_deps
npm install {toxinidir}
py.test -m es_tests --cov-report= --cov-report= --cov=src/olympia/ -v {posargs}
py.test -m es_tests --ignore=tests/ui/ --cov-report= --cov-report= --cov=src/olympia/ -v {posargs}
[testenv:addons]
commands =
@ -40,7 +40,12 @@ commands =
commands =
make update_deps
npm install {toxinidir}
py.test --create-db -n 3 -m 'not es_tests' -v --ignore src/olympia/addons/ --ignore src/olympia/devhub/ --ignore src/olympia/editors/ --cov-report= --cov=src/olympia/ {posargs}
py.test --create-db -n 3 -m 'not es_tests' -v --ignore=tests/ui/ --ignore src/olympia/addons/ --ignore src/olympia/devhub/ --ignore src/olympia/editors/ --cov-report= --cov=src/olympia/ {posargs}
[testenv:ui-tests]
install_command = pip install {packages}
deps = -rtests/ui/requirements.txt
commands = py.test --verify-base-url --driver=Firefox tests/ui {posargs}
[testenv:assets]
commands =