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("@rules_python//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary")
load("//common:defs.bzl", "copy_file")
load("//py:defs.bzl", "generate_devtools", "generate_devtools_latest", "py_test_suite")
load("//py/private:browsers.bzl", "BROWSERS")
load("//py/private:generate_bidi.bzl", "generate_bidi")
load("//py/private:import.bzl", "py_import")
load("//py/private:sphinx_docs.bzl", "sphinx_docs")

exports_files(
    ["pyproject.toml"],
    visibility = ["//py:__subpackages__"],
)

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",
    srcs = [
        "pyproject.toml",
        "requirements.txt",
    ],
    extra_args = ["--no-strip-extras"],
    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.46.0"

BROWSER_VERSIONS = [
    "v149",
    "v150",
    "v148",
]

TEST_DEPS = [
    requirement("filetype"),
    requirement("pytest"),
    requirement("pytest-instafail"),
    requirement("pytest-trio"),
    requirement("pytest-mock"),
    requirement("rich"),
    requirement("zipp"),
    "@rules_python//python/runfiles",
]

genrule(
    name = "java-location",
    srcs = [],
    outs = ["java-location.txt"],
    cmd = "echo $(JAVA) > $@",
    toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"],
)

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/atoms/fragments:get-attribute-typescript.js",
    out = "selenium/webdriver/remote/getAttribute.js",
)

copy_file(
    name = "is-displayed",
    src = "//javascript/atoms/fragments:is-displayed-typescript.js",
    out = "selenium/webdriver/remote/isDisplayed.js",
)

copy_file(
    name = "find-elements",
    src = "//javascript/atoms/fragments:find-elements-typescript.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 = "bidi-mutation-listener",
    src = "//javascript/bidi-support:bidi-mutation-listener.js",
    out = "selenium/webdriver/common/bidi-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",
    testonly = True,
    src = "//common/extensions:webextensions-selenium-example.xpi",
    out = "test/extensions/webextensions-selenium-example.xpi",
)

copy_file(
    name = "webextensions-selenium-example-zip",
    testonly = True,
    src = "//common/extensions:webextensions-selenium-example.zip",
    out = "test/extensions/webextensions-selenium-example.zip",
)

copy_file(
    name = "webextensions-selenium-example-unsigned-zip",
    testonly = True,
    src = "//common/extensions:webextensions-selenium-example-unsigned.zip",
    out = "test/extensions/webextensions-selenium-example-unsigned.zip",
)

copy_file(
    name = "webextensions-selenium-example-crx",
    testonly = True,
    src = "//common/extensions:webextensions-selenium-example.crx",
    out = "test/extensions/webextensions-selenium-example.crx",
)

copy_directory(
    name = "webextensions-selenium-example-dir",
    testonly = True,
    src = "//common/extensions:webextensions-selenium-example",
    out = "test/extensions/webextensions-selenium-example",
)

copy_directory(
    name = "webextensions-selenium-example-signed-dir",
    testonly = True,
    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,
)

select_file(
    name = "global-notice",
    srcs = "//:license",
    subpath = "NOTICE",
)

copy_file(
    name = "notice",
    src = ":global-notice",
    out = "NOTICE",
)

copy_file(
    name = "notice-wheel",
    src = ":global-notice",
    out = "selenium-%s.dist-info/NOTICE" % SE_VERSION,
)

# ==============================================================================
# Module Targets (following Ruby's modular pattern)
# ==============================================================================

# Exceptions and package init (no deps - foundational)
py_library(
    name = "exceptions",
    srcs = [
        "selenium/__init__.py",
        "selenium/webdriver/__init__.py",
    ] + glob(["selenium/common/**/*.py"]),
    data = ["selenium/webdriver/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
)

# Remote/wire protocol (foundational)
py_library(
    name = "remote",
    srcs = glob(["selenium/webdriver/remote/**/*.py"]),
    data = [
        ":find-elements",
        ":get-attribute",
        ":is-displayed",
    ],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":exceptions",
        requirement("certifi"),
        requirement("urllib3"),
        requirement("websocket-client"),
    ],
)

# BiDi protocol support
py_library(
    name = "bidi",
    srcs = [":create-bidi-src"],
    data = [
        ":bidi-mutation-listener",
        ":mutation-listener",
    ],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":exceptions",
        ":remote",
        requirement("trio"),
        requirement("trio-websocket"),
        requirement("websocket-client"),
    ],
)

# Common utilities (shared by all browsers, includes devtools generated code)
py_library(
    name = "common",
    srcs = glob(
        ["selenium/webdriver/common/**/*.py"],
        exclude = [
            "selenium/webdriver/common/action_chains.py",
            "selenium/webdriver/common/actions/**",
            "selenium/webdriver/common/alert.py",
            "selenium/webdriver/common/api_request_context.py",
            "selenium/webdriver/common/bidi/**",
            "selenium/webdriver/common/devtools/**",
            "selenium/webdriver/common/fedcm/**",
            "selenium/webdriver/common/print_page_options.py",
            "selenium/webdriver/common/timeouts.py",
            "selenium/webdriver/common/virtual_authenticator.py",
        ],
    ),
    data = [
        ":manager-linux",
        ":manager-macos",
        ":manager-windows",
    ] + [":create-cdp-srcs-" + n for n in BROWSER_VERSIONS],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":bidi",
        ":exceptions",
        ":latest",
        ":remote",
        requirement("typing_extensions"),
    ],
)

# Input actions API (action_chains + actions subpackage)
py_library(
    name = "common_actions",
    srcs = glob([
        "selenium/webdriver/common/action_chains.py",
        "selenium/webdriver/common/actions/**/*.py",
    ]),
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

py_library(
    name = "common_alert",
    srcs = ["selenium/webdriver/common/alert.py"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

py_library(
    name = "common_api_request_context",
    srcs = ["selenium/webdriver/common/api_request_context.py"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [":exceptions"],
)

py_library(
    name = "common_fedcm",
    srcs = glob(["selenium/webdriver/common/fedcm/**/*.py"]),
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [":exceptions"],
)

py_library(
    name = "common_print_page_options",
    srcs = ["selenium/webdriver/common/print_page_options.py"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [],
)

py_library(
    name = "common_timeouts",
    srcs = ["selenium/webdriver/common/timeouts.py"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [],
)

py_library(
    name = "common_virtual_authenticator",
    srcs = ["selenium/webdriver/common/virtual_authenticator.py"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [":exceptions"],
)

# 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",
    srcs = glob(
        ["selenium/webdriver/support/**/*.py"],
        exclude = ["selenium/webdriver/support/color.py"],
    ),
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":exceptions",
        ":remote",
    ],
)

py_library(
    name = "support_color",
    srcs = ["selenium/webdriver/support/color.py"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [],
)

# Chromium base (shared by Chrome and Edge)
py_library(
    name = "chromium",
    srcs = glob(["selenium/webdriver/chromium/**/*.py"]),
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

# Chrome driver
py_library(
    name = "chrome",
    srcs = glob(["selenium/webdriver/chrome/**/*.py"]),
    data = ["selenium/webdriver/chrome/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [":chromium"],
)

# Edge driver
py_library(
    name = "edge",
    srcs = glob(["selenium/webdriver/edge/**/*.py"]),
    data = ["selenium/webdriver/edge/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [":chromium"],
)

# Firefox driver
py_library(
    name = "firefox",
    srcs = glob(["selenium/webdriver/firefox/**/*.py"]),
    data = [
        "selenium/webdriver/firefox/__init__.pyi",
        ":firefox-driver-prefs",
    ],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

# Safari driver
py_library(
    name = "safari",
    srcs = glob(["selenium/webdriver/safari/**/*.py"]),
    data = ["selenium/webdriver/safari/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

# IE driver
py_library(
    name = "ie",
    srcs = glob(["selenium/webdriver/ie/**/*.py"]),
    data = ["selenium/webdriver/ie/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

# WebKitGTK driver
py_library(
    name = "webkitgtk",
    srcs = glob(["selenium/webdriver/webkitgtk/**/*.py"]),
    data = ["selenium/webdriver/webkitgtk/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

# WPEWebKit driver
py_library(
    name = "wpewebkit",
    srcs = glob(["selenium/webdriver/wpewebkit/**/*.py"]),
    data = ["selenium/webdriver/wpewebkit/__init__.pyi"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":common",
        ":remote",
    ],
)

# ==============================================================================
# Aggregate Target (backwards compatible - includes all modules)
# ==============================================================================

py_library(
    name = "selenium",
    srcs = [],
    data = ["selenium/py.typed"],
    imports = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":bidi",
        ":chrome",
        ":chromium",
        ":common",
        ":common_actions",
        ":common_alert",
        ":common_api_request_context",
        ":common_fedcm",
        ":common_print_page_options",
        ":common_timeouts",
        ":common_virtual_authenticator",
        ":edge",
        ":exceptions",
        ":firefox",
        ":ie",
        ":remote",
        ":safari",
        ":support",
        ":support_color",
        ":webkitgtk",
        ":wpewebkit",
    ],
)

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.common.devtools.latest",
        "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",
        ":notice",
        ":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.10",
        "Programming Language :: Python :: 3.11",
        "Programming Language :: Python :: 3.12",
        "Programming Language :: Python :: 3.13",
        "Programming Language :: Python :: 3.14",
    ],
    description_file = "README.rst",
    distribution = "selenium",
    homepage = "https://www.selenium.dev",
    license = "Apache-2.0",
    python_requires = ">=3.10",
    python_tag = "py3",
    requires = [
        "certifi>=2026.2.25",
        "trio>=0.31.0,<1.0",
        "trio-websocket>=0.12.2,<1.0",
        "typing_extensions>=4.15.0,<5.0",
        "urllib3[socks]>=2.6.3,<3.0",
        "websocket-client>=1.8.0,<2.0",
    ],
    strip_path_prefixes = [
        "py/",
    ],
    summary = "Official Python bindings for Selenium WebDriver",
    tags = [
        "release-artifact",
    ],
    version = SE_VERSION,
    visibility = ["//visibility:public"],
    deps = [
        ":license-wheel",
        ":notice-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/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")],
)

py_binary(
    name = "generate_bidi",
    srcs = ["generate_bidi.py"],
    srcs_version = "PY3",
)

[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]

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

# Generate BiDi source files from CDDL specification.
# extra_cddl_files are merged with the primary WebDriver BiDi spec before
# generation so that end users get the full set of BiDi-adjacent modules.
generate_bidi(
    name = "create-bidi-src",
    cddl_file = "@webdriver_bidi_all_cddl//file:spec.cddl",
    enhancements_manifest = "//py/private:bidi_enhancements_manifest.py",
    extra_cddl_files = [
        "@permissions_all_cddl//file:spec.cddl",
        "@prefetch_all_cddl//file:spec.cddl",
        "@ua_client_hints_all_cddl//file:spec.cddl",
        "@web_bluetooth_all_cddl//file:spec.cddl",
    ],
    extra_srcs = [
        "//py/private:_event_manager.py",
        "//py/private:_network_handlers.py",
        "//py/private:_script_handlers.py",
        "//py/private:cdp.py",
    ],
    generator = ":generate_bidi",
    merge_tool = "//py/private:merge_cddl",
    module_name = "selenium/webdriver/common/bidi",
    spec_version = "1.0",
)

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"])

# Test files that only run against browsers supporting the given feature.
# Each group is split into its own sub-suite so that changing the underlying
# library only triggers that group's targets, not the full ~700-target suite.
FEDCM_TESTS = ["test/selenium/webdriver/common/fedcm_tests.py"]

TIMEOUTS_TESTS = ["test/selenium/webdriver/common/timeout_tests.py"]

VIRTUAL_AUTH_TESTS = ["test/selenium/webdriver/common/virtual_authenticator_tests.py"]

API_REQUEST_TESTS = ["test/selenium/webdriver/common/api_request_context_tests.py"]

# alerts_tests.py and webdriverwait_tests.py both call driver.switch_to.alert,
# requiring :common_alert at runtime, so they share a sub-suite.
ALERT_TESTS = [
    "test/selenium/webdriver/common/alerts_tests.py",
    "test/selenium/webdriver/common/webdriverwait_tests.py",
]

# rendered_webelement_tests.py is the only browser test that imports Color.
RENDERED_WEBELEMENT_TESTS = ["test/selenium/webdriver/common/rendered_webelement_tests.py"]

FEATURE_TESTS = (
    FEDCM_TESTS +
    TIMEOUTS_TESTS +
    VIRTUAL_AUTH_TESTS +
    API_REQUEST_TESTS +
    ALERT_TESTS +
    RENDERED_WEBELEMENT_TESTS
)

# Test files that import from selenium.webdriver.common.actions / action_chains.
# These are kept separate so they can depend on :common_actions without pulling
# that library into every other test suite.
ACTIONS_TESTS = [
    "test/selenium/webdriver/common/interactions_tests.py",
    "test/selenium/webdriver/common/interactions_with_device_tests.py",
    "test/selenium/webdriver/common/w3c_interaction_tests.py",
    "test/selenium/webdriver/support/event_firing_webdriver_tests.py",
]

DRIVER_FINDER_TESTS = ["test/selenium/webdriver/common/driver_finder_tests.py"]

# Browser-specific test configuration
BROWSER_TESTS = {
    "chrome": {
        "browser_srcs": ["test/selenium/webdriver/chrome/**/*.py"],
        "deps": [
            ":chrome",
            ":common",
            ":support",
        ],
        "actions_deps": [
            ":chrome",
            ":common_actions",
            ":support",
        ],
        "bidi": True,
    },
    "edge": {
        "browser_srcs": ["test/selenium/webdriver/edge/**/*.py"],
        "deps": [
            ":edge",
            ":common",
            ":support",
        ],
        "actions_deps": [
            ":edge",
            ":common_actions",
            ":support",
        ],
        "bidi": True,
    },
    "firefox": {
        "browser_srcs": [
            "test/selenium/webdriver/firefox/**/*.py",
        ],
        "deps": [
            ":firefox",
            ":common",
            ":support",
        ],
        "actions_deps": [
            ":firefox",
            ":common_actions",
            ":support",
        ],
        "extra_excludes": ["test/selenium/webdriver/common/devtools_tests.py"],
        "bidi": True,
    },
    "ie": {
        "browser_srcs": ["test/selenium/webdriver/ie/**/*.py"],
        "deps": [
            ":ie",
            ":common",
            ":support",
        ],
        "actions_deps": [
            ":ie",
            ":common_actions",
            ":support",
        ],
    },
    "safari": {
        "browser_srcs": ["test/selenium/webdriver/safari/**/*.py"],
        "deps": [
            ":safari",
            ":common",
            ":support",
        ],
        "actions_deps": [
            ":safari",
            ":common_actions",
            ":support",
        ],
    },
}

DEFAULT_BROWSER_TESTS = [b for b in BROWSER_TESTS if b != "ie"]

# Generate test-<browser>-common targets (non-bidi, non-actions)
[
    py_test_suite(
        name = "test-%s-common" % browser,
        size = "large",
        srcs = glob(
            [
                "test/selenium/webdriver/common/**/*.py",
                "test/selenium/webdriver/support/**/*.py",
            ] + BROWSER_TESTS[browser]["browser_srcs"],
            exclude = BIDI_TESTS + ACTIONS_TESTS + FEATURE_TESTS + DRIVER_FINDER_TESTS + ["test/selenium/webdriver/common/print_pdf_tests.py"] +
                      BROWSER_TESTS[browser].get("extra_excludes", []),
        ),
        args = [
            "--instafail",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        tags = ["no-sandbox"] + BROWSERS[browser]["tags"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = browser,
        deps = [
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
]

# Generate test-<browser>-actions targets (non-bidi, actions tests only)
[
    py_test_suite(
        name = "test-%s-actions" % browser,
        size = "large",
        srcs = ACTIONS_TESTS,
        args = [
            "--instafail",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        tags = ["no-sandbox"] + BROWSERS[browser]["tags"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = "%s-actions" % browser,
        deps = [
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["actions_deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
]

# Feature test definitions: suffix -> (srcs, dep)
FEATURE_SUITE_DEFS = {
    "fedcm": (FEDCM_TESTS, ":common_fedcm"),
    "timeouts": (TIMEOUTS_TESTS, ":common_timeouts"),
    "virtual-auth": (VIRTUAL_AUTH_TESTS, ":common_virtual_authenticator"),
    "api-request": (API_REQUEST_TESTS, ":common_api_request_context"),
    "alerts": (ALERT_TESTS, ":common_alert"),
    "rendered": (RENDERED_WEBELEMENT_TESTS, ":support_color"),
}

# Generate test-<browser>-<feature> targets (non-bidi, one per feature library)
[
    py_test_suite(
        name = "test-%s-%s" % (browser, feature),
        size = "large",
        srcs = FEATURE_SUITE_DEFS[feature][0],
        args = [
            "--instafail",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        tags = ["no-sandbox"] + BROWSERS[browser]["tags"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = "%s-%s" % (browser, feature),
        deps = [
            ":init-tree",
            ":webserver",
            FEATURE_SUITE_DEFS[feature][1],
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
    for feature in FEATURE_SUITE_DEFS
]

# Aggregate test-<browser> = common + actions + features (keeps CI targets unchanged)
[test_suite(
    name = "test-%s" % browser,
    tests = [
        ":test-%s-common" % browser,
        ":test-%s-actions" % browser,
    ] + [":test-%s-%s" % (browser, f) for f in FEATURE_SUITE_DEFS],
) for browser in DEFAULT_BROWSER_TESTS]

[
    py_test_suite(
        name = "test-%s-driver-finder" % browser,
        size = "large",
        srcs = DRIVER_FINDER_TESTS,
        args = [
            "--instafail",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        flaky = True,
        tags = BROWSERS[browser]["tags"] + ["se-manager"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = browser,
        deps = [
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
]

# Generate test-<browser>-bidi-common targets
[
    py_test_suite(
        name = "test-%s-bidi-common" % browser,
        size = "large",
        srcs = glob(
            [
                "test/selenium/webdriver/common/**/*.py",
                "test/selenium/webdriver/support/**/*.py",
            ] + BROWSER_TESTS[browser]["browser_srcs"],
            exclude = ACTIONS_TESTS + FEATURE_TESTS + DRIVER_FINDER_TESTS + ["test/selenium/webdriver/common/print_pdf_tests.py"] +
                      BROWSER_TESTS[browser].get("extra_excludes", []),
        ),
        args = [
            "--instafail",
            "--bidi",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        tags = ["no-sandbox"] + BROWSERS[browser]["tags"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = "%s-bidi" % browser,
        deps = [
            ":common_alert",  # bidi_browsing_context_tests.py calls EC.alert_is_present()
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
    if BROWSER_TESTS[browser].get("bidi", False)
]

# Generate test-<browser>-bidi-actions targets
[
    py_test_suite(
        name = "test-%s-bidi-actions" % browser,
        size = "large",
        srcs = ACTIONS_TESTS,
        args = [
            "--instafail",
            "--bidi",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        tags = ["no-sandbox"] + BROWSERS[browser]["tags"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = "%s-bidi-actions" % browser,
        deps = [
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["actions_deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
    if BROWSER_TESTS[browser].get("bidi", False)
]

# Generate test-<browser>-bidi-<feature> targets
[
    py_test_suite(
        name = "test-%s-bidi-%s" % (browser, feature),
        size = "large",
        srcs = FEATURE_SUITE_DEFS[feature][0],
        args = [
            "--instafail",
            "--bidi",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"],
        env_inherit = ["DISPLAY"],
        tags = ["no-sandbox"] + BROWSERS[browser]["tags"],
        target_compatible_with = BROWSERS[browser]["target_compatible_with"],
        test_suffix = "%s-bidi-%s" % (browser, feature),
        deps = [
            ":init-tree",
            ":webserver",
            FEATURE_SUITE_DEFS[feature][1],
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in DEFAULT_BROWSER_TESTS
    for feature in FEATURE_SUITE_DEFS
    if BROWSER_TESTS[browser].get("bidi", False)
]

# Aggregate test-<browser>-bidi = bidi-common + bidi-actions + bidi-features
[test_suite(
    name = "test-%s-bidi" % browser,
    tests = [
        ":test-%s-bidi-common" % browser,
        ":test-%s-bidi-actions" % browser,
    ] + [":test-%s-bidi-%s" % (browser, f) for f in FEATURE_SUITE_DEFS],
) for browser in DEFAULT_BROWSER_TESTS if BROWSER_TESTS[browser].get("bidi", False)]

# Generate test-<browser>-remote-common targets (chrome and firefox only)
[
    py_test_suite(
        name = "test-%s-remote-common" % browser,
        size = "large",
        srcs = glob(
            [
                "test/selenium/webdriver/common/**/*.py",
                "test/selenium/webdriver/remote/**/*.py",
                "test/selenium/webdriver/support/**/*.py",
            ] + BROWSER_TESTS[browser]["browser_srcs"],
            exclude = BIDI_TESTS + ACTIONS_TESTS + FEATURE_TESTS + DRIVER_FINDER_TESTS + ["test/selenium/webdriver/common/print_pdf_tests.py"] +
                      BROWSER_TESTS[browser].get("extra_excludes", []),
        ),
        args = [
            "--instafail",
            "--remote",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"] + [
            ":java-location",
            "//java/src/org/openqa/selenium/grid:selenium_server_deploy.jar",
            "@bazel_tools//tools/jdk:current_java_runtime",
        ],
        env = {
            "SE_BAZEL_JAVA_LOCATION": "$(rootpath :java-location)",
        },
        env_inherit = ["DISPLAY"],
        tags = [
            "no-sandbox",
            "remote",
            "%s-remote" % browser,
        ],
        test_suffix = "%s-remote" % browser,
        deps = [
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in [
        "chrome",
        "firefox",
    ]
]

# Generate test-<browser>-remote-actions targets (chrome and firefox only)
[
    py_test_suite(
        name = "test-%s-remote-actions" % browser,
        size = "large",
        srcs = ACTIONS_TESTS,
        args = [
            "--instafail",
            "--remote",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"] + [
            ":java-location",
            "//java/src/org/openqa/selenium/grid:selenium_server_deploy.jar",
            "@bazel_tools//tools/jdk:current_java_runtime",
        ],
        env = {
            "SE_BAZEL_JAVA_LOCATION": "$(rootpath :java-location)",
        },
        env_inherit = ["DISPLAY"],
        tags = [
            "no-sandbox",
            "remote",
            "%s-remote" % browser,
        ],
        test_suffix = "%s-remote-actions" % browser,
        deps = [
            ":init-tree",
            ":webserver",
        ] + BROWSER_TESTS[browser]["actions_deps"] + TEST_DEPS,
    )
    for browser in [
        "chrome",
        "firefox",
    ]
]

# Generate test-<browser>-remote-<feature> targets (chrome and firefox only)
[
    py_test_suite(
        name = "test-%s-remote-%s" % (browser, feature),
        size = "large",
        srcs = FEATURE_SUITE_DEFS[feature][0],
        args = [
            "--instafail",
            "--remote",
        ] + BROWSERS[browser]["args"],
        data = BROWSERS[browser]["data"] + [
            ":java-location",
            "//java/src/org/openqa/selenium/grid:selenium_server_deploy.jar",
            "@bazel_tools//tools/jdk:current_java_runtime",
        ],
        env = {
            "SE_BAZEL_JAVA_LOCATION": "$(rootpath :java-location)",
        },
        env_inherit = ["DISPLAY"],
        tags = [
            "no-sandbox",
            "remote",
            "%s-remote" % browser,
        ],
        test_suffix = "%s-remote-%s" % (browser, feature),
        deps = [
            ":init-tree",
            ":webserver",
            FEATURE_SUITE_DEFS[feature][1],
        ] + BROWSER_TESTS[browser]["deps"] + TEST_DEPS,
    )
    for browser in [
        "chrome",
        "firefox",
    ]
    for feature in FEATURE_SUITE_DEFS
]

# Aggregate test-<browser>-remote = remote-common + remote-actions + remote-features
[test_suite(
    name = "test-%s-remote" % browser,
    tests = [
        ":test-%s-remote-common" % browser,
        ":test-%s-remote-actions" % browser,
    ] + [":test-%s-remote-%s" % (browser, f) for f in FEATURE_SUITE_DEFS],
) for browser in [
    "chrome",
    "firefox",
]]

test_suite(
    name = "test-remote",
    tags = ["remote"],
    tests = [
        ":test-chrome-remote",
        ":test-firefox-remote",
    ],
)

py_test_suite(
    name = "test-webkitgtk-common",
    size = "large",
    srcs = glob(
        [
            "test/selenium/webdriver/common/**/*.py",
            "test/selenium/webdriver/support/**/*.py",
        ],
        exclude = BIDI_TESTS + ACTIONS_TESTS + FEATURE_TESTS + DRIVER_FINDER_TESTS,
    ),
    args = [
        "--instafail",
        "--driver=webkitgtk",
        "--browser-binary=MiniBrowser",
        "--browser-args=--automation",
    ],
    tags = [
        "exclusive-if-local",
        "no-sandbox",
        "skip-rbe",
    ],
    test_suffix = "webkitgtk",
    deps = [
        ":common",
        ":init-tree",
        ":support",
        ":webkitgtk",
        ":webserver",
    ] + TEST_DEPS,
)

py_test_suite(
    name = "test-webkitgtk-actions",
    size = "large",
    srcs = ACTIONS_TESTS,
    args = [
        "--instafail",
        "--driver=webkitgtk",
        "--browser-binary=MiniBrowser",
        "--browser-args=--automation",
    ],
    tags = [
        "exclusive-if-local",
        "no-sandbox",
        "skip-rbe",
    ],
    test_suffix = "webkitgtk-actions",
    deps = [
        ":common_actions",
        ":init-tree",
        ":support",
        ":webkitgtk",
        ":webserver",
    ] + TEST_DEPS,
)

[
    py_test_suite(
        name = "test-webkitgtk-%s" % feature,
        size = "large",
        srcs = FEATURE_SUITE_DEFS[feature][0],
        args = [
            "--instafail",
            "--driver=webkitgtk",
            "--browser-binary=MiniBrowser",
            "--browser-args=--automation",
        ],
        tags = [
            "exclusive-if-local",
            "no-sandbox",
            "skip-rbe",
        ],
        test_suffix = "webkitgtk-%s" % feature,
        deps = [
            ":init-tree",
            ":support",
            ":webkitgtk",
            ":webserver",
            FEATURE_SUITE_DEFS[feature][1],
        ] + TEST_DEPS,
    )
    for feature in FEATURE_SUITE_DEFS
]

test_suite(
    name = "test-webkitgtk",
    tests = [
        ":test-webkitgtk-actions",
        ":test-webkitgtk-common",
    ] + [":test-webkitgtk-%s" % f for f in FEATURE_SUITE_DEFS],
)

py_test_suite(
    name = "test-wpewebkit-common",
    size = "large",
    srcs = glob(
        [
            "test/selenium/webdriver/common/**/*.py",
            "test/selenium/webdriver/support/**/*.py",
        ],
        exclude = BIDI_TESTS + ACTIONS_TESTS + FEATURE_TESTS + DRIVER_FINDER_TESTS,
    ),
    args = [
        "--instafail",
        "--driver=wpewebkit",
        "--browser-binary=MiniBrowser",
        "--browser-args=--automation --headless",
    ],
    tags = [
        "exclusive-if-local",
        "no-sandbox",
        "skip-rbe",
    ],
    test_suffix = "wpewebkit",
    deps = [
        ":common",
        ":init-tree",
        ":support",
        ":webserver",
        ":wpewebkit",
    ] + TEST_DEPS,
)

py_test_suite(
    name = "test-wpewebkit-actions",
    size = "large",
    srcs = ACTIONS_TESTS,
    args = [
        "--instafail",
        "--driver=wpewebkit",
        "--browser-binary=MiniBrowser",
        "--browser-args=--automation --headless",
    ],
    tags = [
        "exclusive-if-local",
        "no-sandbox",
        "skip-rbe",
    ],
    test_suffix = "wpewebkit-actions",
    deps = [
        ":common_actions",
        ":init-tree",
        ":support",
        ":webserver",
        ":wpewebkit",
    ] + TEST_DEPS,
)

[
    py_test_suite(
        name = "test-wpewebkit-%s" % feature,
        size = "large",
        srcs = FEATURE_SUITE_DEFS[feature][0],
        args = [
            "--instafail",
            "--driver=wpewebkit",
            "--browser-binary=MiniBrowser",
            "--browser-args=--automation --headless",
        ],
        tags = [
            "exclusive-if-local",
            "no-sandbox",
            "skip-rbe",
        ],
        test_suffix = "wpewebkit-%s" % feature,
        deps = [
            ":init-tree",
            ":support",
            ":webserver",
            ":wpewebkit",
            FEATURE_SUITE_DEFS[feature][1],
        ] + TEST_DEPS,
    )
    for feature in FEATURE_SUITE_DEFS
]

test_suite(
    name = "test-wpewebkit",
    tests = [
        ":test-wpewebkit-actions",
        ":test-wpewebkit-common",
    ] + [":test-wpewebkit-%s" % f for f in FEATURE_SUITE_DEFS],
)

py_binary(
    name = "generate-api-listing",
    srcs = ["generate_api_module_listing.py"],
    main = "generate_api_module_listing.py",
    deps = [":selenium"],
)

py_binary(
    name = "sphinx-autogen",
    srcs = ["run_sphinx_autogen.py"],
    main = "run_sphinx_autogen.py",
    deps = [
        ":selenium",
        requirement("sphinx"),
    ],
)

py_console_script_binary(
    name = "sphinx-build",
    pkg = "@py_dev_requirements//sphinx",
    script = "sphinx-build",
    deps = [
        ":selenium",
        requirement("sphinx-material"),
    ],
)

sphinx_docs(
    name = "docs",
    srcs = glob(["docs/source/**/*.rst"]),
    config = "docs/source/conf.py",
    sphinx = ":sphinx-build",
)

py_binary(
    name = "mypy",
    srcs = ["run_mypy.py"],
    data = [
        "pyproject.toml",
        ":selenium",
    ],
    main = "run_mypy.py",
    deps = [
        ":selenium",
        requirement("mypy"),
    ],
)

alias(
    name = "ruff",
    actual = "//py/private:ruff",
)

alias(
    name = "ruff-check",
    actual = "//py/private:ruff_check",
)

alias(
    name = "ruff-format",
    actual = "//py/private:ruff_format",
)
