Skip to content

[py] Re-enable remote tests in bazel and fix broken tests #15657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions py/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,6 @@ py_library(
"test/selenium/webdriver/__init__.py",
"test/selenium/webdriver/chrome/__init__.py",
"test/selenium/webdriver/common/__init__.py",
"test/selenium/webdriver/common/conftest.py",
"test/selenium/webdriver/common/network.py",
"test/selenium/webdriver/common/webserver.py",
"test/selenium/webdriver/firefox/__init__.py",
Expand All @@ -330,7 +329,6 @@ py_library(
"test/selenium/webdriver/marionette/conftest.py",
"test/selenium/webdriver/safari/conftest.py",
"test/selenium/webdriver/support/__init__.py",
"test/selenium/webdriver/support/conftest.py",
],
data = [
"pyproject.toml",
Expand Down Expand Up @@ -547,6 +545,7 @@ py_test_suite(
srcs = glob(
[
"test/selenium/webdriver/common/**/*.py",
"test/selenium/webdriver/remote/**/*.py",
"test/selenium/webdriver/support/**/*.py",
],
exclude = BIDI_TESTS,
Expand Down
29 changes: 25 additions & 4 deletions py/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ def pytest_ignore_collect(path, config):
return len([d for d in _drivers if d.lower() in parts]) > 0


def pytest_generate_tests(metafunc):
if "driver" in metafunc.fixturenames and metafunc.config.option.drivers:
metafunc.parametrize("driver", metafunc.config.option.drivers, indirect=True)


def get_driver_class(driver_option):
"""Generate the driver class name from the lowercase driver option."""
if driver_option == "webkitgtk":
Expand All @@ -113,20 +118,29 @@ def get_driver_class(driver_option):
@pytest.fixture(scope="function")
def driver(request):
kwargs = {}
driver_option = getattr(request, "param", "Chrome")

# browser can be changed with `--driver=firefox` as an argument or to addopts in pytest.ini
driver_class = get_driver_class(getattr(request, "param", "Chrome"))
# skip tests if not available on the platform
driver_class = get_driver_class(driver_option)

# skip tests in the 'remote' directory if run with a local driver
if request.node.path.parts[-2] == "remote" and driver_class != "Remote":
pytest.skip(f"Remote tests can't be run with driver '{driver_option}'")

# skip tests that can't run on certain platforms
_platform = platform.system()
if driver_class == "Safari" and _platform != "Darwin":
pytest.skip("Safari tests can only run on an Apple OS")
if (driver_class == "Ie") and _platform != "Windows":
pytest.skip("IE and EdgeHTML Tests can only run on Windows")
if "WebKit" in driver_class and _platform == "Windows":
pytest.skip("WebKit tests cannot be run on Windows")

# skip tests for drivers that don't support BiDi when --bidi is enabled
if request.config.option.bidi:
if driver_class in ("Ie", "Safari", "WebKitGTK", "WPEWebKit"):
pytest.skip(f"{driver_class} does not support BiDi")

# conditionally mark tests as expected to fail based on driver
marker = request.node.get_closest_marker(f"xfail_{driver_class.lower()}")

Expand Down Expand Up @@ -177,6 +191,7 @@ def fin():
kwargs["options"] = options

driver_instance = getattr(webdriver, driver_class)(**kwargs)

yield driver_instance
# Close the browser after BiDi tests. Those make event subscriptions
# and doesn't seems to be stable enough, causing the flakiness of the
Expand Down Expand Up @@ -217,7 +232,6 @@ def get_options(driver_class, config):
if headless:
if not options:
options = getattr(webdriver, f"{driver_class}Options")()

if driver_class == "Chrome" or driver_class == "Edge":
options.add_argument("--headless=new")
if driver_class == "Firefox":
Expand All @@ -226,7 +240,6 @@ def get_options(driver_class, config):
if bidi:
if not options:
options = getattr(webdriver, f"{driver_class}Options")()

options.web_socket_url = True
options.unhandled_prompt_behavior = "ignore"

Expand Down Expand Up @@ -382,3 +395,11 @@ def clean_driver(request):

if request.node.get_closest_marker("no_driver_after_test"):
driver_reference = None


@pytest.fixture
def firefox_options(request):
options = webdriver.FirefoxOptions()
if request.config.option.headless:
options.add_argument("-headless")
return options
21 changes: 0 additions & 21 deletions py/test/selenium/webdriver/chrome/conftest.py

This file was deleted.

21 changes: 0 additions & 21 deletions py/test/selenium/webdriver/common/conftest.py

This file was deleted.

21 changes: 0 additions & 21 deletions py/test/selenium/webdriver/edge/conftest.py

This file was deleted.

22 changes: 4 additions & 18 deletions py/test/selenium/webdriver/firefox/firefox_sizing_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,27 @@
import pytest

from selenium import webdriver
from selenium.webdriver.firefox.options import Options


def is_running_wayland():
return platform.system() == "Linux" and os.getenv("WAYLAND_DISPLAY")


@pytest.mark.skipif(not is_running_wayland(), reason="This test only runs on Linux under Wayland")
def test_firefox_opens_large_when_running_xwayland(request): # noqa: F821
options = Options()
if request.config.getoption("--headless"):
options.add_argument("-headless")
def test_firefox_opens_large_when_running_xwayland(firefox_options):
# setting environment variable `MOZ_ENABLE_WAYLAND=0` forces Firefox
# to run under XWayland on Wayland based systems
with patch.dict("os.environ", {"MOZ_ENABLE_WAYLAND": "0"}):
try:
driver = webdriver.Firefox(options=options)
with webdriver.Firefox(options=firefox_options) as driver:
size = driver.get_window_size()
assert size["height"] > 500
assert size["width"] > 500
finally:
driver.quit()


@pytest.mark.skipif(not is_running_wayland(), reason="This test only runs on Linux under Wayland")
@pytest.mark.xfail(reason="https://bugzilla.mozilla.org/show_bug.cgi?id=1959040")
# Firefox opens in a small window when running on Linux/Wayland
def test_firefox_opens_large_when_running_wayland(request): # noqa: F821
options = Options()
if request.config.getoption("--headless"):
options.add_argument("-headless")
try:
driver = webdriver.Firefox(options=options)
def test_firefox_opens_large_when_running_wayland(firefox_options):
with webdriver.Firefox(options=firefox_options) as driver:
size = driver.get_window_size()
assert size["height"] > 500
assert size["width"] > 500
finally:
driver.quit()
2 changes: 2 additions & 0 deletions py/test/selenium/webdriver/remote/remote_connection_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

import base64

import filetype


def test_browser_specific_method(driver, pages):
"""This only works on Firefox"""
pages.load("simpleTest.html")
screenshot = driver.execute("FULL_PAGE_SCREENSHOT")["value"]
result = base64.b64decode(screenshot)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

import pytest

from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement

Expand All @@ -24,20 +27,27 @@ def custom_method(self):
return "Custom element method"


def test_find_element_with_custom_class(driver, pages):
@pytest.fixture()
def custom_element_driver(driver):
try:
driver._web_element_cls = MyCustomElement
yield driver
finally:
driver._web_element_cls = WebElement


def test_find_element_with_custom_class(custom_element_driver, pages):
"""Test to ensure custom element class is used for a single element."""
driver._web_element_cls = MyCustomElement
pages.load("simpleTest.html")
element = driver.find_element(By.TAG_NAME, "body")
element = custom_element_driver.find_element(By.TAG_NAME, "body")
assert isinstance(element, MyCustomElement)
assert element.custom_method() == "Custom element method"


def test_find_elements_with_custom_class(driver, pages):
def test_find_elements_with_custom_class(custom_element_driver, pages):
"""Test to ensure custom element class is used for multiple elements."""
driver._web_element_cls = MyCustomElement
pages.load("simpleTest.html")
elements = driver.find_elements(By.TAG_NAME, "div")
elements = custom_element_driver.find_elements(By.TAG_NAME, "div")
assert all(isinstance(el, MyCustomElement) for el in elements)
assert all(el.custom_method() == "Custom element method" for el in elements)

Expand Down
25 changes: 19 additions & 6 deletions py/test/selenium/webdriver/remote/remote_custom_locator_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

import pytest

from selenium import webdriver
from selenium.webdriver.remote.locator_converter import LocatorConverter


Expand All @@ -25,16 +29,25 @@ def convert(self, by, value):
return super().convert(by, value)


def test_find_element_with_custom_locator(driver):
driver.get("data:text/html,<div custom-attr='example'>Test</div>")
element = driver.find_element("custom", "example")
@pytest.fixture()
def custom_locator_driver(firefox_options):
driver = webdriver.Remote(options=firefox_options, locator_converter=CustomLocatorConverter())
yield driver
driver.quit()


def test_find_element_with_custom_locator(custom_locator_driver):
custom_locator_driver.get("data:text/html,<div custom-attr='example'>Test</div>")
element = custom_locator_driver.find_element("custom", "example")
assert element is not None
assert element.text == "Test"


def test_find_elements_with_custom_locator(driver):
driver.get("data:text/html,<div custom-attr='example'>Test1</div><div custom-attr='example'>Test2</div>")
elements = driver.find_elements("custom", "example")
def test_find_elements_with_custom_locator(custom_locator_driver):
custom_locator_driver.get(
"data:text/html,<div custom-attr='example'>Test1</div><div custom-attr='example'>Test2</div>"
)
elements = custom_locator_driver.find_elements("custom", "example")
assert len(elements) == 2
assert elements[0].text == "Test1"
assert elements[1].text == "Test2"
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

import os
import tempfile

Expand Down
27 changes: 7 additions & 20 deletions py/test/selenium/webdriver/remote/remote_firefox_profile_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,13 @@
# specific language governing permissions and limitations
# under the License.

import pytest

from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile


@pytest.fixture
def driver(options):
with pytest.warns(None) as record:
driver = webdriver.Remote(options=options)
assert len(record) == 0
yield driver
driver.quit()


@pytest.fixture
def options():
options = webdriver.FirefoxOptions()
options.set_preference("browser.startup.homepage", "about:")
return options


def test_profile_is_used(driver):
assert "about:blank" == driver.current_url or "about:" == driver.current_url
def test_profile_is_used(firefox_options):
ff_profile = FirefoxProfile()
ff_profile.set_preference("browser.startup.page", "1")
firefox_options.profile = ff_profile
with webdriver.Remote(options=firefox_options) as driver:
assert "browser/content/blanktab.html" in driver.current_url
8 changes: 6 additions & 2 deletions py/test/selenium/webdriver/remote/remote_hub_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@
import urllib3

from selenium import webdriver
from selenium.webdriver.firefox.options import Options


def test_command_executor_ssl_certificate_is_verified():
options = Options()
site = "wrong.host.badssl.com"
with pytest.raises(urllib3.exceptions.MaxRetryError) as excinfo:
webdriver.Remote(command_executor="https://wrong.host.badssl.com/")
webdriver.Remote(command_executor="https://wrong.host.badssl.com/", options=options)
assert isinstance(excinfo.value.reason, urllib3.exceptions.SSLError)
assert "doesn't match" in str(excinfo.value)
assert site in str(excinfo.value)
assert "certificate is not valid" in str(excinfo.value).lower()
21 changes: 0 additions & 21 deletions py/test/selenium/webdriver/support/conftest.py

This file was deleted.

Loading