Skip to content
This repository has been archived by the owner on Aug 20, 2018. It is now read-only.

Commit

Permalink
Merge pull request #734 from bobsilverberg/mobile_nav_changes
Browse files Browse the repository at this point in the history
More fixes for mobile tests
  • Loading branch information
stephendonner committed Nov 5, 2015
2 parents fea37ce + 6bccb4b commit c178719
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 93 deletions.
4 changes: 3 additions & 1 deletion pages/mobile/add_review.py
Expand Up @@ -29,5 +29,7 @@ def write_a_review(self, rating, body):
self.wait_for_element_visible(*self._submit_review_button_locator)
self.set_review_rating(rating)
self.enter_review_with_text(body)
self.selenium.find_element(*self._submit_review_button_locator).click()
review_button = self.selenium.find_element(*self._submit_review_button_locator)
self.scroll_to_element(review_button)
review_button.click()
self.wait_notification_box_visible()
82 changes: 24 additions & 58 deletions pages/mobile/base.py
Expand Up @@ -6,8 +6,7 @@
from selenium.webdriver.support.ui import WebDriverWait

import expected
from pages.page import Page
from pages.page import PageRegion
from pages.page import Page, PageRegion


class Base(Page):
Expand All @@ -17,6 +16,10 @@ class Base(Page):
_notification_content_locator = (By.ID, 'notification-content')
_new_popular_apps_list_locator = (By.CSS_SELECTOR, '.app-list li')
_feed_title_locator = (By.CSS_SELECTOR, '.subheader > h1')
_apps_locator = (By.CSS_SELECTOR, '#navigation a[data-nav-type="apps"]')
_sites_locator = (By.CSS_SELECTOR, '#navigation a[data-nav-type="websites"]')
_close_banner_button_locator = (By.CLASS_NAME, 'mkt-banner-close')
_bag_icon_locator = (By.CLASS_NAME, 'mkt-wordmark')

def set_window_size(self):
# This method can be called to force the browser to a mobile screen
Expand All @@ -39,6 +42,23 @@ def feed_title_text(self):
def notification_message(self):
return self.selenium.find_element(*self._notification_content_locator).text

def click_apps(self):
self.selenium.find_element(*self._apps_locator).click()
from pages.mobile.item_list import ItemList
return ItemList(self.testsetup)

def click_sites(self):
self.selenium.find_element(*self._sites_locator).click()
from pages.mobile.item_list import ItemList
return ItemList(self.testsetup)

def close_banner(self):
close_banner_button = self.selenium.find_element(*self._close_banner_button_locator)
bag_icon = self.selenium.find_element(*self._bag_icon_locator)
if close_banner_button.is_displayed():
close_banner_button.click()
WebDriverWait(self.selenium, self.timeout).until(expected.element_not_moving(bag_icon))

def wait_notification_box_visible(self):
self.wait_for_element_visible(*self._notification_locator)

Expand Down Expand Up @@ -72,7 +92,7 @@ def new_apps(self):

def go_to_first_free_app_page(self):
results_page = self.header.search(':free')
return results_page.results()[0].click()
return results_page.items()[0].click()

class Application(PageRegion):

Expand Down Expand Up @@ -110,7 +130,7 @@ def search_and_click_on_app(self, search_term):

# Select the application link in the list
# It can't always be the first in the list
results = search_page.results()
results = search_page.items()
for i in range(len(results)):
if search_term == results[i].name:
return results[i].click()
Expand Down Expand Up @@ -157,57 +177,3 @@ def click_sign_in(self):
sign_in_item = self.selenium.find_element(*self._sign_in_menu_item_locator)
self.scroll_to_element(sign_in_item)
sign_in_item.click()

def click_new(self):
self.open()
new_item = self.selenium.find_element(*self._new_menu_item_locator)
self.scroll_to_element(new_item)
new_item.click()
return self.new_apps

def click_popular(self):
self.open()
popular_item = self.selenium.find_element(*self._popular_menu_item_locator)
self.scroll_to_element(popular_item)
popular_item.click()
return self.popular_apps

def click_categories(self):
self.open()
categories_item = self.selenium.find_element(*self._categories_menu_item_locator)
self.scroll_to_element(categories_item)
categories_item.click()
return self.Categories(self.testsetup)

class Categories(Page):

_category_item_locator = (By.CSS_SELECTOR, '#categories mkt-category-item')

def __init__(self, testsetup):
Page.__init__(self, testsetup)
# Wait for the first category to be visible
element = self.selenium.find_element(*self._category_item_locator)
WebDriverWait(self.selenium, self.timeout).until(lambda s: element.is_displayed())

@property
def categories(self):
return [self.CategoryItem(self.testsetup, web_element)
for web_element in self.selenium.find_elements(*self._category_item_locator)]

class CategoryItem(PageRegion):

_category_link_locator = (By.CSS_SELECTOR, '.mkt-category-link')

@property
def name(self):
return self.find_element(*self._category_link_locator).text

@property
def link_to_category_page(self):
return self.find_element(*self._category_link_locator).get_attribute("href")

def click_category(self):
category_name = self.name
self.find_element(*self._category_link_locator).click()
from pages.desktop.consumer_pages.category import Category
return Category(self.testsetup, category_name)
1 change: 1 addition & 0 deletions pages/mobile/home.py
Expand Up @@ -17,6 +17,7 @@ class Home(Base):
def go_to_homepage(self):
self.selenium.get(self.base_url)
self.wait_for_element_present(*self._site_navigation_footer_locator)
self.close_banner()

@property
def is_promo_box_not_visible(self):
Expand Down
94 changes: 94 additions & 0 deletions pages/mobile/item_list.py
@@ -0,0 +1,94 @@
# 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

import expected
from pages.page import Page, PageRegion
from pages.mobile.base import Base


class ItemList(Base):

_item_locator = (By.CSS_SELECTOR, '.app-list .app-list-app')
_categories_button_locator = (By.CLASS_NAME, 'header-categories-btn')
_categories_menu_locator = (By.CLASS_NAME, 'cat-menu-overlay')
_new_button_locator = (By.CLASS_NAME, 'sort-toggle-new')
_popular_button_locator = (By.CLASS_NAME, 'sort-toggle-popular')
_new_popular_data_page_type_container_locator = (By.TAG_NAME, 'body')

@property
def is_new_selected(self):
return 'new' in self.selenium.find_element(
*self._new_popular_data_page_type_container_locator).get_attribute('data-page-type')

@property
def is_popular_selected(self):
return 'popular' in self.selenium.find_element(
*self._new_popular_data_page_type_container_locator).get_attribute('data-page-type')

def click_categories(self):
menu = self.selenium.find_element(*self._categories_menu_locator)
self.selenium.find_element(*self._categories_button_locator).click()
WebDriverWait(self.selenium, self.timeout).until(expected.element_not_moving(menu))
return self.Categories(self.testsetup)

def click_new(self):
self.selenium.find_element(*self._new_button_locator).click()

def click_popular(self):
self.selenium.find_element(*self._popular_button_locator).click()

def items(self, wait_for_items=True):
items = self.find_elements(*self._item_locator)
if wait_for_items:
WebDriverWait(self.selenium, self.timeout).until(lambda s: len(items) > 0)
return [self.Item(self.testsetup, item) for item in items]

class Categories(Page):

_category_item_locator = (By.CSS_SELECTOR, '.app-categories li:not(.cat-menu-all)')

def __init__(self, testsetup):
Page.__init__(self, testsetup)
# Wait for the first category to be visible
element = self.selenium.find_element(*self._category_item_locator)
WebDriverWait(self.selenium, self.timeout).until(lambda s: element.is_displayed())

@property
def categories(self):
return [self.CategoryItem(self.testsetup, web_element)
for web_element in self.selenium.find_elements(*self._category_item_locator)]

class CategoryItem(PageRegion):

_category_link_locator = (By.CSS_SELECTOR, '.mkt-category-link')

@property
def name(self):
return self.find_element(*self._category_link_locator).text

@property
def link_to_category_page(self):
return self.find_element(*self._category_link_locator).get_attribute("href")

def click_category(self):
category_name = self.name
self.find_element(*self._category_link_locator).click()
from pages.desktop.consumer_pages.category import Category
return Category(self.testsetup, category_name)

class Item(PageRegion):

_name_locator = (By.CSS_SELECTOR, ".mkt-product-name")

@property
def name(self):
return self.find_element(*self._name_locator).text

def click(self):
self.selenium.find_element(*self._name_locator).click()
from pages.mobile.details import Details
return Details(self.testsetup)
26 changes: 2 additions & 24 deletions pages/mobile/search.py
Expand Up @@ -3,36 +3,14 @@
# 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 pages.page import PageRegion
from pages.mobile.base import Base
from pages.mobile.item_list import ItemList


class Search(Base):
class Search(ItemList):

_result_locator = (By.CSS_SELECTOR, '#search-results .item.result')
_no_results_locator = (By.CSS_SELECTOR, '.no-results')

@property
def no_results_text(self):
return self.find_element(*self._no_results_locator).text

def results(self, wait_for_results=True):
results = self.find_elements(*self._result_locator)
if wait_for_results:
WebDriverWait(self.selenium, self.timeout).until(lambda s: len(results) > 0)
return [self.Result(self.testsetup, result) for result in results]

class Result(PageRegion):

_name_locator = (By.CSS_SELECTOR, ".mkt-product-name")

@property
def name(self):
return self.find_element(*self._name_locator).text

def click(self):
self.selenium.find_element(*self._name_locator).click()
from pages.mobile.details import Details
return Details(self.testsetup)
18 changes: 10 additions & 8 deletions tests/mobile/test_home_page.py
Expand Up @@ -19,17 +19,19 @@ def test_that_promo_module_not_present_on_mobile(self, mozwebqa):
def test_that_verifies_categories_menu(self, mozwebqa):
home_page = Home(mozwebqa)
home_page.go_to_homepage()
categories = home_page.more_menu.click_categories()
page = home_page.click_apps()
categories = page.click_categories()
assert len(categories.categories) > 0

@pytest.mark.nondestructive
def test_switch_between_new_and_popular_pages(self, mozwebqa):
home_page = Home(mozwebqa)
home_page.go_to_homepage()
popular_apps = home_page.more_menu.click_popular()
assert 'Popular' == home_page.feed_title_text
assert len(popular_apps) > 0

new_apps = home_page.more_menu.click_new()
assert 'New' == home_page.feed_title_text
assert len(new_apps) > 0
page = home_page.click_apps()
page.click_popular()
assert page.is_popular_selected
assert len(page.items()) > 0

page.click_new()
assert page.is_new_selected
assert len(page.items()) > 0
4 changes: 2 additions & 2 deletions tests/mobile/test_search.py
Expand Up @@ -14,7 +14,7 @@ def test_that_searching_with_empty_field_returns_results(self, mozwebqa):
home_page = Home(mozwebqa)
home_page.go_to_homepage()
search_page = home_page.header.search('')
assert len(search_page.results()) > 0
assert len(search_page.items()) > 0

@pytest.mark.nondestructive
def test_that_searching_returns_results(self, mozwebqa):
Expand All @@ -24,7 +24,7 @@ def test_that_searching_returns_results(self, mozwebqa):
search_term = details_page.title
details_page.header.click_back()
search_page = home_page.header.search(search_term)
results = search_page.results()
results = search_page.items()
assert len(results) > 0
assert search_term in [result.name for result in results]

Expand Down

0 comments on commit c178719

Please sign in to comment.