From 17ef2378a51829d1dd44a745665335972f994969 Mon Sep 17 00:00:00 2001 From: jsfehler Date: Fri, 14 Jun 2024 12:12:05 -0400 Subject: [PATCH] Use pytest fixtures to setup browser, split up chrome and firefox jobs (#1299) --- .github/workflows/main.yml | 5 +- tests/conftest.py | 38 +++++++++++ tests/test_webdriver_chrome.py | 4 +- tests/test_webdriver_edge_chromium.py | 4 +- tests/test_webdriver_firefox.py | 63 ++---------------- .../test_firefox_capabilities.py | 14 ++++ .../test_firefox_extension.py | 36 +++++++++++ .../test_firefox_preferences.py | 23 +++++++ .../test_async_finder.py | 29 ++------- .../test_element_is_visible.py | 37 +++-------- .../test_html_snapshot.py | 21 ++---- tests/{ => tests_webdriver}/test_iframes.py | 21 ++---- .../test_mouse_interaction.py | 27 ++------ tests/{ => tests_webdriver}/test_popups.py | 64 ++++--------------- .../{ => tests_webdriver}/test_screenshot.py | 43 ++++--------- .../{ => tests_webdriver}/test_shadow_root.py | 19 ++---- tests/{ => tests_webdriver}/test_webdriver.py | 24 +++---- tox.ini | 15 +++-- 18 files changed, 207 insertions(+), 280 deletions(-) create mode 100644 tests/tests_firefox_webdriver/test_firefox_capabilities.py create mode 100644 tests/tests_firefox_webdriver/test_firefox_extension.py create mode 100644 tests/tests_firefox_webdriver/test_firefox_preferences.py rename tests/{ => tests_webdriver}/test_async_finder.py (50%) rename tests/{ => tests_webdriver}/test_element_is_visible.py (58%) rename tests/{ => tests_webdriver}/test_html_snapshot.py (53%) rename tests/{ => tests_webdriver}/test_iframes.py (65%) rename tests/{ => tests_webdriver}/test_mouse_interaction.py (72%) rename tests/{ => tests_webdriver}/test_popups.py (58%) rename tests/{ => tests_webdriver}/test_screenshot.py (55%) rename tests/{ => tests_webdriver}/test_shadow_root.py (60%) rename tests/{ => tests_webdriver}/test_webdriver.py (66%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 350d98848..e6e6a4301 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,7 +91,7 @@ jobs: xvfb-run java -jar selenium-server.jar standalone > selenium-server.log 2>&1 & timeout 60 bash -c 'while ! wget -O /dev/null -T 1 http://localhost:4444/readyz; do echo waiting for selenium server; sleep 1; done' || (cat selenium-server.log && exit 2) echo "Selenium server is ready, running tests" - tox -e tests_selenium + tox -e tests_selenium_remote tests_selenium: runs-on: ubuntu-latest @@ -122,4 +122,5 @@ jobs: - name: Run Selenium tests run: | - tox -e tests_selenium -- -n 4; + tox -e tests_selenium_firefox -- -n 4; + tox -e tests_selenium_chrome -- -n 4; diff --git a/tests/conftest.py b/tests/conftest.py index aabf9edf2..effd5dd41 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,6 +9,10 @@ from tests.fake_webapp import start_flask_app from tests.get_browser import get_browser +import splinter +from splinter import Browser +from splinter.config import Config + class Env: def __init__(self): @@ -75,3 +79,37 @@ def new_browser(browser_name): return browser return new_browser + + +def pytest_addoption(parser): + group = parser.getgroup( + "splinter", + "splinter integration", + ) + group.addoption( + "--browser", + help="Name of the browser to use.", + type=str, + choices=list(splinter.browser._DRIVERS.keys()), + dest="browser_name", + ) + + +@pytest.fixture(scope="session") +def browser_name(request) -> str: + return request.config.option.browser_name + + +@pytest.fixture(scope="session") +def browser_config(): + return Config(headless=True) + + +@pytest.fixture(scope="session") +def browser_kwargs(): + return {} + + +@pytest.fixture(scope="function") +def browser(browser_name, browser_config, browser_kwargs): + return Browser(browser_name, config=browser_config, **browser_kwargs) diff --git a/tests/test_webdriver_chrome.py b/tests/test_webdriver_chrome.py index 81925881b..6cefc6387 100644 --- a/tests/test_webdriver_chrome.py +++ b/tests/test_webdriver_chrome.py @@ -13,7 +13,7 @@ class TestChromeBrowser(WebDriverTests): @pytest.fixture(autouse=True, scope="class") def setup_browser(self, request): - config = Config(fullscreen=False) + config = Config(fullscreen=False, headless=True) request.cls.browser = get_browser("chrome", config=config) request.addfinalizer(request.cls.browser.quit) @@ -26,7 +26,7 @@ def visit_example_app(self, request): class TestChromeBrowserFullscreen(WebDriverTests): @pytest.fixture(autouse=True, scope="class") def setup_browser(self, request): - config = Config(fullscreen=True) + config = Config(fullscreen=True, headless=True) request.cls.browser = get_browser("chrome", config=config) request.addfinalizer(request.cls.browser.quit) diff --git a/tests/test_webdriver_edge_chromium.py b/tests/test_webdriver_edge_chromium.py index fdbdc1ab9..66ce3d184 100644 --- a/tests/test_webdriver_edge_chromium.py +++ b/tests/test_webdriver_edge_chromium.py @@ -13,7 +13,7 @@ class TestEdgeChromiumBrowser(WebDriverTests): @pytest.fixture(autouse=True, scope="class") def setup_browser(self, request): - config = Config(fullscreen=False) + config = Config(fullscreen=False, headless=True) request.cls.browser = get_browser("edge", config=config) request.addfinalizer(request.cls.browser.quit) @@ -26,7 +26,7 @@ def visit_example_app(self, request): class TestEdgeChromiumBrowserFullscreen(WebDriverTests): @pytest.fixture(autouse=True, scope="class") def setup_browser(self, request): - config = Config(fullscreen=True) + config = Config(fullscreen=True, headless=True) request.cls.browser = get_browser("edge", config=config) request.addfinalizer(request.cls.browser.quit) diff --git a/tests/test_webdriver_firefox.py b/tests/test_webdriver_firefox.py index f7c09ea3c..20f476a9d 100644 --- a/tests/test_webdriver_firefox.py +++ b/tests/test_webdriver_firefox.py @@ -1,13 +1,11 @@ # Copyright 2013 splinter authors. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -import os - import pytest -from .base import get_browser -from .base import WebDriverTests -from .fake_webapp import EXAMPLE_APP +from tests.base import get_browser +from tests.base import WebDriverTests +from tests.fake_webapp import EXAMPLE_APP from splinter.config import Config @@ -15,7 +13,7 @@ class TestFirefoxBrowser(WebDriverTests): @pytest.fixture(autouse=True, scope="class") def setup_browser(self, request): - config = Config(fullscreen=False) + config = Config(fullscreen=False, headless=True) request.cls.browser = get_browser("firefox", config=config) request.addfinalizer(request.cls.browser.quit) @@ -27,59 +25,10 @@ def visit_example_app(self, request): class TestFirefoxBrowserFullScreen(WebDriverTests): @pytest.fixture(autouse=True, scope="class") def setup_browser(self, request): - config = Config(fullscreen=True) + config = Config(fullscreen=True, headless=True) request.cls.browser = get_browser("firefox", config=config) request.addfinalizer(request.cls.browser.quit) @pytest.fixture(autouse=True) - def visit_example_app(self): + def visit_example_app(self, request): self.browser.visit(EXAMPLE_APP) - - -def test_firefox_create_instance_with_extension(request): - """Test: Load an extension via selenium. - - The dummy extension should add a red border to any web page. - """ - extension_path = os.path.join( - os.path.abspath(os.path.dirname(__file__)), - "dummy_extension", - "borderify-1.0-an+fx.xpi", - ) - - config = Config(extensions=[extension_path]) - browser = get_browser("firefox", config=config) - request.addfinalizer(browser.quit) - - browser.visit(EXAMPLE_APP) - - elem = browser.find_by_css("body") - elem.is_visible(wait_time=20) - style = elem._element.get_attribute("style") - - assert "border: 5px solid red;" == style - - -def test_preference_set(request): - preferences = { - "dom.max_script_run_time": 213, - "devtools.inspector.enabled": True, - } - browser = get_browser("firefox", profile_preferences=preferences) - request.addfinalizer(browser.quit) - - # Rip the preferences out of firefox's config page - browser.visit("about:config") - browser.find_by_id("warningButton").click() - browser.find_by_id("about-config-search").fill("dom.max_script_run_time") - elem = browser.find_by_xpath("//table[@id='prefs']/tr[1]/td[1]/span/span") - assert elem.value == "213" - - -def test_capabilities_set(request): - browser = get_browser("firefox", capabilities={"pageLoadStrategy": "eager"}) - request.addfinalizer(browser.quit) - - capabilities = browser.driver.capabilities - assert "pageLoadStrategy" in capabilities - assert "eager" == capabilities.get("pageLoadStrategy") diff --git a/tests/tests_firefox_webdriver/test_firefox_capabilities.py b/tests/tests_firefox_webdriver/test_firefox_capabilities.py new file mode 100644 index 000000000..591bf20b5 --- /dev/null +++ b/tests/tests_firefox_webdriver/test_firefox_capabilities.py @@ -0,0 +1,14 @@ +import pytest + + +@pytest.fixture(scope="session") +def browser_kwargs(): + return {"capabilities": {"pageLoadStrategy": "eager"}} + + +def test_capabilities_set(request, browser): + request.addfinalizer(browser.quit) + + capabilities = browser.driver.capabilities + assert "pageLoadStrategy" in capabilities + assert "eager" == capabilities.get("pageLoadStrategy") diff --git a/tests/tests_firefox_webdriver/test_firefox_extension.py b/tests/tests_firefox_webdriver/test_firefox_extension.py new file mode 100644 index 000000000..3243e35d9 --- /dev/null +++ b/tests/tests_firefox_webdriver/test_firefox_extension.py @@ -0,0 +1,36 @@ +import os +import pathlib + +import pytest + +from tests.fake_webapp import EXAMPLE_APP + +from splinter.config import Config + + +@pytest.fixture(scope="session") +def browser_config(): + extension_path = pathlib.Path( + os.getcwd(), # NOQA PTH109 + "tests", + "dummy_extension", + "borderify-1.0-an+fx.xpi", + ) + + return Config(extensions=[str(extension_path)], headless=True) + + +def test_firefox_create_instance_with_extension(request, browser): + """Test: Load an extension via selenium. + + The dummy extension should add a red border to any web page. + """ + request.addfinalizer(browser.quit) + + browser.visit(EXAMPLE_APP) + + elem = browser.find_by_css("body") + elem.is_visible(wait_time=20) + + style = elem._element.get_attribute("style") + assert "border: 5px solid red;" == style diff --git a/tests/tests_firefox_webdriver/test_firefox_preferences.py b/tests/tests_firefox_webdriver/test_firefox_preferences.py new file mode 100644 index 000000000..3375a2579 --- /dev/null +++ b/tests/tests_firefox_webdriver/test_firefox_preferences.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.fixture(scope="session") +def browser_kwargs(): + prefs = { + "profile_preferences": { + "dom.max_script_run_time": 213, + "devtools.inspector.enabled": True, + }, + } + return prefs + + +def test_preference_set(request, browser): + request.addfinalizer(browser.quit) + + # Rip the preferences out of firefox's config page + browser.visit("about:config") + browser.find_by_id("warningButton").click() + browser.find_by_id("about-config-search").fill("dom.max_script_run_time") + elem = browser.find_by_xpath("//table[@id='prefs']/tr[1]/td[1]/span/span") + assert elem.value == "213" diff --git a/tests/test_async_finder.py b/tests/tests_webdriver/test_async_finder.py similarity index 50% rename from tests/test_async_finder.py rename to tests/tests_webdriver/test_async_finder.py index 5ac7a9c75..79f3dc4a1 100644 --- a/tests/test_async_finder.py +++ b/tests/tests_webdriver/test_async_finder.py @@ -1,15 +1,10 @@ # Copyright 2012 splinter authors. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -import pytest +from tests.fake_webapp import EXAMPLE_APP -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP - -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_find_by_css_should_found_an_async_element(get_new_browser, browser_name): - browser = get_new_browser(browser_name) +def test_find_by_css_should_found_an_async_element(browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() @@ -18,9 +13,7 @@ def test_find_by_css_should_found_an_async_element(get_new_browser, browser_name assert 1 == len(elements) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_find_by_xpath_should_found_an_async_element(get_new_browser, browser_name): - browser = get_new_browser(browser_name) +def test_find_by_xpath_should_found_an_async_element(browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() @@ -29,9 +22,7 @@ def test_find_by_xpath_should_found_an_async_element(get_new_browser, browser_na assert 1 == len(elements) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_find_by_tag_should_found_an_async_element(get_new_browser, browser_name): - browser = get_new_browser(browser_name) +def test_find_by_tag_should_found_an_async_element(browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() @@ -40,9 +31,7 @@ def test_find_by_tag_should_found_an_async_element(get_new_browser, browser_name assert 1 == len(elements) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_find_by_id_should_found_an_async_element(get_new_browser, browser_name): - browser = get_new_browser(browser_name) +def test_find_by_id_should_found_an_async_element(browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() @@ -51,9 +40,7 @@ def test_find_by_id_should_found_an_async_element(get_new_browser, browser_name) assert 1 == len(elements) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_find_by_name_should_found_an_async_element(get_new_browser, browser_name): - browser = get_new_browser(browser_name) +def test_find_by_name_should_found_an_async_element(browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() @@ -62,9 +49,7 @@ def test_find_by_name_should_found_an_async_element(get_new_browser, browser_nam assert 1 == len(elements) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_find_by_value_should_found_an_async_element(get_new_browser, browser_name): - browser = get_new_browser(browser_name) +def test_find_by_value_should_found_an_async_element(browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() diff --git a/tests/test_element_is_visible.py b/tests/tests_webdriver/test_element_is_visible.py similarity index 58% rename from tests/test_element_is_visible.py rename to tests/tests_webdriver/test_element_is_visible.py index 6ff7d27c3..c8cc1e225 100644 --- a/tests/test_element_is_visible.py +++ b/tests/tests_webdriver/test_element_is_visible.py @@ -3,77 +3,60 @@ # license that can be found in the LICENSE file. import time -import pytest +from tests.fake_webapp import EXAMPLE_APP -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP - -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_visible(browser_name, get_new_browser): +def test_element_is_visible(browser): """WebDriverElement.is_visible() should verify if element is visible.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) browser.find_by_css(".show-invisible-element").click() assert browser.find_by_css("#invisible").is_visible() -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_visible_custom_wait_time(browser_name, get_new_browser): +def test_element_is_visible_custom_wait_time(browser): """WebDriverElement.is_visible()'s wait_time argument should be respected.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) browser.find_by_css(".show-invisible-element").click() assert browser.find_by_css("#invisible").is_visible(wait_time=12) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_visible_return_false(browser_name, get_new_browser): +def test_element_is_visible_return_false(browser): """WebDriverElement.is_visible() should return False if element is not visible.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) assert not browser.find_by_css("#invisible").is_visible() -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_not_visible(browser_name, get_new_browser): +def test_element_is_not_visible(browser): """WebDriverElement.is_not_visible() should verify if element is not visible.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) assert browser.find_by_css("#invisible").is_not_visible() -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_not_visible_return_false(browser_name, get_new_browser): +def test_element_is_not_visible_return_false(browser): """WebDriverElement.is_not_visible() should return False if element is visible.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) browser.find_by_css(".show-invisible-element").click() assert not browser.find_by_css("#invisible").is_not_visible() -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_not_visible_custom_wait_time(browser_name, get_new_browser): +def test_element_is_not_visible_custom_wait_time(browser): """WebDriverElement.is_not_visible()'s wait_time argument should be respected.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) assert browser.find_by_css("#invisible").is_not_visible(wait_time=12) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_visible_element_removed(browser_name, get_new_browser): +def test_element_is_visible_element_removed(browser): """ Given an element has been found When it is removed from the page Then the is_visible() method for this element will return False """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) elem = browser.find_by_css("#removed_after_5_seconds") @@ -84,14 +67,12 @@ def test_element_is_visible_element_removed(browser_name, get_new_browser): assert not elem.is_visible() -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_is_not_visible_element_removed(browser_name, get_new_browser): +def test_element_is_not_visible_element_removed(browser): """ Given an element has been found When it is removed from the page Then the is_not_visible() method for this element will return True """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) elem = browser.find_by_css("#removed_after_5_seconds") diff --git a/tests/test_html_snapshot.py b/tests/tests_webdriver/test_html_snapshot.py similarity index 53% rename from tests/test_html_snapshot.py rename to tests/tests_webdriver/test_html_snapshot.py index 9fef5ef55..f05a7cdce 100644 --- a/tests/test_html_snapshot.py +++ b/tests/tests_webdriver/test_html_snapshot.py @@ -1,18 +1,13 @@ import os import tempfile -import pytest +from tests.fake_webapp import EXAMPLE_APP -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP - -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_snapshot_no_unique_file(get_new_browser, browser_name): +def test_take_snapshot_no_unique_file(browser): """When the unique_file parameter is false, Then the filename should match the name parameter exactly. """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) browser.html_snapshot(name="test_html_snap", unique_file=False) @@ -20,30 +15,24 @@ def test_take_snapshot_no_unique_file(get_new_browser, browser_name): assert os.path.isfile(expected_filepath) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_html_snapshot(get_new_browser, browser_name): +def test_html_snapshot(browser): """Should take an html snapshot of the current page.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.html_snapshot() assert tempfile.gettempdir() in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_html_snapshot_with_prefix(get_new_browser, browser_name): +def test_html_snapshot_with_prefix(browser): """Should add the prefix to the snapshot filename""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.html_snapshot(name="foobar") assert "foobar" in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_html_snapshot_with_suffix(get_new_browser, browser_name): +def test_html_snapshot_with_suffix(browser): """Should add the suffix to the snapshot filename""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.html_snapshot(suffix="xml") diff --git a/tests/test_iframes.py b/tests/tests_webdriver/test_iframes.py similarity index 65% rename from tests/test_iframes.py rename to tests/tests_webdriver/test_iframes.py index c4aabd470..0cc02080f 100644 --- a/tests/test_iframes.py +++ b/tests/tests_webdriver/test_iframes.py @@ -1,16 +1,11 @@ # Copyright 2012 splinter authors. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -import pytest +from tests.fake_webapp import EXAMPLE_APP -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP - -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_can_work_on_iframes_by_name(get_new_browser, browser_name): +def test_can_work_on_iframes_by_name(browser): """can work on iframes and switch back to the page""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) with browser.get_iframe("iframemodal-name") as frame: @@ -21,10 +16,8 @@ def test_can_work_on_iframes_by_name(get_new_browser, browser_name): assert "Example Header" == value -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_can_work_on_iframes_by_id(get_new_browser, browser_name): +def test_can_work_on_iframes_by_id(browser): """can work on iframes and switch back to the page""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) with browser.get_iframe("iframemodal") as frame: @@ -35,10 +28,8 @@ def test_can_work_on_iframes_by_id(get_new_browser, browser_name): assert "Example Header" == value -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_can_work_on_iframes_by_webelement(get_new_browser, browser_name): +def test_can_work_on_iframes_by_webelement(browser): """can work on iframes and switch back to the page""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) elem = browser.find_by_id("iframemodal").first @@ -51,10 +42,8 @@ def test_can_work_on_iframes_by_webelement(get_new_browser, browser_name): assert "Example Header" == value -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_can_work_on_iframes_by_index(get_new_browser, browser_name): +def test_can_work_on_iframes_by_index(browser): """can work on iframes and switch back to the page""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) with browser.get_iframe(0) as frame: diff --git a/tests/test_mouse_interaction.py b/tests/tests_webdriver/test_mouse_interaction.py similarity index 72% rename from tests/test_mouse_interaction.py rename to tests/tests_webdriver/test_mouse_interaction.py index d82c101c0..fa029f8b4 100644 --- a/tests/test_mouse_interaction.py +++ b/tests/tests_webdriver/test_mouse_interaction.py @@ -5,15 +5,12 @@ import pytest -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP +from tests.fake_webapp import EXAMPLE_APP @pytest.mark.flaky -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_mouse_over(browser_name, get_new_browser): +def test_mouse_over(browser): "Should be able to perform a mouse over on an element" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) element = browser.find_by_css(".add-element-mouseover") @@ -29,10 +26,8 @@ def test_mouse_over(browser_name, get_new_browser): @pytest.mark.flaky -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_mouse_out(browser_name, get_new_browser): +def test_mouse_out(browser): "Should be able to perform a mouse out on an element" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) element = browser.find_by_css(".add-element-mouseover") @@ -43,12 +38,10 @@ def test_mouse_out(browser_name, get_new_browser): @pytest.mark.flaky -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_mouse_out_top_left(browser_name, get_new_browser): +def test_mouse_out_top_left(browser): """Should be able to perform a mouse out on an element, even if the element is at the top left corner of the screen. """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP + "/mouse") element = browser.find_by_css(".add-element-mouseover") @@ -59,14 +52,12 @@ def test_mouse_out_top_left(browser_name, get_new_browser): @pytest.mark.flaky -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_double_click(browser_name, get_new_browser): +def test_double_click(browser): """Test: WebDriverElement.double_click() When an element has an action activated by a double click Then using the double_click() method will trigger it """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) button = browser.find_by_css(".db-button", wait_time=10) @@ -82,10 +73,8 @@ def test_double_click(browser_name, get_new_browser): @pytest.mark.flaky -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_right_click(browser_name, get_new_browser): +def test_right_click(browser): "should be able to perform a right click on an element" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) element = browser.find_by_css(".right-clicable") @@ -99,12 +88,10 @@ def test_right_click(browser_name, get_new_browser): @pytest.mark.flaky -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_drag_and_drop(browser_name, get_new_browser): +def test_drag_and_drop(browser): """ should be able to perform a drag an element and drop in another element """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) droppable = browser.find_by_css(".droppable") diff --git a/tests/test_popups.py b/tests/tests_webdriver/test_popups.py similarity index 58% rename from tests/test_popups.py rename to tests/tests_webdriver/test_popups.py index c28e06b6f..99fbcdd59 100644 --- a/tests/test_popups.py +++ b/tests/tests_webdriver/test_popups.py @@ -3,15 +3,10 @@ # license that can be found in the LICENSE file. import time -import pytest +from tests.fake_webapp import EXAMPLE_APP -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP - -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_lists_all_windows_as_window_instances(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_lists_all_windows_as_window_instances(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -30,23 +25,13 @@ def test_lists_all_windows_as_window_instances(browser_name, get_new_browser): assert window.name == handle -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_current_is_a_window_instance_pointing_to_current_window( - browser_name, - get_new_browser, -): - browser = get_new_browser(browser_name) +def test_current_is_a_window_instance_pointing_to_current_window(browser): browser.visit(EXAMPLE_APP) assert browser.windows.current.name == browser.driver.current_window_handle -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_set_current_to_window_instance_sets_current_window( - browser_name, - get_new_browser, -): - browser = get_new_browser(browser_name) +def test_set_current_to_window_instance_sets_current_window(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -55,9 +40,7 @@ def test_set_current_to_window_instance_sets_current_window( assert browser.windows.current != last_current_window -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_next_prev_return_next_prev_windows(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_next_prev_return_next_prev_windows(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -65,12 +48,7 @@ def test_next_prev_return_next_prev_windows(browser_name, get_new_browser): assert browser.windows.current != browser.windows.current.next -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_is_current_returns_true_if_current_window_else_false( - browser_name, - get_new_browser, -): - browser = get_new_browser(browser_name) +def test_is_current_returns_true_if_current_window_else_false(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -81,9 +59,7 @@ def test_is_current_returns_true_if_current_window_else_false( browser.windows.current.close_others() -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_set_is_current_to_true_sets_window_to_current(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_set_is_current_to_true_sets_window_to_current(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -94,18 +70,14 @@ def test_set_is_current_to_true_sets_window_to_current(browser_name, get_new_bro assert next_window.is_current -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_get_window_by_index(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_get_window_by_index(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() assert browser.windows[0].name == browser.driver.window_handles[0] -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_get_window_by_name(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_get_window_by_name(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -113,9 +85,7 @@ def test_get_window_by_name(browser_name, get_new_browser): assert browser.windows[window_handle].name == window_handle -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_close_closes_window(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_close_closes_window(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -125,12 +95,7 @@ def test_close_closes_window(browser_name, get_new_browser): assert browser.windows.current == current -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_close_current_window_expect_previous_window_becomes_current( - browser_name, - get_new_browser, -): - browser = get_new_browser(browser_name) +def test_close_current_window_expect_previous_window_becomes_current(browser): browser.visit(EXAMPLE_APP) browser.find_by_id("open-popup").click() @@ -142,12 +107,7 @@ def test_close_current_window_expect_previous_window_becomes_current( assert browser.windows.current == prev -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_close_others_expect_close_all_other_open_windows( - browser_name, - get_new_browser, -): - browser = get_new_browser(browser_name) +def test_close_others_expect_close_all_other_open_windows(browser): browser.visit(EXAMPLE_APP) current = browser.windows.current diff --git a/tests/test_screenshot.py b/tests/tests_webdriver/test_screenshot.py similarity index 55% rename from tests/test_screenshot.py rename to tests/tests_webdriver/test_screenshot.py index cc37772fa..1d9437c4f 100644 --- a/tests/test_screenshot.py +++ b/tests/tests_webdriver/test_screenshot.py @@ -7,16 +7,13 @@ import pytest from selenium.common.exceptions import WebDriverException -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP +from tests.fake_webapp import EXAMPLE_APP -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_screenshot_no_unique_file(browser_name, get_new_browser): +def test_take_screenshot_no_unique_file(browser): """When the unique_file parameter is false, Then the screenshot filename should match the name parameter exactly. """ - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) browser.screenshot(name="test_screenshot", unique_file=False) @@ -24,49 +21,39 @@ def test_take_screenshot_no_unique_file(browser_name, get_new_browser): assert os.path.isfile(expected_filepath) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_screenshot(browser_name, get_new_browser): +def test_take_screenshot(browser): """Should take a screenshot of the current page""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.screenshot() assert tempfile.gettempdir() in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_screenshot_full_screen(browser_name, get_new_browser): +def test_take_screenshot_full_screen(browser): """Should take a full screen screenshot of the current page""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.screenshot(full=True) assert tempfile.gettempdir() in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_screenshot_with_prefix(browser_name, get_new_browser): +def test_take_screenshot_with_prefix(browser): """Should add the prefix to the screenshot file name""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.screenshot(name="foobar") assert "foobar" in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_screenshot_with_suffix(browser_name, get_new_browser): +def test_take_screenshot_with_suffix(browser): """Should add the suffix to the screenshot file name""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) filename = browser.screenshot(suffix=".png") assert ".png" in filename[-4:] -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_element_screenshot(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_take_element_screenshot(browser): browser.visit(EXAMPLE_APP) elem = browser.find_by_tag("body") @@ -74,10 +61,8 @@ def test_take_element_screenshot(browser_name, get_new_browser): assert tempfile.gettempdir() in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_element_screenshot_with_prefix(browser_name, get_new_browser): +def test_take_element_screenshot_with_prefix(browser): """Should add the prefix to the screenshot file name""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) elem = browser.find_by_tag("body") @@ -85,10 +70,8 @@ def test_take_element_screenshot_with_prefix(browser_name, get_new_browser): assert "foobar" in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_element_screenshot_full_screen(browser_name, get_new_browser): +def test_take_element_screenshot_full_screen(browser): """Should resize the window before taking screenshot of the element""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) elem = browser.find_by_tag("body") @@ -96,9 +79,7 @@ def test_take_element_screenshot_full_screen(browser_name, get_new_browser): assert tempfile.gettempdir() in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_take_nested_element_screenshot(browser_name, get_new_browser): - browser = get_new_browser(browser_name) +def test_take_nested_element_screenshot(browser): browser.visit(EXAMPLE_APP) elem = browser.find_by_tag("body").find_by_css("h1") @@ -106,10 +87,8 @@ def test_take_nested_element_screenshot(browser_name, get_new_browser): assert tempfile.gettempdir() in filename -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_element_screenshot_zero_size(browser_name, get_new_browser): +def test_element_screenshot_zero_size(browser): """Elements with 0 width and 0 height should crash.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) elem = browser.find_by_id("zerodiv") diff --git a/tests/test_shadow_root.py b/tests/tests_webdriver/test_shadow_root.py similarity index 60% rename from tests/test_shadow_root.py rename to tests/tests_webdriver/test_shadow_root.py index 7d9cf64e0..1e6372cf1 100644 --- a/tests/test_shadow_root.py +++ b/tests/tests_webdriver/test_shadow_root.py @@ -1,16 +1,9 @@ -import pytest - -from .fake_webapp import EXAMPLE_APP +from tests.fake_webapp import EXAMPLE_APP from splinter.driver.webdriver import ShadowRootElement -supported_browsers = ["chrome", "chrome_fullscreen"] - - -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_shadow_root(browser_name, get_new_browser): +def test_shadow_root(browser): """The shadow_root property will return a ShadowRootElement.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) element = browser.find_by_id("has_shadow_root") @@ -18,10 +11,8 @@ def test_shadow_root(browser_name, get_new_browser): assert isinstance(shadow_root, ShadowRootElement) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_shadow_root_element_find_by_css(browser_name, get_new_browser): +def test_shadow_root_element_find_by_css(browser): """ShadowRootElement implements ElementAPI.find_by_css.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) element = browser.find_by_id("has_shadow_root") @@ -31,10 +22,8 @@ def test_shadow_root_element_find_by_css(browser_name, get_new_browser): assert "Inside a shadow root" == inner_element.value -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_shadow_root_element_find_by_name(browser_name, get_new_browser): +def test_shadow_root_element_find_by_name(browser): """ShadowRootElement implements ElementAPI.find_by_value.""" - browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) element = browser.find_by_id("has_shadow_root") diff --git a/tests/test_webdriver.py b/tests/tests_webdriver/test_webdriver.py similarity index 66% rename from tests/test_webdriver.py rename to tests/tests_webdriver/test_webdriver.py index 015e07fca..86b399d3d 100644 --- a/tests/test_webdriver.py +++ b/tests/tests_webdriver/test_webdriver.py @@ -1,14 +1,12 @@ import os +import pathlib import pytest from selenium.common.exceptions import WebDriverException -from .base import supported_browsers -from .fake_webapp import EXAMPLE_APP -from .get_browser import get_browser +from tests.fake_webapp import EXAMPLE_APP -@pytest.mark.parametrize("browser_name", ["chrome", "firefox"]) def test_webdriver_local_driver_not_present(browser_name): """When chromedriver/geckodriver are not present on the system.""" from splinter import Browser @@ -25,16 +23,18 @@ def test_webdriver_local_driver_not_present(browser_name): Browser(browser_name, service=service) -@pytest.mark.parametrize("browser_name", supported_browsers) -def test_attach_file(request, browser_name): +def test_attach_file(request, browser): """Should provide a way to change file field value""" - browser = get_browser(browser_name) request.addfinalizer(browser.quit) - file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "mockfile.txt") + file_path = pathlib.Path( + os.getcwd(), # NOQA PTH109 + "tests", + "mockfile.txt", + ) browser.visit(EXAMPLE_APP) - browser.attach_file("file", file_path) + browser.attach_file("file", str(file_path)) browser.find_by_name("upload").click() html = browser.html @@ -44,13 +44,13 @@ def test_attach_file(request, browser_name): assert str(f.read()) in html -@pytest.mark.parametrize("browser_name", supported_browsers) def test_browser_config(request, browser_name): """Splinter's drivers get the Config object when it's passed through the Browser function.""" from splinter import Config + from splinter import Browser - config = Config(user_agent="agent_smith") - browser = get_browser(browser_name, config=config) + config = Config(user_agent="agent_smith", headless=True) + browser = Browser(browser_name, config=config) request.addfinalizer(browser.quit) assert browser.config.user_agent == "agent_smith" diff --git a/tox.ini b/tox.ini index f10fae26c..b3718e620 100644 --- a/tox.ini +++ b/tox.ini @@ -10,19 +10,26 @@ deps = -rrequirements/test.txt commands = pytest --ignore-flaky -v {posargs} tests/test_flaskclient.py tests/test_zopetestbrowser.py tests/test_djangoclient.py tests/test_is_element_present_nojs.py -[testenv:tests_selenium] +[testenv:tests_selenium_firefox] extras = selenium deps = -rrequirements/test.txt commands = - pytest --ignore-flaky -m "not macos" -v {posargs} tests/test_element_is_visible.py tests/test_screenshot.py tests/test_shadow_root.py tests/test_mouse_interaction.py tests/test_async_finder.py tests/test_html_snapshot.py tests/test_iframes.py tests/test_popups.py tests/test_webdriver.py tests/test_webdriver_firefox.py tests/test_webdriver_chrome.py + pytest --ignore-flaky -m "not macos" -v {posargs} --browser=firefox tests/tests_firefox_webdriver tests/tests_webdriver tests/test_webdriver_firefox.py + +[testenv:tests_selenium_chrome] +extras = selenium +deps = + -rrequirements/test.txt +commands = + pytest --ignore-flaky -m "not macos" -v {posargs} --browser=chrome tests/tests_webdriver tests/test_webdriver_chrome.py [testenv:tests_selenium_remote] extras = selenium deps = -rrequirements/test.txt commands = - pytest --ignore-flaky -v {posargs} tests/test_webdriver_remote.py + pytest --ignore-flaky -m "not macos" -v {posargs} tests/test_webdriver_remote.py [testenv:tests_selenium_edge] extras = selenium @@ -31,7 +38,7 @@ deps = passenv = EDGEWEBDRIVER commands = - pytest --ignore-flaky -v {posargs} tests/test_webdriver.py tests/test_popups.py tests/test_webdriver_edge_chromium.py + pytest --ignore-flaky -v {posargs} --browser=edge tests/tests_webdriver tests/test_webdriver_edge_chromium.py [testenv:tests_selenium_safari] extras = selenium