Merge pull request #5363 from jrbenny35/add_search_tests
Initial commit adding some basic search tests
This commit is contained in:
Коммит
4b78eeae04
|
@ -34,7 +34,7 @@ addons:
|
|||
apt:
|
||||
packages:
|
||||
- swig
|
||||
firefox: latest
|
||||
firefox: latest-nightly
|
||||
|
||||
before_install:
|
||||
- scripts/travis_es.sh
|
||||
|
@ -52,7 +52,7 @@ before_script:
|
|||
- node --version
|
||||
- |
|
||||
if [[ $TOXENV == "ui-tests" ]]; then
|
||||
wget -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-linux64.tar.gz
|
||||
wget -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.16.1/geckodriver-v0.16.1-linux64.tar.gz
|
||||
mkdir $HOME/geckodriver && tar xvf /tmp/geckodriver.tar.gz -C $HOME/geckodriver
|
||||
export PATH=$HOME/geckodriver:$PATH
|
||||
firefox --version
|
||||
|
|
|
@ -109,7 +109,7 @@ def theme(transactional_db, create_superuser, pytestconfig):
|
|||
type=ADDON_PERSONA,
|
||||
average_daily_users=4242,
|
||||
users=[UserProfile.objects.get(username='uitest')],
|
||||
average_rating=4.21,
|
||||
average_rating=5,
|
||||
description=u'My UI Theme description',
|
||||
file_kw={
|
||||
'hash': 'fakehash',
|
||||
|
@ -155,9 +155,9 @@ def addon(transactional_db, create_superuser, pytestconfig):
|
|||
addon = addon_factory(
|
||||
status=STATUS_PUBLIC,
|
||||
type=ADDON_EXTENSION,
|
||||
average_daily_users=4242,
|
||||
average_daily_users=5567,
|
||||
users=[UserProfile.objects.get(username='uitest')],
|
||||
average_rating=4.21,
|
||||
average_rating=5,
|
||||
description=u'My Addon description',
|
||||
file_kw={
|
||||
'hash': 'fakehash',
|
||||
|
@ -174,8 +174,8 @@ def addon(transactional_db, create_superuser, pytestconfig):
|
|||
support_email=u'support@example.org',
|
||||
support_url=u'https://support.example.org/support/ui-test-addon/',
|
||||
tags=['some_tag', 'another_tag', 'ui-testing',
|
||||
'selenium', 'python'],
|
||||
total_reviews=777,
|
||||
'selenium', 'python'],
|
||||
total_reviews=888,
|
||||
weekly_downloads=2147483647,
|
||||
developer_comments='This is a testing addon, used within pytest.',
|
||||
is_experimental=True,
|
||||
|
@ -196,6 +196,53 @@ def addon(transactional_db, create_superuser, pytestconfig):
|
|||
return addon
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def minimal_addon(transactional_db, create_superuser, pytestconfig):
|
||||
"""Creates a custom addon named 'Ui-Addon-2'.
|
||||
|
||||
It will belong to the user created by the 'create_superuser' fixture.
|
||||
|
||||
It has 1 preview, and 2 reviews.
|
||||
"""
|
||||
if not pytestconfig.option.usingliveserver:
|
||||
return
|
||||
|
||||
default_icons = [x[0] for x in icons() if x[0].startswith('icon/')]
|
||||
addon = addon_factory(
|
||||
status=STATUS_PUBLIC,
|
||||
type=ADDON_EXTENSION,
|
||||
average_daily_users=7000,
|
||||
users=[UserProfile.objects.get(username='uitest')],
|
||||
average_rating=3,
|
||||
description=u'My Addon description',
|
||||
file_kw={
|
||||
'hash': 'fakehash',
|
||||
'platform': amo.PLATFORM_ALL.id,
|
||||
'size': 42,
|
||||
},
|
||||
guid=generate_addon_guid(),
|
||||
icon_type=random.choice(default_icons),
|
||||
name=u'Ui-Addon-2',
|
||||
public_stats=True,
|
||||
slug='ui-test-2',
|
||||
summary=u'My Addon summary',
|
||||
tags=['some_tag', 'another_tag', 'ui-testing',
|
||||
'selenium', 'python'],
|
||||
total_reviews=777,
|
||||
weekly_downloads=22233879,
|
||||
developer_comments='This is a testing addon, used within pytest.',
|
||||
)
|
||||
Preview.objects.create(addon=addon, position=1)
|
||||
Review.objects.create(addon=addon, rating=5, user=user_factory())
|
||||
Review.objects.create(addon=addon, rating=3, user=user_factory())
|
||||
addon.reload()
|
||||
|
||||
addon.save()
|
||||
generate_collection(addon, app=FIREFOX)
|
||||
print('Created addon {0} for testing successfully'.format(addon.name))
|
||||
return addon
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def themes(transactional_db, create_superuser, pytestconfig):
|
||||
"""Creates exactly 6 themes that will be not featured.
|
||||
|
|
|
@ -12,6 +12,11 @@ class Base(Page):
|
|||
super(Base, self).__init__(
|
||||
selenium, base_url, locale=locale, timeout=30, **kwargs)
|
||||
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(
|
||||
lambda _: self.find_element(*self._amo_header).is_displayed())
|
||||
return self
|
||||
|
||||
@property
|
||||
def header(self):
|
||||
return self.Header(self)
|
||||
|
@ -21,6 +26,9 @@ class Base(Page):
|
|||
"""Returns True if a user is logged in"""
|
||||
return self.is_element_displayed(*self.header._user_locator)
|
||||
|
||||
def search_for(self, term):
|
||||
return self.header.search_for(term)
|
||||
|
||||
def login(self, email, password):
|
||||
login_page = self.header.click_login()
|
||||
login_page.login(email, password)
|
||||
|
@ -28,17 +36,14 @@ class Base(Page):
|
|||
def logout(self):
|
||||
self.header.click_logout()
|
||||
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(
|
||||
lambda _: self.find_element(*self._amo_header).is_displayed())
|
||||
return self
|
||||
|
||||
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')
|
||||
_search_button_locator = (By.CSS_SELECTOR, '.search-button')
|
||||
_search_textbox_locator = (By.ID, 'search-q')
|
||||
|
||||
def click_login(self):
|
||||
self.find_element(*self._login_locator).click()
|
||||
|
@ -55,3 +60,9 @@ class Base(Page):
|
|||
action.perform()
|
||||
self.wait.until(lambda s: self.is_element_displayed(
|
||||
*self._login_locator))
|
||||
|
||||
def search_for(self, term):
|
||||
self.find_element(*self._search_textbox_locator).send_keys(term)
|
||||
self.find_element(*self._search_button_locator).click()
|
||||
from pages.desktop.search import SearchResultList
|
||||
return SearchResultList(self.selenium, self.page.base_url)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
from selenium.webdriver.common.by import By
|
||||
import selenium.webdriver.support.expected_conditions as EC
|
||||
|
||||
from pypom import Region
|
||||
|
||||
|
||||
class Sorter(Region):
|
||||
"""Helper class for sorting."""
|
||||
_root_locator = (By.ID, 'sorter')
|
||||
_sort_by_type_locator = (By.CSS_SELECTOR, 'ul > li')
|
||||
_updating_locator = (By.CSS_SELECTOR, '.updating')
|
||||
|
||||
def sort_by(self, sort):
|
||||
"""Clicks the sort button for the requested sort-order."""
|
||||
els = self.find_elements(*self._sort_by_type_locator)
|
||||
next(el for el in els if el.text == sort).click()
|
||||
self.wait.until(
|
||||
EC.invisibility_of_element_located(self._updating_locator))
|
|
@ -0,0 +1,50 @@
|
|||
from pypom import Region
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from base import Base
|
||||
|
||||
|
||||
class SearchResultList(Base):
|
||||
"""Search page"""
|
||||
_results_locator = (By.CSS_SELECTOR, 'div.items div.item.addon')
|
||||
_search_text_locator = (By.CSS_SELECTOR, '.primary > h1')
|
||||
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(lambda _: self.find_element(
|
||||
self._search_text_locator).is_displayed())
|
||||
return self
|
||||
|
||||
@property
|
||||
def results(self):
|
||||
"""List of results"""
|
||||
elements = self.selenium.find_elements(*self._results_locator)
|
||||
return [self.SearchResultItem(self, el) for el in elements]
|
||||
|
||||
def sort_by(self, category, attribute):
|
||||
from pages.desktop.regions.sorter import Sorter
|
||||
Sorter(self).sort_by(category)
|
||||
|
||||
class SearchResultItem(Region):
|
||||
"""Represents individual results on the search page."""
|
||||
_name_locator = (By.CSS_SELECTOR, 'h3 > a')
|
||||
_rating_locator = (By.CSS_SELECTOR, '.rating > .stars')
|
||||
_users_sort_locator = (By.CSS_SELECTOR, '.vitals > .adu')
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Extension Name"""
|
||||
return self.find_element(*self._name_locator).text
|
||||
|
||||
@property
|
||||
def users(self):
|
||||
"""Extensions users"""
|
||||
number = self.find_element(*self._users_sort_locator).text
|
||||
if 'downloads' in number:
|
||||
raise AssertionError('Found weekly downloads instead')
|
||||
return int(number.split()[0].replace(',', ''))
|
||||
|
||||
@property
|
||||
def rating(self):
|
||||
"""Returns the rating"""
|
||||
rating = self.find_element(*self._rating_locator).text
|
||||
return int(rating.split()[1])
|
|
@ -0,0 +1,33 @@
|
|||
import pytest
|
||||
|
||||
from pages.desktop.home import Home
|
||||
|
||||
|
||||
@pytest.mark.smoke
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_searching_for_addon_returns_addon_as_first_result(
|
||||
my_base_url, selenium, addon):
|
||||
"""Test searching for an addon returns the addon."""
|
||||
page = Home(selenium, my_base_url).open()
|
||||
name = str(
|
||||
getattr(addon, 'name', page.featured_extensions.extensions[0].name))
|
||||
search_page = page.search_for(name)
|
||||
assert name in search_page.results[0].name
|
||||
assert name in selenium.title
|
||||
|
||||
|
||||
@pytest.mark.native
|
||||
@pytest.mark.nondestructive
|
||||
@pytest.mark.parametrize('category, sort_attr', [
|
||||
['Most Users', 'users'],
|
||||
['Top Rated', 'rating']])
|
||||
def test_sorting_by(
|
||||
my_base_url, selenium, addon, minimal_addon, category, sort_attr):
|
||||
"""Test searching for an addon and sorting."""
|
||||
page = Home(selenium, my_base_url).open()
|
||||
name = str(
|
||||
getattr(addon, 'name', page.featured_extensions.extensions[0].name))
|
||||
search_page = page.search_for(name)
|
||||
search_page.sort_by(category, sort_attr)
|
||||
results = [getattr(i, sort_attr) for i in search_page.results]
|
||||
assert sorted(results, reverse=True) == results
|
Загрузка…
Ссылка в новой задаче