diff --git a/.gitignore b/.gitignore index 2cb8fa2b0a..ec98a9439e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ supervisord.log .env .cache tests/functional/results.html +tests/functional/driver.log tests/functional/assets .eslintcache .docker-build* diff --git a/bin/run-integration-tests.sh b/bin/run-integration-tests.sh index ff04f82105..0c50d9ca59 100755 --- a/bin/run-integration-tests.sh +++ b/bin/run-integration-tests.sh @@ -23,8 +23,7 @@ CMD="${CMD} --base-url ${BASE_URL}" # rerun a flaky test once # DO NOT INCREASE THIS CMD="${CMD} --reruns 1" -# Disable HTML report due to https://github.com/pytest-dev/pytest/issues/1351 -# CMD="${CMD} --html ${RESULTS_PATH}/index.html" +CMD="${CMD} --html ${RESULTS_PATH}/index.html" CMD="${CMD} --junitxml ${RESULTS_PATH}/junit.xml" if [ -n "${DRIVER}" ]; then CMD="${CMD} --driver ${DRIVER}"; fi diff --git a/docker/bin/run_integration_tests.sh b/docker/bin/run_integration_tests.sh index 21fef36028..694068576c 100755 --- a/docker/bin/run_integration_tests.sh +++ b/docker/bin/run_integration_tests.sh @@ -12,7 +12,7 @@ case $1 in ;; firefox) BROWSER_NAME=firefox - BROWSER_VERSION="45.0" + BROWSER_VERSION="57.0" PLATFORM="Windows 10" ;; ie) @@ -69,7 +69,7 @@ if [ "${DRIVER}" = "Remote" ]; then # Waits until all nodes are ready and then runs tests against a local # bedrock instance. - SELENIUM_VERSION=${SELENIUM_VERSION:-2.48.2} + SELENIUM_VERSION=${DOCKER_SELENIUM_VERSION:-"3.5.3-astatine"} docker pull selenium/hub:${SELENIUM_VERSION} docker pull selenium/node-firefox:${SELENIUM_VERSION} @@ -83,7 +83,7 @@ if [ "${DRIVER}" = "Remote" ]; then # start selenium grid nodes for NODE_NUMBER in `seq ${NUMBER_OF_NODES:-5}`; do - docker run -d --rm \ + docker run -d --rm --shm-size 2g \ --name bedrock-selenium-node-${NODE_NUMBER}-${GIT_COMMIT_SHORT} \ ${DOCKER_LINKS[@]} \ selenium/node-firefox:${SELENIUM_VERSION} diff --git a/docs/testing.rst b/docs/testing.rst index 9c5aa8d95d..e5efcd3a5f 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -54,7 +54,10 @@ Running functional tests Before running the functional tests, please make sure to follow the bedrock :ref:`installation docs`, including the database sync that is needed to pull in external data such as event/blog feeds etc. These are required for - some of the tests to pass. + some of the tests to pass. To run the tests using Firefox, you must also first + download `geckodriver`_ and make it available in your `system path`_. You can + alternatively specify the path to geckodriver using the command line (see the + `pytest-selenium documentation`_ for more information). To run the full functional test suite against your local bedrock instance: @@ -343,3 +346,5 @@ and also do not depend on a crawler to find them. .. _download: https://github.com/mozilla/bedrock/blob/master/tests/functional/test_download.py .. _localized download: https://github.com/mozilla/bedrock/blob/master/tests/functional/test_download_l10n.py .. _Basket: https://github.com/mozilla/basket +.. _geckodriver: https://github.com/mozilla/geckodriver/releases/latest +.. _system path: https://developer.mozilla.org/docs/Mozilla/QA/Marionette/WebDriver#Add_executable_to_system_path diff --git a/jenkins/global.yml b/jenkins/global.yml index 1a9c35fb23..26a95f6a0a 100644 --- a/jenkins/global.yml +++ b/jenkins/global.yml @@ -1,5 +1,6 @@ environment: - SELENIUM_VERSION: 2.52.0 + SELENIUM_VERSION: 3.5.0 + DOCKER_SELENIUM_VERSION: 3.5.3-astatine regions: usw: diff --git a/requirements/test.txt b/requirements/test.txt index 909cefdfbd..1779704481 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -20,18 +20,18 @@ pytest==3.0.1 \ pytest-django==3.0.0 \ --hash=sha256:7898731205fa245926c800273dcffcd9b25e0b660a363ecb6cc2901ffe4aa1cc \ --hash=sha256:5952283b0e6e0f9d8cb46803636e3940e1c77da8a529f03a8a4320f52d9bf560 -pytest-html==1.10.0 \ - --hash=sha256:c95e04dc2889bdd6b856b61710bb2a8b9510f423baa6912387e9aefffe9afa55 \ - --hash=sha256:2093b97e41b4e8881a47e2926ea2343d7ce67d9d0f106bc21d5ba542e86e56d0 -pytest-selenium==1.3.1 \ - --hash=sha256:e321bb93ac2b45fbe1f86f3512799fb7622253f0cebe1d87de1b2a11f7ee6a5e \ - --hash=sha256:48dcdecafae6f5b8b3319770217b12114df317a7a60b82b9551a96e3e3988997 -pytest-variables==1.4 \ - --hash=sha256:29dcb084ed5d0c357e925c9a6cb454dbe7ae6192fdea2f9d1929f521b4e532e3 \ - --hash=sha256:bd2e152e64c8f670e7969c76219a7842cf8ede795703127981ed71af38cfe08a -selenium==2.53.6 \ - --hash=sha256:5071f43daa2e698d60d5633ab0a6630cc68a852b360be99144f1c4c1ace2746c \ - --hash=sha256:f507181f13768d73b98dd9647a466ea5758ef5c7f07b62a285d2bd8de9b27016 +pytest-html==1.14.1 \ + --hash=sha256:bc6007504193e93b135aa48eedd798957beef895c090a557984a65e97fb2c59e \ + --hash=sha256:6f2dd32a98e76503cd1bfa8647268d8622b848c7c99dbef5840a426dd124e8f0 +pytest-selenium==1.11.1 \ + --hash=sha256:b98f97f7fc1f24b9806ab369df3077cf43cce0884e427ad7a21b9239ac8bef47 \ + --hash=sha256:91a94a1221d180c7d455b5b1bd50d5cbce797f0ca81d28239075048abbf416b4 +pytest-variables==1.5.1 \ + --hash=sha256:1365c5f2c3be70d1b165272c1ab76ba0692c901db9b98c0b09062cc70b55a36d \ + --hash=sha256:8f2b7c16c54bfe93561c7a36a5e9d8780bdcd36e6e37d9f7b3b51b656449e2ea +selenium==3.5.0 \ + --hash=sha256:69b479bdfa1ab2fee86a75086f7d5c6ef93cdad8cb6521cb0596554c6722f3eb \ + --hash=sha256:267418f5fde1a4f8c180e5b8f45bd57c6d45b1f7d8fa5ad699a48e9a98fa79a3 pytest-xdist==1.15.0 \ --hash=sha256:6238395f8bd050f9288a3b10f34330edece80f4424cf2b4204d6e7d622f0f00b pytest-rerunfailures==2.0.1 \ @@ -39,3 +39,6 @@ pytest-rerunfailures==2.0.1 \ pytest-base-url==1.1.0 \ --hash=sha256:90a1ce6a00a558231117b5aee32300edecbc0c2fd701c13e8cec62177900d28c \ --hash=sha256:001c1b2678dae82c2891db415251361b29ed6824cb2085e4821635119499071e +pytest-metadata==1.3.0 \ + --hash=sha256:2aa89161636c12418b2f8dfe226b6007a50ce3570f2b09fe23d72506fb21a3bc \ + --hash=sha256:b8735ad24a4974b35ca2d37a443596a26e0986754b0841c46231f4a6f6fa92c9 diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py index 8e223077d3..08055d0853 100644 --- a/tests/functional/conftest.py +++ b/tests/functional/conftest.py @@ -9,9 +9,27 @@ VIEWPORT = { 'mobile': {'width': 320, 'height': 480}} +@pytest.fixture +def capabilities(request, capabilities): + driver = request.config.getoption('driver') + if capabilities.get('browserName', driver).lower() == 'firefox': + capabilities['marionette'] = True + return capabilities + + +@pytest.fixture +def driver_log(): + return 'tests/functional/driver.log' + + @pytest.fixture(scope='session') -def session_capabilities(session_capabilities): - session_capabilities.setdefault('tags', []).append('bedrock') +def session_capabilities(pytestconfig, session_capabilities): + if pytestconfig.getoption('driver') == 'SauceLabs': + session_capabilities.setdefault('tags', []).append('bedrock') + + # Avoid default SauceLabs proxy for IE8. + session_capabilities['avoidProxy'] = True + return session_capabilities diff --git a/tests/functional/firefox/new/test_download.py b/tests/functional/firefox/new/test_download.py index a192ca0db2..a59e56923e 100644 --- a/tests/functional/firefox/new/test_download.py +++ b/tests/functional/firefox/new/test_download.py @@ -15,9 +15,9 @@ def test_download_button_displayed(base_url, selenium): assert page.download_button.is_displayed +# Firefox and Internet Explorer don't cope well with file prompts whilst using Selenium. +@pytest.mark.skip_if_firefox(reason='http://saucelabs.com/jobs/5a8a62a7620f489d92d6193fa67cf66b') @pytest.mark.skip_if_internet_explorer(reason='https://github.com/SeleniumHQ/selenium/issues/448') -@pytest.mark.smoke -@pytest.mark.sanity @pytest.mark.nondestructive def test_click_download_button(base_url, selenium): page = DownloadPage(selenium, base_url).open() diff --git a/tests/functional/firefox/new/test_thank_you.py b/tests/functional/firefox/new/test_thank_you.py index ace7543f9c..033f64bd0a 100644 --- a/tests/functional/firefox/new/test_thank_you.py +++ b/tests/functional/firefox/new/test_thank_you.py @@ -7,9 +7,9 @@ import pytest from pages.firefox.new.thank_you import ThankYouPage +# Firefox and Internet Explorer don't cope well with file prompts whilst using Selenium. +@pytest.mark.skip_if_firefox(reason='http://saucelabs.com/jobs/5a8a62a7620f489d92d6193fa67cf66b') @pytest.mark.skip_if_internet_explorer(reason='https://github.com/SeleniumHQ/selenium/issues/448') -@pytest.mark.smoke -@pytest.mark.sanity @pytest.mark.nondestructive def test_direct_download_link_thank_you(base_url, selenium): page = ThankYouPage(selenium, base_url).open() diff --git a/tests/functional/test_contact.py b/tests/functional/test_contact.py index 4e03de2f2e..eaf24ae308 100644 --- a/tests/functional/test_contact.py +++ b/tests/functional/test_contact.py @@ -7,7 +7,6 @@ import pytest from pages.contact import ContactPage, SpacesPage, CommunitiesPage -@pytest.mark.flaky(reruns=1) @pytest.mark.nondestructive def test_tab_navigation(base_url, selenium): page = ContactPage(selenium, base_url).open() @@ -34,7 +33,6 @@ def test_tab_navigation(base_url, selenium): assert contact_page.seed_url in selenium.current_url -@pytest.mark.flaky(reruns=1) @pytest.mark.nondestructive def test_spaces_list(base_url, selenium): page = SpacesPage(selenium, base_url).open() @@ -46,7 +44,6 @@ def test_spaces_list(base_url, selenium): assert 1 == page.displayed_map_pins -@pytest.mark.flaky(reruns=1) @pytest.mark.nondestructive def test_communities_region_list(base_url, selenium): page = CommunitiesPage(selenium, base_url).open() @@ -58,7 +55,6 @@ def test_communities_region_list(base_url, selenium): assert key.is_selected -@pytest.mark.flaky(reruns=1) @pytest.mark.nondestructive def test_communities_region_legend(base_url, selenium): page = CommunitiesPage(selenium, base_url).open() @@ -70,7 +66,6 @@ def test_communities_region_legend(base_url, selenium): assert region.is_displayed -@pytest.mark.flaky(reruns=1) @pytest.mark.nondestructive def test_communities_region_menus(base_url, selenium): page = CommunitiesPage(selenium, base_url).open() diff --git a/tests/pages/about.py b/tests/pages/about.py index b32034bc8a..8811df56d4 100644 --- a/tests/pages/about.py +++ b/tests/pages/about.py @@ -9,7 +9,7 @@ from pages.base import BasePage class AboutPage(BasePage): - URL_TEMPLATE = '/{locale}/about' + URL_TEMPLATE = '/{locale}/about/' _video_overlay_locator = (By.CSS_SELECTOR, '.moz-video-container .moz-video-button') _video_locator = (By.CSS_SELECTOR, '.moz-video-container video') diff --git a/tests/pages/base.py b/tests/pages/base.py index 9f9f24029b..05f79e30ea 100644 --- a/tests/pages/base.py +++ b/tests/pages/base.py @@ -11,7 +11,7 @@ from regions.newsletter import NewsletterEmbedForm class BasePage(Page): - URL_TEMPLATE = '/{locale}' + URL_TEMPLATE = '/{locale}/' def __init__(self, selenium, base_url, locale='en-US', **url_kwargs): super(BasePage, self).__init__(selenium, base_url, locale=locale, **url_kwargs) diff --git a/tests/pages/contact.py b/tests/pages/contact.py index 969c623bc3..1f0104749f 100644 --- a/tests/pages/contact.py +++ b/tests/pages/contact.py @@ -10,7 +10,7 @@ from pages.base import BasePage class ContactPage(BasePage): - URL_TEMPLATE = '/{locale}/contact' + URL_TEMPLATE = '/{locale}/contact/' _map_pins_locator = (By.CSS_SELECTOR, '#map img.leaflet-marker-icon') _contact_tab_locator = (By.CSS_SELECTOR, '.category-tabs > li[data-id=contact]') @@ -64,6 +64,7 @@ class SpacesPage(ContactPage): URL_TEMPLATE = '/{locale}/contact/spaces' + _map_locator = (By.ID, 'map') _spaces_locator = (By.CSS_SELECTOR, '#nav-spaces li') @property @@ -91,8 +92,9 @@ class SpacesPage(ContactPage): def click(self): self.find_element(*self._link_locator).click() - self.wait.until(lambda s: self.is_displayed and - self.page.displayed_map_pins == 1) + self.wait.until(lambda s: self.is_displayed) + self.page.scroll_element_into_view(*self.page._map_locator) + self.wait.until(lambda s: self.page.displayed_map_pins == 1) class CommunitiesPage(ContactPage): diff --git a/tests/pages/contribute/contribute.py b/tests/pages/contribute/contribute.py index df36774d96..8821e2011f 100644 --- a/tests/pages/contribute/contribute.py +++ b/tests/pages/contribute/contribute.py @@ -10,7 +10,7 @@ from pages.regions.modal import Modal class ContributePage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute' + URL_TEMPLATE = '/{locale}/contribute/' _video_play_locator = (By.CSS_SELECTOR, '.video-play') diff --git a/tests/pages/contribute/events.py b/tests/pages/contribute/events.py index 0e3aaca427..0a107dddfc 100644 --- a/tests/pages/contribute/events.py +++ b/tests/pages/contribute/events.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class ContributeEventsPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/events' + URL_TEMPLATE = '/{locale}/contribute/events/' _events_table_locator = (By.CSS_SELECTOR, '.events-table > tbody > tr') diff --git a/tests/pages/contribute/friends.py b/tests/pages/contribute/friends.py index 68d9323490..cab8ac63f8 100644 --- a/tests/pages/contribute/friends.py +++ b/tests/pages/contribute/friends.py @@ -11,7 +11,7 @@ from pages.contribute.base import ContributeBasePage class ContributeFriendsPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/friends' + URL_TEMPLATE = '/{locale}/contribute/friends/' _email_locator = (By.ID, 'id_email') _fx_and_you_locator = (By.ID, 'id_fx-and-you') diff --git a/tests/pages/contribute/stories.py b/tests/pages/contribute/stories.py index afcbe899ec..6189bb3cb2 100644 --- a/tests/pages/contribute/stories.py +++ b/tests/pages/contribute/stories.py @@ -11,9 +11,9 @@ class ContributeStoriesPage(ContributeBasePage): # We're specifically testing Shreya's story. Stories all use # a shared template so it's probably overkill to test them all. - URL_TEMPLATE = '/{locale}/contribute/stories/shreyas' + URL_TEMPLATE = '/{locale}/contribute/stories/shreyas/' - _story_locator = (By.CSS_SELECTOR, '.story-more') + _story_locator = (By.CLASS_NAME, 'story-more') _story_toggle_locator = (By.CSS_SELECTOR, '.more-toggle > button') def show_story(self): diff --git a/tests/pages/contribute/task/dev_tools_challenger.py b/tests/pages/contribute/task/dev_tools_challenger.py index cc36d102af..3b16b72fe8 100644 --- a/tests/pages/contribute/task/dev_tools_challenger.py +++ b/tests/pages/contribute/task/dev_tools_challenger.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class DevToolsChallengerTaskPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/task/devtools-challenger' + URL_TEMPLATE = '/{locale}/contribute/task/devtools-challenger/' _download_button_locator = (By.ID, 'download-button-desktop-alpha') _visit_dev_tools_challenger_locator = (By.CSS_SELECTOR, 'a[data-task="devtools"]') diff --git a/tests/pages/contribute/task/encryption.py b/tests/pages/contribute/task/encryption.py index 6d000acb3b..fc0f4bf267 100644 --- a/tests/pages/contribute/task/encryption.py +++ b/tests/pages/contribute/task/encryption.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class EncryptionTaskPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/task/encryption' + URL_TEMPLATE = '/{locale}/contribute/task/encryption/' _take_the_pledge_button_locator = (By.CSS_SELECTOR, 'a[data-task="encryption"]') diff --git a/tests/pages/contribute/task/joy_of_coding.py b/tests/pages/contribute/task/joy_of_coding.py index 9894beb02c..9d6f3151c3 100644 --- a/tests/pages/contribute/task/joy_of_coding.py +++ b/tests/pages/contribute/task/joy_of_coding.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class JoyOfCodingTaskPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/task/joy-of-coding' + URL_TEMPLATE = '/{locale}/contribute/task/joy-of-coding/' _video_locator = (By.ID, 'joc') _watch_the_video_button_locator = (By.CSS_SELECTOR, 'button[data-task="joyofcoding"]') diff --git a/tests/pages/contribute/task/mobile.py b/tests/pages/contribute/task/mobile.py index 75db50b84b..6238c993d9 100644 --- a/tests/pages/contribute/task/mobile.py +++ b/tests/pages/contribute/task/mobile.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class MobileTaskPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/task/firefox-mobile' + URL_TEMPLATE = '/{locale}/contribute/task/firefox-mobile/' _android_download_button_locator = (By.CSS_SELECTOR, '.step-content a[data-download-os="Android"]') _ios_download_button_locator = (By.CSS_SELECTOR, '.step-content a[data-download-os="iOS"]') diff --git a/tests/pages/contribute/task/stumbler.py b/tests/pages/contribute/task/stumbler.py index 368267f7ea..25df636e3b 100644 --- a/tests/pages/contribute/task/stumbler.py +++ b/tests/pages/contribute/task/stumbler.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class StumblerTaskPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/task/stumbler' + URL_TEMPLATE = '/{locale}/contribute/task/stumbler/' _stumbler_button_locator = (By.CLASS_NAME, 'stumbler-button') diff --git a/tests/pages/contribute/task/twitter.py b/tests/pages/contribute/task/twitter.py index 2e1e5cf590..aa800c3c30 100644 --- a/tests/pages/contribute/task/twitter.py +++ b/tests/pages/contribute/task/twitter.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class TwitterTaskPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/task/follow-mozilla' + URL_TEMPLATE = '/{locale}/contribute/task/follow-mozilla/' _share_button_locator = (By.CSS_SELECTOR, 'a[data-action="tweet"]') _follow_button_locator = (By.CSS_SELECTOR, 'a[data-action="follow"]') diff --git a/tests/pages/contribute/tasks.py b/tests/pages/contribute/tasks.py index 707b363da3..5de00965e7 100644 --- a/tests/pages/contribute/tasks.py +++ b/tests/pages/contribute/tasks.py @@ -9,7 +9,7 @@ from pages.contribute.base import ContributeBasePage class ContributeSignUpPage(ContributeBasePage): - URL_TEMPLATE = '/{locale}/contribute/signup' + URL_TEMPLATE = '/{locale}/contribute/signup/' _twitter_task_locator = (By.CSS_SELECTOR, 'a[data-task="Connect with Mozilla on Twitter"]') _mobile_task_locator = (By.CSS_SELECTOR, 'a[data-task="Get Firefox on Your Phone"]') diff --git a/tests/pages/firefox/all.py b/tests/pages/firefox/all.py index 2dbdf92125..3abf7798e6 100644 --- a/tests/pages/firefox/all.py +++ b/tests/pages/firefox/all.py @@ -9,7 +9,7 @@ from pages.firefox.base import FirefoxBasePage, FirefoxBaseRegion class FirefoxAllPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/all' + URL_TEMPLATE = '/{locale}/firefox/all/' _search_input_locator = (By.ID, 'language-search-q') _submit_button_locator = (By.CSS_SELECTOR, '#language-search button') diff --git a/tests/pages/firefox/channel/android.py b/tests/pages/firefox/channel/android.py index 5964e7895f..cf49e3683e 100644 --- a/tests/pages/firefox/channel/android.py +++ b/tests/pages/firefox/channel/android.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class ChannelAndroidPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/channel/android' + URL_TEMPLATE = '/{locale}/firefox/channel/android/' _beta_download_locator = (By.ID, 'android-beta-download') _nightly_download_locator = (By.ID, 'android-nightly-download') diff --git a/tests/pages/firefox/channel/desktop.py b/tests/pages/firefox/channel/desktop.py index 8e45aa91a5..471846b76a 100644 --- a/tests/pages/firefox/channel/desktop.py +++ b/tests/pages/firefox/channel/desktop.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class ChannelDesktopPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/channel/desktop' + URL_TEMPLATE = '/{locale}/firefox/channel/desktop/' _beta_download_locator = (By.ID, 'desktop-beta-download') _developer_download_locator = (By.ID, 'desktop-developer-download') diff --git a/tests/pages/firefox/channel/ios.py b/tests/pages/firefox/channel/ios.py index b714fd842f..35e25248c8 100644 --- a/tests/pages/firefox/channel/ios.py +++ b/tests/pages/firefox/channel/ios.py @@ -9,7 +9,7 @@ from pages.firefox.base import FirefoxBasePage class ChannelIOSPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/channel/ios' + URL_TEMPLATE = '/{locale}/firefox/channel/ios/' _testflight_button_locator = (By.CLASS_NAME, 'testflight-cta') diff --git a/tests/pages/firefox/developer.py b/tests/pages/firefox/developer.py index ef351ee1a3..1f2381247a 100644 --- a/tests/pages/firefox/developer.py +++ b/tests/pages/firefox/developer.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class DeveloperPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/developer' + URL_TEMPLATE = '/{locale}/firefox/developer/' _primary_download_locator = (By.ID, 'intro-download') _secondary_download_locator = (By.ID, 'footer-download') diff --git a/tests/pages/firefox/do_not_track.py b/tests/pages/firefox/do_not_track.py index 4cb8ce9129..93aec9cd56 100644 --- a/tests/pages/firefox/do_not_track.py +++ b/tests/pages/firefox/do_not_track.py @@ -9,7 +9,7 @@ from pages.firefox.base import FirefoxBasePage, FirefoxBaseRegion class DoNotTrackPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/dnt' + URL_TEMPLATE = '/{locale}/firefox/dnt/' _dnt_status_locator = (By.CSS_SELECTOR, '#dnt-status > h5') _faqs_locator = (By.CSS_SELECTOR, '#faq > section') diff --git a/tests/pages/firefox/family_navigation.py b/tests/pages/firefox/family_navigation.py index a11a85da6d..ec92f3ff5e 100644 --- a/tests/pages/firefox/family_navigation.py +++ b/tests/pages/firefox/family_navigation.py @@ -7,4 +7,4 @@ from pages.firefox.base import FirefoxBasePage class FirefoxPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/{slug}' + URL_TEMPLATE = '/{locale}/firefox/{slug}/' diff --git a/tests/pages/firefox/features/feature.py b/tests/pages/firefox/features/feature.py index 9360f28108..9affc55889 100644 --- a/tests/pages/firefox/features/feature.py +++ b/tests/pages/firefox/features/feature.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class FeaturePage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/features/{slug}' + URL_TEMPLATE = '/{locale}/firefox/features/{slug}/' _download_button_locator = (By.ID, 'features-header-download') diff --git a/tests/pages/firefox/installer_help.py b/tests/pages/firefox/installer_help.py index 5b3fbfcc9b..4b5aef6e2f 100644 --- a/tests/pages/firefox/installer_help.py +++ b/tests/pages/firefox/installer_help.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class InstallerHelpPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/installer-help' + URL_TEMPLATE = '/{locale}/firefox/installer-help/' _firefox_download_button_locator = (By.ID, 'download-button-desktop-release') _beta_download_button_locator = (By.ID, 'download-button-desktop-beta') diff --git a/tests/pages/firefox/ios_testflight.py b/tests/pages/firefox/ios_testflight.py index 71497194ac..f367d746b9 100644 --- a/tests/pages/firefox/ios_testflight.py +++ b/tests/pages/firefox/ios_testflight.py @@ -10,7 +10,7 @@ from pages.firefox.base import FirefoxBasePage class iOSTestFlightPage(FirefoxBasePage): - URL_TEMPLATE = '/{locale}/firefox/ios/testflight' + URL_TEMPLATE = '/{locale}/firefox/ios/testflight/' _email_locator = (By.ID, 'id_email') _html_format_locator = (By.ID, 'id_fmt_0') diff --git a/tests/pages/firefox/nightly.py b/tests/pages/firefox/nightly.py index 53153c4b22..ff75405a5d 100644 --- a/tests/pages/firefox/nightly.py +++ b/tests/pages/firefox/nightly.py @@ -9,7 +9,7 @@ from pages.base import BasePage class FirstRunPage(BasePage): - URL_TEMPLATE = '/{locale}/firefox/nightly/firstrun' + URL_TEMPLATE = '/{locale}/firefox/nightly/firstrun/' _start_testing_locator = (By.CSS_SELECTOR, '#nightly-box .test .button') _start_coding_locator = (By.CSS_SELECTOR, '#nightly-box .code .button') diff --git a/tests/pages/history.py b/tests/pages/history.py index d9f6aee2c4..e2712a2532 100644 --- a/tests/pages/history.py +++ b/tests/pages/history.py @@ -9,7 +9,7 @@ from pages.base import BasePage class HistoryPage(BasePage): - URL_TEMPLATE = '/{locale}/about/history' + URL_TEMPLATE = '/{locale}/about/history/' _slideshow_locator = (By.CSS_SELECTOR, '#slideshow') _previous_button_locator = (By.CSS_SELECTOR, '.slide-control > .prev') diff --git a/tests/pages/internet_health.py b/tests/pages/internet_health.py index 175a560374..0b4b7b0e55 100644 --- a/tests/pages/internet_health.py +++ b/tests/pages/internet_health.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class InternetHealthPage(BasePage): - URL_TEMPLATE = '/{locale}/internet-health' + URL_TEMPLATE = '/{locale}/internet-health/' _download_button_locator = (By.ID, 'global-nav-download-firefox') diff --git a/tests/pages/leadership.py b/tests/pages/leadership.py index b204940783..41f6941900 100644 --- a/tests/pages/leadership.py +++ b/tests/pages/leadership.py @@ -10,7 +10,7 @@ from pages.regions.modal import Modal class LeadershipPage(BasePage): - URL_TEMPLATE = '/{locale}/about/leadership' + URL_TEMPLATE = '/{locale}/about/leadership/' _corporation_bios_locator = (By.CSS_SELECTOR, '.gallery.mgmt-corp .vcard.has-bio') _foundation_bios_locator = (By.CSS_SELECTOR, '.gallery.mgmt-foundation .vcard.has-bio') diff --git a/tests/pages/mission.py b/tests/pages/mission.py index 7145dea0b2..f811d50658 100644 --- a/tests/pages/mission.py +++ b/tests/pages/mission.py @@ -9,7 +9,7 @@ from pages.base import BasePage class MissionPage(BasePage): - URL_TEMPLATE = '/{locale}/mission' + URL_TEMPLATE = '/{locale}/mission/' _video_overlay_locator = (By.CSS_SELECTOR, '.moz-video-container > .moz-video-button') _video_locator = (By.CSS_SELECTOR, '.moz-video-container > video') diff --git a/tests/pages/newsletter/base.py b/tests/pages/newsletter/base.py index 59a2c540c0..024906a948 100644 --- a/tests/pages/newsletter/base.py +++ b/tests/pages/newsletter/base.py @@ -11,7 +11,7 @@ from pages.base import BasePage class NewsletterBasePage(BasePage): - URL_TEMPLATE = '/{locale}/newsletter' + URL_TEMPLATE = '/{locale}/newsletter/' _email_locator = (By.ID, 'id_email') _country_locator = (By.ID, 'id_country') diff --git a/tests/pages/newsletter/developer.py b/tests/pages/newsletter/developer.py index c86ae41b3c..f93f68bb0a 100644 --- a/tests/pages/newsletter/developer.py +++ b/tests/pages/newsletter/developer.py @@ -7,4 +7,4 @@ from pages.newsletter.base import NewsletterBasePage class DeveloperNewsletterPage(NewsletterBasePage): - URL_TEMPLATE = '/{locale}/newsletter/developer' + URL_TEMPLATE = '/{locale}/newsletter/developer/' diff --git a/tests/pages/newsletter/firefox.py b/tests/pages/newsletter/firefox.py index e286e55dba..3cb2dcaf14 100644 --- a/tests/pages/newsletter/firefox.py +++ b/tests/pages/newsletter/firefox.py @@ -7,4 +7,4 @@ from pages.newsletter.base import NewsletterBasePage class FirefoxNewsletterPage(NewsletterBasePage): - URL_TEMPLATE = '/{locale}/newsletter/firefox' + URL_TEMPLATE = '/{locale}/newsletter/firefox/' diff --git a/tests/pages/newsletter/mozilla.py b/tests/pages/newsletter/mozilla.py index 0f46aa69f1..f4faf75895 100644 --- a/tests/pages/newsletter/mozilla.py +++ b/tests/pages/newsletter/mozilla.py @@ -7,4 +7,4 @@ from pages.newsletter.base import NewsletterBasePage class MozillaNewsletterPage(NewsletterBasePage): - URL_TEMPLATE = '/{locale}/newsletter/mozilla' + URL_TEMPLATE = '/{locale}/newsletter/mozilla/' diff --git a/tests/pages/not_found.py b/tests/pages/not_found.py index ac7e8f2a5c..e784087c90 100644 --- a/tests/pages/not_found.py +++ b/tests/pages/not_found.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class NotFoundPage(BasePage): - URL_TEMPLATE = '/{locale}/404' + URL_TEMPLATE = '/{locale}/404/' _download_button_locator = (By.ID, 'download-button-desktop-release') diff --git a/tests/pages/partnerships.py b/tests/pages/partnerships.py index b6624d7c89..1268fdedae 100644 --- a/tests/pages/partnerships.py +++ b/tests/pages/partnerships.py @@ -9,7 +9,7 @@ from pages.base import BasePage class PartnershipsPage(BasePage): - URL_TEMPLATE = '/{locale}/about/partnerships' + URL_TEMPLATE = '/{locale}/about/partnerships/' _first_name_locator = (By.ID, 'first_name') _last_name_locator = (By.ID, 'last_name') diff --git a/tests/pages/plugincheck.py b/tests/pages/plugincheck.py index c9d725b612..f9188960ee 100644 --- a/tests/pages/plugincheck.py +++ b/tests/pages/plugincheck.py @@ -9,7 +9,7 @@ from pages.base import BasePage class PluginCheckPage(BasePage): - URL_TEMPLATE = '/{locale}/plugincheck' + URL_TEMPLATE = '/{locale}/plugincheck/' _not_supported_message_locator = (By.ID, 'not-supported-container') diff --git a/tests/pages/regions/modal.py b/tests/pages/regions/modal.py index 30f7136e8d..d08c829261 100644 --- a/tests/pages/regions/modal.py +++ b/tests/pages/regions/modal.py @@ -19,7 +19,7 @@ class Modal(Region): @property def is_displayed(self): - return self.is_element_displayed(*self._root_locator) + return self.page.is_element_displayed(*self._root_locator) def displays(self, selector): return self.is_element_displayed(*selector) diff --git a/tests/pages/regions/newsletter.py b/tests/pages/regions/newsletter.py index fb14d9e6a0..2f17a0addd 100644 --- a/tests/pages/regions/newsletter.py +++ b/tests/pages/regions/newsletter.py @@ -23,7 +23,7 @@ class NewsletterEmbedForm(Region): def expand_form(self): # scroll newsletter into view before expanding the form - self.scroll_element_into_view(*self._root_locator) + self.page.scroll_element_into_view(*self._root_locator) assert not self.is_form_detail_displayed, 'Form detail is already displayed' # Click the submit button to expand the form when not visible. # Ideally here we would focus on the email field, but Selenium has issues diff --git a/tests/pages/regions/send_to_device.py b/tests/pages/regions/send_to_device.py index f1c334139f..671f75b34c 100644 --- a/tests/pages/regions/send_to_device.py +++ b/tests/pages/regions/send_to_device.py @@ -29,4 +29,4 @@ class SendToDevice(FirefoxBaseRegion): @property def is_displayed(self): - return self.is_element_displayed(*self._root_locator) + return self.page.is_element_displayed(*self._root_locator) diff --git a/tests/pages/smarton/base.py b/tests/pages/smarton/base.py index 7c5e3b735e..383863a00c 100644 --- a/tests/pages/smarton/base.py +++ b/tests/pages/smarton/base.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class SmartOnBasePage(BasePage): - URL_TEMPLATE = '/{locale}/teach/smarton/{slug}' + URL_TEMPLATE = '/{locale}/teach/smarton/{slug}/' _download_button_locator = (By.ID, 'smarton-foot-download') diff --git a/tests/pages/smarton/landing.py b/tests/pages/smarton/landing.py index 3285fd6c3c..2b2b6f9c34 100644 --- a/tests/pages/smarton/landing.py +++ b/tests/pages/smarton/landing.py @@ -9,7 +9,7 @@ from pages.smarton.base import SmartOnBasePage class SmartOnLandingPage(SmartOnBasePage): - URL_TEMPLATE = '/{locale}/teach/smarton' + URL_TEMPLATE = '/{locale}/teach/smarton/' _topic_tracking_locator = (By.CSS_SELECTOR, '#topic-tracking > a') _topic_security_locator = (By.CSS_SELECTOR, '#topic-security > a') diff --git a/tests/pages/styleguide.py b/tests/pages/styleguide.py index 1f21940fd0..90008b35ff 100644 --- a/tests/pages/styleguide.py +++ b/tests/pages/styleguide.py @@ -10,7 +10,7 @@ from pages.base import BasePage class StyleGuidePage(BasePage): - URL_TEMPLATE = '/{locale}/styleguide' + URL_TEMPLATE = '/{locale}/styleguide/' _sidebar_locator = (By.CSS_SELECTOR, '#sidebar nav > ul > .has-children') diff --git a/tests/pages/technology.py b/tests/pages/technology.py index f24f5c4b73..585e8122e4 100644 --- a/tests/pages/technology.py +++ b/tests/pages/technology.py @@ -9,7 +9,7 @@ from pages.base import BasePage class TechnologyPage(BasePage): - URL_TEMPLATE = '/{locale}/technology' + URL_TEMPLATE = '/{locale}/technology/' _blog_feed_locator = (By.ID, 'blogs') _blog_feed_articles_locator = (By.CSS_SELECTOR, '#blogs article') diff --git a/tests/pages/thunderbird/channel.py b/tests/pages/thunderbird/channel.py index 11d3bc22fd..bf865e6d94 100644 --- a/tests/pages/thunderbird/channel.py +++ b/tests/pages/thunderbird/channel.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class ThunderbirdChannelPage(BasePage): - URL_TEMPLATE = '/{locale}/thunderbird/channel' + URL_TEMPLATE = '/{locale}/thunderbird/channel/' _beta_download_button_locator = (By.ID, 'download-button-desktop-beta') diff --git a/tests/pages/thunderbird/thunderbird.py b/tests/pages/thunderbird/thunderbird.py index a5dba7d29d..172d31fcc5 100644 --- a/tests/pages/thunderbird/thunderbird.py +++ b/tests/pages/thunderbird/thunderbird.py @@ -10,7 +10,7 @@ from pages.regions.download_button import DownloadButton class ThunderbirdPage(BasePage): - URL_TEMPLATE = '/{locale}/thunderbird' + URL_TEMPLATE = '/{locale}/thunderbird/' _download_button_locator = (By.ID, 'download-button-desktop-release')