load("@aspect_bazel_lib//lib:copy_directory.bzl", "copy_directory") load("@bazel_skylib//rules:select_file.bzl", "select_file") load("@py_dev_requirements//:requirements.bzl", "requirement") load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//pkg:pkg.bzl", "pkg_tar") load("@rules_python//python:defs.bzl", "py_binary", "py_library") load("@rules_python//python:packaging.bzl", "py_package", "py_wheel") load("@rules_python//python:pip.bzl", "compile_pip_requirements") load("//common:defs.bzl", "copy_file") load("//py:defs.bzl", "generate_devtools", "py_test_suite") load("//py/private:browsers.bzl", "BROWSERS") load("//py/private:import.bzl", "py_import") py_binary( name = "selenium-release", srcs = [ "release-selenium.py", ], args = [ "upload", "$(location :selenium-wheel)", "$(location :selenium-sdist)", ], data = [ ":selenium-sdist", ":selenium-wheel", ], main = "release-selenium.py", deps = [ requirement("twine"), ], ) py_binary( name = "selenium-release-nightly", srcs = [ "release-selenium.py", ], args = [ "upload", "--repository", "testpypi", "$(location :selenium-wheel)", "$(location :selenium-sdist)", ], data = [ ":selenium-sdist", ":selenium-wheel", ], main = "release-selenium.py", deps = [ requirement("twine"), ], ) compile_pip_requirements( # base name for generated targets, typically "requirements" name = "requirements", requirements_in = ":requirements.txt", requirements_txt = ":requirements_lock.txt", tags = [ "skip-rbe", # This test won't run on the RBE because of a lack of network connectivity ], ) SE_VERSION = "4.35.0.202507081456" BROWSER_VERSIONS = [ "v137", "v138", "v136", ] TEST_DEPS = [ requirement("attrs"), requirement("debugpy"), requirement("filetype"), requirement("idna"), requirement("iniconfig"), requirement("importlib_metadata"), requirement("h11"), requirement("more-itertools"), requirement("multidict"), requirement("outcome"), requirement("pluggy"), requirement("py"), requirement("pytest"), requirement("pytest-instafail"), requirement("pytest-trio"), requirement("pytest-mock"), requirement("sortedcontainers"), requirement("sniffio"), requirement("zipp"), "@rules_python//python/runfiles", ] copy_file( name = "manager-linux", src = "//common/manager:selenium-manager-linux", out = "selenium/webdriver/common/linux/selenium-manager", ) copy_file( name = "manager-macos", src = "//common/manager:selenium-manager-macos", out = "selenium/webdriver/common/macos/selenium-manager", ) copy_file( name = "manager-windows", src = "//common/manager:selenium-manager-windows", out = "selenium/webdriver/common/windows/selenium-manager.exe", ) copy_file( name = "get-attribute", src = "//javascript/webdriver/atoms:get-attribute.js", out = "selenium/webdriver/remote/getAttribute.js", ) copy_file( name = "is-displayed", src = "//javascript/atoms/fragments:is-displayed.js", out = "selenium/webdriver/remote/isDisplayed.js", ) copy_file( name = "find-elements", src = "//javascript/atoms/fragments:find-elements.js", out = "selenium/webdriver/remote/findElements.js", ) copy_file( name = "mutation-listener", src = "//javascript/cdp-support:mutation-listener.js", out = "selenium/webdriver/common/mutation-listener.js", ) copy_file( name = "firefox-driver-prefs", src = "//third_party/js/selenium:webdriver_json", out = "selenium/webdriver/firefox/webdriver_prefs.json", ) copy_file( name = "webextensions-selenium-example-xpi", src = "//common/extensions:webextensions-selenium-example.xpi", out = "test/extensions/webextensions-selenium-example.xpi", ) copy_file( name = "webextensions-selenium-example-zip", src = "//common/extensions:webextensions-selenium-example.zip", out = "test/extensions/webextensions-selenium-example.zip", ) copy_file( name = "webextensions-selenium-example-unsigned-zip", src = "//common/extensions:webextensions-selenium-example-unsigned.zip", out = "test/extensions/webextensions-selenium-example-unsigned.zip", ) copy_file( name = "webextensions-selenium-example-crx", src = "//common/extensions:webextensions-selenium-example.crx", out = "test/extensions/webextensions-selenium-example.crx", ) copy_directory( name = "webextensions-selenium-example-dir", src = "//common/extensions:webextensions-selenium-example", out = "test/extensions/webextensions-selenium-example", ) copy_directory( name = "webextensions-selenium-example-signed-dir", src = "//common/extensions:webextensions-selenium-example-signed", out = "test/extensions/webextensions-selenium-example-signed", ) select_file( name = "global-license", srcs = "//:license", subpath = "LICENSE", ) copy_file( name = "license", src = ":global-license", out = "LICENSE", ) copy_file( name = "license-wheel", src = ":global-license", out = "selenium-%s.dist-info/LICENSE" % SE_VERSION, ) py_library( name = "selenium", srcs = glob( ["selenium/**/*.py"], exclude = ["generate.py"], ), data = [ "selenium/py.typed", ":find-elements", ":firefox-driver-prefs", ":get-attribute", ":is-displayed", ":manager-linux", ":manager-macos", ":manager-windows", ":mutation-listener", ] + [":create-cdp-srcs-" + n for n in BROWSER_VERSIONS], imports = ["."], visibility = ["//visibility:public"], deps = [ requirement("urllib3"), requirement("trio"), requirement("trio-websocket"), requirement("certifi"), requirement("typing_extensions"), requirement("websocket-client"), ], ) py_package( name = "selenium-pkg", packages = [ "py.selenium", "py.selenium.common", "py.selenium.webdriver", "py.selenium.webdriver.chrome", "py.selenium.webdriver.chromium", "py.selenium.webdriver.common", "py.selenium.webdriver.common.bidi", "py.selenium.webdriver.common.devtools", "py.selenium.webdriver.edge", "py.selenium.webdriver.firefox", "py.selenium.webdriver.remote", "py.selenium.webdriver.safari", ], deps = [":selenium"], ) pkg_files( name = "selenium-sdist-pkg", srcs = [ "CHANGES", "README.rst", "pyproject.toml", ":license", ":selenium-pkg", ":selenium-pkginfo", "//rust:selenium_manager_srcs", ], excludes = [ ":manager-linux", ":manager-macos", ":manager-windows", ], strip_prefix = strip_prefix.from_pkg(), ) pkg_tar( name = "selenium-sdist", srcs = [":selenium-sdist-pkg"], extension = "tar.gz", mode = "0644", package_dir = "selenium-%s" % SE_VERSION, package_file_name = "selenium-%s.tar.gz" % SE_VERSION, ) genrule( name = "selenium-pkginfo", srcs = [":selenium-wheel-lib"], outs = ["PKG-INFO"], cmd = "cp $(location :selenium-wheel-lib)/selenium-%s.dist-info/METADATA $@" % SE_VERSION, ) py_import( name = "selenium-wheel-lib", wheel = ":selenium-wheel", ) py_wheel( name = "selenium-wheel", classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Libraries", "Programming Language :: Python", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", ], description_file = "README.rst", distribution = "selenium", homepage = "https://www.selenium.dev", license = "Apache 2.0", python_requires = ">=3.9", python_tag = "py3", requires = [ "urllib3[socks]~=2.5.0", "trio~=0.30.0", "trio-websocket~=0.12.2", "certifi>=2025.6.15", "typing_extensions~=4.14.0", "websocket-client~=1.8.0", ], strip_path_prefixes = [ "py/", ], summary = "Official Python bindings for Selenium WebDriver", tags = [ "release-artifact", ], version = SE_VERSION, visibility = ["//visibility:public"], deps = [ ":license-wheel", ":selenium-pkg", ], ) py_library( name = "init-tree", testonly = True, srcs = [ "conftest.py", "test/__init__.py", "test/selenium/__init__.py", "test/selenium/webdriver/__init__.py", "test/selenium/webdriver/chrome/__init__.py", "test/selenium/webdriver/common/__init__.py", "test/selenium/webdriver/common/network.py", "test/selenium/webdriver/common/webserver.py", "test/selenium/webdriver/firefox/__init__.py", "test/selenium/webdriver/firefox/conftest.py", "test/selenium/webdriver/marionette/__init__.py", "test/selenium/webdriver/marionette/conftest.py", "test/selenium/webdriver/safari/conftest.py", "test/selenium/webdriver/support/__init__.py", ], data = [ "pyproject.toml", "test/selenium/webdriver/common/test_file.txt", "test/selenium/webdriver/common/test_file2.txt", ":webextensions-selenium-example-crx", ":webextensions-selenium-example-dir", ":webextensions-selenium-example-signed-dir", ":webextensions-selenium-example-unsigned-zip", ":webextensions-selenium-example-xpi", ":webextensions-selenium-example-zip", ], imports = ["."], deps = [ ":webserver", ], ) py_binary( name = "generate", srcs = ["generate.py"], srcs_version = "PY3", deps = [requirement("inflection")], ) [generate_devtools( name = "create-cdp-srcs-{}".format(devtools_version), browser_protocol = "//common/devtools/chromium/{}:browser_protocol".format(devtools_version), generator = ":generate", js_protocol = "//common/devtools/chromium/{}:js_protocol".format(devtools_version), outdir = "selenium/webdriver/common/devtools/{}".format(devtools_version), protocol_version = devtools_version, ) for devtools_version in BROWSER_VERSIONS] py_test_suite( name = "unit", size = "small", srcs = glob([ "test/unit/**/*.py", ]), args = [ "--instafail", ], deps = [ ":init-tree", ":selenium", ] + TEST_DEPS, ) py_library( name = "webserver", testonly = True, srcs = [ "test/selenium/webdriver/common/network.py", "test/selenium/webdriver/common/webserver.py", ], data = [ "//common/src/web", ], deps = [], ) BIDI_TESTS = glob(["test/selenium/webdriver/common/**/*bidi*_tests.py"]) [ py_test_suite( name = "common-%s" % browser, size = "large", srcs = glob( [ "test/selenium/webdriver/common/**/*.py", "test/selenium/webdriver/support/**/*.py", ], exclude = BIDI_TESTS + ["test/selenium/webdriver/common/print_pdf_tests.py"], ), args = [ "--instafail", ] + BROWSERS[browser]["args"], data = BROWSERS[browser]["data"], env_inherit = ["DISPLAY"], tags = ["no-sandbox"] + BROWSERS[browser]["tags"], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) for browser in BROWSERS.keys() ] [ py_test_suite( name = "common-%s-bidi" % browser, size = "large", srcs = glob( [ "test/selenium/webdriver/common/**/*.py", "test/selenium/webdriver/support/**/*.py", ], exclude = ["test/selenium/webdriver/common/print_pdf_tests.py"], ), args = [ "--instafail", "--bidi", ] + BROWSERS[browser]["args"], data = BROWSERS[browser]["data"], env_inherit = ["DISPLAY"], tags = ["no-sandbox"] + BROWSERS[browser]["tags"], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) for browser in BROWSERS.keys() ] py_test_suite( name = "test-chrome", size = "large", srcs = glob( [ "test/selenium/webdriver/chrome/**/*.py", ], exclude = ["test/selenium/webdriver/common/print_pdf_tests.py"], ), args = [ "--instafail", ] + BROWSERS["chrome"]["args"], data = BROWSERS["chrome"]["data"], env_inherit = ["DISPLAY"], tags = [ "no-sandbox", ] + BROWSERS["chrome"]["tags"], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-chrome-headless", size = "large", srcs = glob( [ "test/selenium/webdriver/chrome/**/*.py", ], ), args = [ "--instafail", "--headless", ] + BROWSERS["chrome"]["args"], data = BROWSERS["chrome"]["data"], env_inherit = ["DISPLAY"], tags = [ "no-sandbox", "skip-rbe", ] + BROWSERS["chrome"]["tags"], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-edge", size = "large", srcs = glob([ "test/selenium/webdriver/edge/**/*.py", ]), args = [ "--instafail", ] + BROWSERS["edge"]["args"], data = BROWSERS["edge"]["data"], env_inherit = ["DISPLAY"], tags = [ "no-sandbox", ] + BROWSERS["edge"]["tags"], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-firefox", size = "large", srcs = glob( [ "test/selenium/webdriver/marionette/**/*.py", "test/selenium/webdriver/firefox/**/*.py", ], exclude = ["test/selenium/webdriver/common/devtools_tests.py"], ), args = [ "--instafail", ] + BROWSERS["firefox"]["args"], data = BROWSERS["firefox"]["data"], env_inherit = ["DISPLAY"], tags = [ "no-sandbox", "skip-rbe", ] + BROWSERS["firefox"]["tags"], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-remote", size = "large", srcs = glob( [ "test/selenium/webdriver/common/**/*.py", "test/selenium/webdriver/remote/**/*.py", "test/selenium/webdriver/support/**/*.py", ], exclude = BIDI_TESTS, ), args = [ "--instafail", "--driver=remote", ], data = [ "//java/src/org/openqa/selenium/grid:selenium_server_deploy.jar", ], tags = [ "no-sandbox", "skip-rbe", ], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-ie", size = "large", srcs = glob([ "test/selenium/webdriver/common/**/*.py", "test/selenium/webdriver/ie/**/*.py", "test/selenium/webdriver/support/**/*.py", ]), args = [ "--instafail", "--driver=ie", ], tags = [ "no-sandbox", "skip-rbe", ], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-safari", size = "large", srcs = glob([ "test/selenium/webdriver/safari/**/*.py", ]), args = [ "--instafail", "--driver=safari", ], tags = [ "exclusive-if-local", "no-sandbox", "skip-rbe", ], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-webkitgtk", size = "large", srcs = glob([ "test/selenium/webdriver/common/**/*.py", "test/selenium/webdriver/support/**/*.py", ]), args = [ "--instafail", "--driver=webkitgtk", "--browser-binary=MiniBrowser", "--browser-args=--automation", ], tags = [ "exclusive-if-local", "no-sandbox", "skip-rbe", ], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, ) py_test_suite( name = "test-wpewebkit", size = "large", srcs = glob([ "test/selenium/webdriver/common/**/*.py", "test/selenium/webdriver/support/**/*.py", ]), args = [ "--instafail", "--driver=wpewebkit", "--browser-binary=MiniBrowser", "--browser-args=--automation --headless", ], tags = [ "exclusive-if-local", "no-sandbox", "skip-rbe", ], deps = [ ":init-tree", ":selenium", ":webserver", ] + TEST_DEPS, )