Skip to content
Open
17 changes: 16 additions & 1 deletion py/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ load("@rules_python//python:packaging.bzl", "py_package", "py_wheel")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("@rules_python//sphinxdocs:sphinx.bzl", "sphinx_build_binary", "sphinx_docs")
load("//common:defs.bzl", "copy_file")
load("//py:defs.bzl", "generate_devtools", "py_test_suite")
load("//py:defs.bzl", "generate_devtools", "generate_devtools_latest", "py_test_suite")
load("//py/private:browsers.bzl", "BROWSERS")
load("//py/private:import.bzl", "py_import")

Expand Down Expand Up @@ -291,11 +291,20 @@ py_library(
deps = [
":bidi",
":exceptions",
":latest",
":remote",
requirement("typing_extensions"),
],
)

# Module that points to the latest devtools module
py_library(
name = "latest",
srcs = [":create-latest-devtools"],
imports = ["selenium.webdriver.common.devtools"],
visibility = ["//visibility:public"],
)

# Support utilities (wait conditions, event listeners, etc.)
py_library(
name = "support",
Expand Down Expand Up @@ -438,6 +447,7 @@ py_package(
"py.selenium.webdriver.common",
"py.selenium.webdriver.common.bidi",
"py.selenium.webdriver.common.devtools",
"py.selenium.webdriver.common.devtools.latest",
"py.selenium.webdriver.edge",
"py.selenium.webdriver.firefox",
"py.selenium.webdriver.remote",
Expand Down Expand Up @@ -583,6 +593,11 @@ py_binary(
protocol_version = devtools_version,
) for devtools_version in BROWSER_VERSIONS]

generate_devtools_latest(
name = "create-latest-devtools",
browser_versions = BROWSER_VERSIONS,
)

py_test_suite(
name = "unit",
size = "small",
Expand Down
3 changes: 2 additions & 1 deletion py/defs.bzl
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
load("//py/private:generate_devtools.bzl", _generate_devtools = "generate_devtools")
load("//py/private:generate_devtools.bzl", _generate_devtools = "generate_devtools", _generate_devtools_latest = "generate_devtools_latest")
load("//py/private:import.bzl", _py_import = "py_import")
load("//py/private:pytest.bzl", _pytest_test = "pytest_test")
load("//py/private:suite.bzl", _py_test_suite = "py_test_suite")

generate_devtools = _generate_devtools
generate_devtools_latest = _generate_devtools_latest
pytest_test = _pytest_test
py_import = _py_import
py_test_suite = _py_test_suite
20 changes: 20 additions & 0 deletions py/private/generate_devtools.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,23 @@ generate_devtools = rule(
"deps": attr.label_list(),
},
)

def _generate_latest_impl(ctx):
versions = ctx.attr.browser_versions
latest = "v%s" % max([int(v[1:]) for v in versions])
output_file = ctx.actions.declare_file("selenium/webdriver/common/devtools/latest/__init__.py")
ctx.actions.write(
output = output_file,
content = "from ..%s import *\n" % latest,
)
return [DefaultInfo(
files = depset([output_file]),
runfiles = ctx.runfiles(files = [output_file]),
)]

generate_devtools_latest = rule(
implementation = _generate_latest_impl,
attrs = {
"browser_versions": attr.string_list(mandatory = True),
},
)
2 changes: 1 addition & 1 deletion py/selenium/webdriver/common/bidi/cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def import_devtools(ver):
# Attempt to parse and load the 'most recent' devtools module. This is likely
# because cdp has been updated but selenium python has not been released yet.
devtools_path = pathlib.Path(__file__).parents[1].joinpath("devtools")
versions = tuple(f.name for f in devtools_path.iterdir() if f.is_dir())
versions = tuple(f.name for f in devtools_path.iterdir() if f.is_dir() and f.name != "latest")
latest = max(int(x[1:]) for x in versions)
selenium_logger = logging.getLogger(__name__)
selenium_logger.debug("Falling back to loading `devtools`: v%s", latest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,30 @@
# specific language governing permissions and limitations
# under the License.

import importlib
import logging
import re
import types
from types import ModuleType

from selenium.webdriver.common.bidi.cdp import import_devtools


def test_missing_cdp_devtools_version_falls_back(caplog):
"""This test verifies the most recent devtools module is imported if an unknown devtools version is requested."""
with caplog.at_level(logging.DEBUG, logger="selenium"):
assert isinstance(import_devtools("will_never_exist"), types.ModuleType)
devtools_module = import_devtools("will_never_exist")
assert isinstance(devtools_module, ModuleType)
# assert the fallback occurred successfully offered up a v{n} option.
assert re.match(r"Falling back to loading `devtools`: v\d+", caplog.records[-1].getMessage()) is not None


def test_import_latest_cdp_devtools():
"""This test verifies the `latest` devtools module can be imported and it contains submodules."""
latest_module = importlib.import_module("selenium.webdriver.common.devtools.latest")
assert isinstance(latest_module, ModuleType)
devtools_submodules = [
getattr(latest_module, name)
for name in dir(latest_module)
if isinstance(getattr(latest_module, name), ModuleType)
]
assert len(devtools_submodules) > 1
Loading