diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 4b37354af5361..2bfde171c39d8 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -158,7 +158,7 @@ jobs: shell: pwsh run: ./scripts/github-actions/delete-browsers-drivers.ps1 - name: Free disk space - if: inputs.os == 'ubuntu' + if: contains(inputs.os, 'ubuntu') shell: bash run: | . ./scripts/github-actions/disk-status.sh @@ -209,7 +209,7 @@ jobs: shell: bash run: . ./scripts/github-actions/disk-status.sh - name: Setup Fluxbox and Xvfb - if: inputs.needs-display && inputs.os == 'ubuntu' + if: inputs.needs-display && contains(inputs.os, 'ubuntu') run: | sudo apt-get update && sudo apt-get -y install fluxbox x11-utils Xvfb :99 & diff --git a/.github/workflows/ci-ruby.yml b/.github/workflows/ci-ruby.yml index e98e22151d2a0..11c785f0e1a06 100644 --- a/.github/workflows/ci-ruby.yml +++ b/.github/workflows/ci-ruby.yml @@ -57,10 +57,12 @@ jobs: strategy: fail-fast: false matrix: + os: [ubuntu, windows, macos] + tag_filters: ["unit,os-sensitive,se-manager,skip-rbe"] include: - - os: ubuntu - - os: windows - - os: macos + # Chrome has no linux-arm64 build before 153; Edge has none at all. + - os: ubuntu-24.04-arm + tag_filters: "unit,os-sensitive,se-manager,skip-rbe,-chrome,-edge" with: name: ${{ matrix.os }} needs-display: true @@ -78,7 +80,7 @@ jobs: --test_env=SE_FORCE_BROWSER_DOWNLOAD=true --test_env=SE_SKIP_DRIVER_IN_PATH=true --test_env=SKIP_PENDING=true - --test_tag_filters=unit,os-sensitive,se-manager,skip-rbe + --test_tag_filters=${{ matrix.tag_filters }} --target_pattern_file=bazel-targets-rb.txt os-tests-full: diff --git a/.github/workflows/ci-rust.yml b/.github/workflows/ci-rust.yml index 82b89e085fed7..da2cfcfdc3c27 100644 --- a/.github/workflows/ci-rust.yml +++ b/.github/workflows/ci-rust.yml @@ -112,11 +112,11 @@ jobs: - arch: x86_64 runner: ubuntu-latest target: x86_64-unknown-linux-musl - artifact: selenium-manager-linux + artifact: selenium-manager-linux-x86_64 - arch: aarch64 runner: ubuntu-24.04-arm target: aarch64-unknown-linux-musl - artifact: selenium-manager-linux-aarch64 + artifact: selenium-manager-linux-arm64 steps: - name: "Checkout project" uses: actions/checkout@v6 @@ -156,11 +156,11 @@ jobs: - arch: x86_64 runner: ubuntu-latest target: x86_64-unknown-linux-musl - artifact: selenium-manager-linux-debug + artifact: selenium-manager-linux-x86_64-debug - arch: aarch64 runner: ubuntu-24.04-arm target: aarch64-unknown-linux-musl - artifact: selenium-manager-linux-aarch64-debug + artifact: selenium-manager-linux-arm64-debug steps: - name: "Checkout project" uses: actions/checkout@v6 @@ -308,13 +308,13 @@ jobs: path: artifacts - name: "Prepare and Commit" run: | - linux_sha=$(shasum -a 256 artifacts/selenium-manager-linux/selenium-manager-linux | awk '{print $1}') - linux_aarch64_sha=$(shasum -a 256 artifacts/selenium-manager-linux-aarch64/selenium-manager-linux-aarch64 | awk '{print $1}') + linux_x86_64_sha=$(shasum -a 256 artifacts/selenium-manager-linux-x86_64/selenium-manager-linux-x86_64 | awk '{print $1}') + linux_arm64_sha=$(shasum -a 256 artifacts/selenium-manager-linux-arm64/selenium-manager-linux-arm64 | awk '{print $1}') macos_sha=$(shasum -a 256 artifacts/selenium-manager-macos/selenium-manager-macos | awk '{print $1}') windows_sha=$(shasum -a 256 artifacts/selenium-manager-windows/selenium-manager-windows.exe | awk '{print $1}') sbom_sha=$(shasum -a 256 artifacts/selenium-manager-sbom/selenium-manager.cdx.json | awk '{print $1}') notice_sha=$(shasum -a 256 artifacts/selenium-manager-sbom/selenium-manager-THIRD-PARTY-NOTICES.txt | awk '{print $1}') - echo "{\"macos\": \"$macos_sha\", \"windows\": \"$windows_sha\", \"linux\": \"$linux_sha\", \"linux-aarch64\": \"$linux_aarch64_sha\", \"sbom\": \"$sbom_sha\", \"notice\": \"$notice_sha\"}" > latest.json + echo "{\"macos\": \"$macos_sha\", \"windows\": \"$windows_sha\", \"linux-x86_64\": \"$linux_x86_64_sha\", \"linux-arm64\": \"$linux_arm64_sha\", \"sbom\": \"$sbom_sha\", \"notice\": \"$notice_sha\"}" > latest.json git config --local user.email "selenium-ci@users.noreply.github.com" git config --local user.name "Selenium CI Bot" git add latest.json @@ -332,12 +332,12 @@ jobs: draft: false prerelease: false files: | - artifacts/selenium-manager-linux/selenium-manager-linux - artifacts/selenium-manager-linux-aarch64/selenium-manager-linux-aarch64 + artifacts/selenium-manager-linux-x86_64/selenium-manager-linux-x86_64 + artifacts/selenium-manager-linux-arm64/selenium-manager-linux-arm64 artifacts/selenium-manager-macos/selenium-manager-macos artifacts/selenium-manager-windows/selenium-manager-windows.exe - artifacts/selenium-manager-linux-debug/selenium-manager-linux-debug.tar - artifacts/selenium-manager-linux-aarch64-debug/selenium-manager-linux-aarch64-debug.tar + artifacts/selenium-manager-linux-x86_64-debug/selenium-manager-linux-x86_64-debug.tar + artifacts/selenium-manager-linux-arm64-debug/selenium-manager-linux-arm64-debug.tar artifacts/selenium-manager-macos-debug/selenium-manager-macos-debug.tar artifacts/selenium-manager-windows-debug/selenium-manager-windows-debug.exe artifacts/selenium-manager-sbom/selenium-manager.cdx.json diff --git a/MODULE.bazel b/MODULE.bazel index 72a6953ddd248..05af8ee973a8d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -455,7 +455,8 @@ use_repo(crate, "crates") selenium_manager_artifacts = use_extension("//common:selenium_manager.bzl", "selenium_manager_artifacts") use_repo( selenium_manager_artifacts, - "download_sm_linux", + "download_sm_linux_arm64", + "download_sm_linux_x86_64", "download_sm_macos", "download_sm_notice", "download_sm_sbom", diff --git a/common/BUILD.bazel b/common/BUILD.bazel index f267704b2dd06..c4d05851ac0be 100644 --- a/common/BUILD.bazel +++ b/common/BUILD.bazel @@ -41,6 +41,24 @@ config_setting( constraint_values = ["@platforms//os:windows"], ) +[ + config_setting( + name = "{}_{}".format(os, arch), + constraint_values = [ + "@platforms//os:{}".format(os), + "@platforms//cpu:{}".format(arch), + ], + ) + for (os, arch) in [ + ("linux", "arm64"), + ("linux", "x86_64"), + ("macos", "arm64"), + ("macos", "x86_64"), + ("windows", "arm64"), + ("windows", "x86_64"), + ] +] + # Are we creating a stamped build? config_setting( name = "stamp", diff --git a/common/manager/BUILD.bazel b/common/manager/BUILD.bazel index 4e4f5f25fe686..8e2d61145d19c 100644 --- a/common/manager/BUILD.bazel +++ b/common/manager/BUILD.bazel @@ -10,10 +10,18 @@ package( ) alias( - name = "selenium-manager-linux", + name = "selenium-manager-linux-x86_64", actual = select({ - "//common:use_pinned_browser": "@download_sm_linux//file", - "//conditions:default": "//rust:selenium-manager-linux", + "//common:use_pinned_browser": "@download_sm_linux_x86_64//file", + "//conditions:default": "//rust:selenium-manager-linux-x86_64", + }), +) + +alias( + name = "selenium-manager-linux-arm64", + actual = select({ + "//common:use_pinned_browser": "@download_sm_linux_arm64//file", + "//conditions:default": "//rust:selenium-manager-linux-arm64", }), ) diff --git a/common/selenium_manager.bzl b/common/selenium_manager.bzl index a963743defb2b..1fe4ba4ea93d3 100644 --- a/common/selenium_manager.bzl +++ b/common/selenium_manager.bzl @@ -5,36 +5,43 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") def selenium_manager(): http_file( - name = "download_sm_linux", + name = "download_sm_linux_x86_64", executable = True, - sha256 = "97df9c7b4aefd1dd1385c81e81543355ca46809f8ec49a20d55a4d0cbac71567", - url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-3f61eec/selenium-manager-linux", + sha256 = "d76852d481cd736426a0e3b3b7ec3c246b5abe6907b44341249bf51f00781901", + url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-d62f09d/selenium-manager-linux", + ) + + http_file( + name = "download_sm_linux_arm64", + executable = True, + sha256 = "774d08f8188b991e657ee503aa28cee2dea6c97c8f804a73d7646db5fa7d995b", + url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-d62f09d/selenium-manager-linux-aarch64", ) http_file( name = "download_sm_macos", executable = True, - sha256 = "8d7e7d02944c357934540cb87e89b1ec3bac2d63f2fb3118957fa38abb7e4bcb", - url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-3f61eec/selenium-manager-macos", + sha256 = "8b228c9ff5d212a93e5895f3387efc4f22e548de75c48976c36efab23fbf3377", + url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-d62f09d/selenium-manager-macos", ) http_file( name = "download_sm_windows", executable = True, - sha256 = "79ea01dba38fee92802aea868623de282c42145b32e3b97fd2ff2802e804355d", - url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-3f61eec/selenium-manager-windows.exe", + sha256 = "cb7460d2330b3d9037a6ab78c8e626cfecec97a30059fc51c46764e07e8c43ef", + url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-d62f09d/selenium-manager-windows.exe", ) http_file( name = "download_sm_sbom", - sha256 = "a0230dd7a0daba4e047290452288feb7ed05cdfcd890b8ba459e92b1f90ce240", - url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-3f61eec/selenium-manager.cdx.json", + sha256 = "2e5e138a6a52e6536e8689dbfdff1c19ace8ae0be64a00bb9dfd65ea83854e93", + url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-d62f09d/selenium-manager.cdx.json", ) http_file( name = "download_sm_notice", - sha256 = "6ffe344c4bab09c047a9b932f012f795832829b1f38fd97f351b9ea177d437b8", - url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-3f61eec/selenium-manager-THIRD-PARTY-NOTICES.txt", + sha256 = "562302c53a61f88b900c09b1ec5cc4574fd9e5bf8eae3b3a8e49d30026c95ce3", + url = "https://github.com/SeleniumHQ/selenium_manager_artifacts/releases/download/selenium-manager-d62f09d/selenium-manager-THIRD-PARTY-NOTICES.txt", ) def _selenium_manager_artifacts_impl(_ctx): diff --git a/dotnet/src/webdriver/BUILD.bazel b/dotnet/src/webdriver/BUILD.bazel index 38fa717171c94..2bd6f48f81712 100644 --- a/dotnet/src/webdriver/BUILD.bazel +++ b/dotnet/src/webdriver/BUILD.bazel @@ -150,9 +150,16 @@ copy_file( ) copy_file( - name = "manager-linux", - src = "//common/manager:selenium-manager-linux", - out = "manager/linux/selenium-manager", + name = "manager-linux-x86_64", + src = "//common/manager:selenium-manager-linux-x86_64", + out = "manager/linux-x86_64/selenium-manager", + visibility = ["//dotnet/test/webdriver:__pkg__"], +) + +copy_file( + name = "manager-linux-arm64", + src = "//common/manager:selenium-manager-linux-arm64", + out = "manager/linux-arm64/selenium-manager", visibility = ["//dotnet/test/webdriver:__pkg__"], ) @@ -174,7 +181,8 @@ nuget_pack( name = "webdriver-pack", files = { "//common/images:selenium_logo_small.png": "icon.png", - "//common/manager:selenium-manager-linux": "manager/linux/selenium-manager", + "//common/manager:selenium-manager-linux-x86_64": "manager/linux-x86_64/selenium-manager", + "//common/manager:selenium-manager-linux-arm64": "manager/linux-arm64/selenium-manager", "//common/manager:selenium-manager-macos": "manager/macos/selenium-manager", "//common/manager:selenium-manager-notice": "selenium-manager-THIRD-PARTY-NOTICES.txt", "//common/manager:selenium-manager-sbom": "selenium-manager.cdx.json", diff --git a/dotnet/src/webdriver/Manager/SeleniumManager.cs b/dotnet/src/webdriver/Manager/SeleniumManager.cs index d11f657e07495..0f7c8ab02002a 100644 --- a/dotnet/src/webdriver/Manager/SeleniumManager.cs +++ b/dotnet/src/webdriver/Manager/SeleniumManager.cs @@ -19,9 +19,7 @@ using System.Diagnostics; using System.Globalization; -#if !NET8_0_OR_GREATER using System.Runtime.InteropServices; -#endif using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -134,7 +132,15 @@ public static partial class SeleniumManager probingPaths.Add(Path.Combine(baseDirectory, "runtimes", "win", "native", seleniumManagerFileName)); break; case SupportedPlatform.Linux: - probingPaths.Add(Path.Combine(baseDirectory, "runtimes", "linux", "native", seleniumManagerFileName)); + // linux-musl-* resolves through these, so no generic "linux" folder is needed. +#if !NET462 + var linuxRid = RuntimeInformation.ProcessArchitecture == Architecture.Arm64 + ? "linux-arm64" + : "linux-x64"; +#else + const string linuxRid = "linux-x64"; +#endif + probingPaths.Add(Path.Combine(baseDirectory, "runtimes", linuxRid, "native", seleniumManagerFileName)); break; case SupportedPlatform.MacOS: probingPaths.Add(Path.Combine(baseDirectory, "runtimes", "osx", "native", seleniumManagerFileName)); diff --git a/dotnet/src/webdriver/Selenium.WebDriver.csproj b/dotnet/src/webdriver/Selenium.WebDriver.csproj index 30523dbaaf6ce..caac89123a3e0 100644 --- a/dotnet/src/webdriver/Selenium.WebDriver.csproj +++ b/dotnet/src/webdriver/Selenium.WebDriver.csproj @@ -61,7 +61,7 @@ - + @@ -70,7 +70,8 @@ - + + diff --git a/dotnet/src/webdriver/Selenium.WebDriver.nuspec b/dotnet/src/webdriver/Selenium.WebDriver.nuspec index a66debca748d1..2814c5440cbf1 100644 --- a/dotnet/src/webdriver/Selenium.WebDriver.nuspec +++ b/dotnet/src/webdriver/Selenium.WebDriver.nuspec @@ -61,7 +61,8 @@ - + + diff --git a/dotnet/src/webdriver/assets/nuget/build/Selenium.WebDriver.props b/dotnet/src/webdriver/assets/nuget/build/Selenium.WebDriver.props index 31e59250fd6d3..f843fbaa9ef15 100644 --- a/dotnet/src/webdriver/assets/nuget/build/Selenium.WebDriver.props +++ b/dotnet/src/webdriver/assets/nuget/build/Selenium.WebDriver.props @@ -11,8 +11,15 @@ false - - runtimes\linux\native\%(Filename)%(Extension) + + runtimes\linux-x64\native\%(Filename)%(Extension) + PreserveNewest + False + false + + + + runtimes\linux-arm64\native\%(Filename)%(Extension) PreserveNewest False false diff --git a/dotnet/test/webdriver/BUILD.bazel b/dotnet/test/webdriver/BUILD.bazel index b1161a0f296e8..bb437746be328 100644 --- a/dotnet/test/webdriver/BUILD.bazel +++ b/dotnet/test/webdriver/BUILD.bazel @@ -8,7 +8,8 @@ filegroup( "appconfig.json", "//common/extensions", "//common/src/web", - "//dotnet/src/webdriver:manager-linux", + "//dotnet/src/webdriver:manager-linux-arm64", + "//dotnet/src/webdriver:manager-linux-x86_64", "//dotnet/src/webdriver:manager-macos", "//dotnet/src/webdriver:manager-windows", "//javascript/atoms", diff --git a/dotnet/test/webdriver/Infrastructure/Environment/EnvironmentManager.cs b/dotnet/test/webdriver/Infrastructure/Environment/EnvironmentManager.cs index 3e6b8f9a9fc1f..1949ace343c23 100644 --- a/dotnet/test/webdriver/Infrastructure/Environment/EnvironmentManager.cs +++ b/dotnet/test/webdriver/Infrastructure/Environment/EnvironmentManager.cs @@ -100,7 +100,8 @@ private EnvironmentManager() } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - managerFilePath = runfiles.Rlocation("_main/dotnet/src/webdriver/manager/linux/selenium-manager"); + var linuxArch = RuntimeInformation.ProcessArchitecture == Architecture.Arm64 ? "arm64" : "x86_64"; + managerFilePath = runfiles.Rlocation($"_main/dotnet/src/webdriver/manager/linux-{linuxArch}/selenium-manager"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { diff --git a/java/src/org/openqa/selenium/manager/BUILD.bazel b/java/src/org/openqa/selenium/manager/BUILD.bazel index 40b3c09a252dd..27b43186572cf 100644 --- a/java/src/org/openqa/selenium/manager/BUILD.bazel +++ b/java/src/org/openqa/selenium/manager/BUILD.bazel @@ -11,7 +11,8 @@ java_export( ], pom_template = "//java/src/org/openqa/selenium:template-pom", resources = [ - ":manager-linux", + ":manager-linux-arm64", + ":manager-linux-x86_64", ":manager-macos", ":manager-notice", ":manager-sbom", @@ -32,9 +33,15 @@ java_export( ) copy_file( - name = "manager-linux", - src = "//common/manager:selenium-manager-linux", - out = "linux/selenium-manager", + name = "manager-linux-x86_64", + src = "//common/manager:selenium-manager-linux-x86_64", + out = "linux-x86_64/selenium-manager", +) + +copy_file( + name = "manager-linux-arm64", + src = "//common/manager:selenium-manager-linux-arm64", + out = "linux-arm64/selenium-manager", ) copy_file( diff --git a/java/src/org/openqa/selenium/manager/SeleniumManager.java b/java/src/org/openqa/selenium/manager/SeleniumManager.java index f0f0929049369..bd57e8a599212 100644 --- a/java/src/org/openqa/selenium/manager/SeleniumManager.java +++ b/java/src/org/openqa/selenium/manager/SeleniumManager.java @@ -211,18 +211,16 @@ private synchronized Path getBinary() { } else if (current.is(MAC)) { folder = "macos"; } else if (current.is(LINUX)) { - if (System.getProperty("os.arch").contains("arm") - || System.getProperty("os.arch").contains("aarch64")) { - throw new WebDriverException("Linux ARM is not supported by Selenium Manager"); - } else { - folder = "linux"; - } + folder = + System.getProperty("os.arch", "").toLowerCase().contains("aarch64") + ? "linux-arm64" + : "linux-x86_64"; } else if (current.is(UNIX)) { LOG.warning( String.format( "Selenium Manager binary may not be compatible with %s; verify settings", current)); - folder = "linux"; + folder = "linux-x86_64"; } else { throw new WebDriverException("Unsupported platform: " + current); } diff --git a/javascript/selenium-webdriver/BUILD.bazel b/javascript/selenium-webdriver/BUILD.bazel index 31a1f60842e76..1d225801c4497 100644 --- a/javascript/selenium-webdriver/BUILD.bazel +++ b/javascript/selenium-webdriver/BUILD.bazel @@ -165,7 +165,8 @@ npm_package( srcs = [ ":create-bidi-src", ":license", - ":manager-linux", + ":manager-linux-arm64", + ":manager-linux-x86_64", ":manager-macos", ":manager-notice", ":manager-sbom", @@ -324,9 +325,15 @@ genrule( ) copy_file( - name = "manager-linux", - src = "//common/manager:selenium-manager-linux", - out = "bin/linux/selenium-manager", + name = "manager-linux-x86_64", + src = "//common/manager:selenium-manager-linux-x86_64", + out = "bin/linux-x86_64/selenium-manager", +) + +copy_file( + name = "manager-linux-arm64", + src = "//common/manager:selenium-manager-linux-arm64", + out = "bin/linux-arm64/selenium-manager", ) copy_file( diff --git a/javascript/selenium-webdriver/common/seleniumManager.js b/javascript/selenium-webdriver/common/seleniumManager.js index 71e79616da2b1..8194d4f5c2b87 100644 --- a/javascript/selenium-webdriver/common/seleniumManager.js +++ b/javascript/selenium-webdriver/common/seleniumManager.js @@ -21,7 +21,7 @@ * Wrapper for getting information from the Selenium Manager binaries */ -const { platform } = require('node:process') +const { platform, arch } = require('node:process') const path = require('node:path') const fs = require('node:fs') const spawnSync = require('node:child_process').spawnSync @@ -39,7 +39,7 @@ function getBinary() { darwin: 'macos', win32: 'windows', cygwin: 'windows', - linux: 'linux', + linux: arch === 'arm64' ? 'linux-arm64' : 'linux-x86_64', }[platform] const file = directory === 'windows' ? 'selenium-manager.exe' : 'selenium-manager' diff --git a/py/BUILD.bazel b/py/BUILD.bazel index a87bf9f7b79ab..e8d0a2b6aff87 100644 --- a/py/BUILD.bazel +++ b/py/BUILD.bazel @@ -104,9 +104,15 @@ genrule( ) copy_file( - name = "manager-linux", - src = "//common/manager:selenium-manager-linux", - out = "selenium/webdriver/common/linux/selenium-manager", + name = "manager-linux-x86_64", + src = "//common/manager:selenium-manager-linux-x86_64", + out = "selenium/webdriver/common/linux-x86_64/selenium-manager", +) + +copy_file( + name = "manager-linux-arm64", + src = "//common/manager:selenium-manager-linux-arm64", + out = "selenium/webdriver/common/linux-arm64/selenium-manager", ) copy_file( @@ -321,7 +327,8 @@ py_library( ], ), data = [ - ":manager-linux", + ":manager-linux-arm64", + ":manager-linux-x86_64", ":manager-macos", ":manager-notice", ":manager-sbom", @@ -606,7 +613,8 @@ pkg_files( "//rust:selenium_manager_srcs", ], excludes = [ - ":manager-linux", + ":manager-linux-x86_64", + ":manager-linux-arm64", ":manager-macos", ":manager-notice", ":manager-sbom", diff --git a/py/selenium/webdriver/common/selenium_manager.py b/py/selenium/webdriver/common/selenium_manager.py index 9dfdbb052fe4c..c19ece5938a4c 100644 --- a/py/selenium/webdriver/common/selenium_manager.py +++ b/py/selenium/webdriver/common/selenium_manager.py @@ -90,10 +90,15 @@ def _get_binary() -> Path: allowed = { ("darwin", "any"): "macos/selenium-manager", ("win32", "x86_64"): "windows/selenium-manager.exe", + ("win32", "arm64"): "windows/selenium-manager.exe", ("cygwin", "x86_64"): "windows/selenium-manager.exe", - ("linux", "x86_64"): "linux/selenium-manager", - ("freebsd", "x86_64"): "linux/selenium-manager", - ("openbsd", "x86_64"): "linux/selenium-manager", + ("cygwin", "arm64"): "windows/selenium-manager.exe", + ("linux", "x86_64"): "linux-x86_64/selenium-manager", + ("linux", "aarch64"): "linux-arm64/selenium-manager", + ("freebsd", "x86_64"): "linux-x86_64/selenium-manager", + ("freebsd", "aarch64"): "linux-arm64/selenium-manager", + ("openbsd", "x86_64"): "linux-x86_64/selenium-manager", + ("openbsd", "aarch64"): "linux-arm64/selenium-manager", } # some operating systems report x86-64 architecture as amd64/AMD64 diff --git a/py/test/unit/selenium/webdriver/common/selenium_manager_tests.py b/py/test/unit/selenium/webdriver/common/selenium_manager_tests.py index 7351f10163161..7533c2ea23a76 100644 --- a/py/test/unit/selenium/webdriver/common/selenium_manager_tests.py +++ b/py/test/unit/selenium/webdriver/common/selenium_manager_tests.py @@ -61,8 +61,9 @@ def test_uses_windows(monkeypatch): def test_uses_windows_arm64(monkeypatch): monkeypatch.setattr(sys, "platform", "win32") monkeypatch.setattr("platform.machine", lambda: "ARM64") - with pytest.raises(WebDriverException, match="Unsupported platform/architecture combination: win32/arm64"): - SeleniumManager()._get_binary() + binary = SeleniumManager()._get_binary() + project_root = Path(selenium.__file__).parent.parent + assert binary == project_root.joinpath("selenium/webdriver/common/windows/selenium-manager.exe") def test_uses_linux(monkeypatch): @@ -70,14 +71,15 @@ def test_uses_linux(monkeypatch): monkeypatch.setattr("platform.machine", lambda: "x86_64") binary = SeleniumManager()._get_binary() project_root = Path(selenium.__file__).parent.parent - assert binary == project_root.joinpath("selenium/webdriver/common/linux/selenium-manager") + assert binary == project_root.joinpath("selenium/webdriver/common/linux-x86_64/selenium-manager") -def test_uses_linux_arm64(monkeypatch): +def test_uses_linux_aarch64(monkeypatch): monkeypatch.setattr(sys, "platform", "linux") - monkeypatch.setattr("platform.machine", lambda: "arm64") - with pytest.raises(WebDriverException, match="Unsupported platform/architecture combination: linux/arm64"): - SeleniumManager()._get_binary() + monkeypatch.setattr("platform.machine", lambda: "aarch64") + binary = SeleniumManager()._get_binary() + project_root = Path(selenium.__file__).parent.parent + assert binary == project_root.joinpath("selenium/webdriver/common/linux-arm64/selenium-manager") def test_uses_mac(monkeypatch): @@ -97,7 +99,7 @@ def test_uses_freebsd(monkeypatch, caplog): try: binary = SeleniumManager()._get_binary() project_root = Path(selenium.__file__).parent.parent - assert binary == project_root.joinpath("selenium/webdriver/common/linux/selenium-manager") + assert binary == project_root.joinpath("selenium/webdriver/common/linux-x86_64/selenium-manager") assert "Selenium Manager binary may not be compatible with FreeBSD" in caplog.text finally: root.handlers = old_handlers diff --git a/rake_tasks/python.rake b/rake_tasks/python.rake index 60d2cc81f17c3..723f2f850b92c 100644 --- a/rake_tasks/python.rake +++ b/rake_tasks/python.rake @@ -80,7 +80,8 @@ task :local_dev, [:all] do |_task, arguments| files = %w[ remote/getAttribute.js remote/isDisplayed.js remote/findElements.js common/mutation-listener.js common/bidi-mutation-listener.js - common/linux/selenium-manager common/macos/selenium-manager common/windows/selenium-manager.exe + common/linux-x86_64/selenium-manager common/linux-arm64/selenium-manager + common/macos/selenium-manager common/windows/selenium-manager.exe firefox/webdriver_prefs.json ] end diff --git a/rb/BUILD.bazel b/rb/BUILD.bazel index 6d924214a0a1b..2f4cf4bdaa1de 100644 --- a/rb/BUILD.bazel +++ b/rb/BUILD.bazel @@ -12,9 +12,15 @@ package(default_visibility = ["//:__subpackages__"]) GITHUB_PACKAGES_HOST = "https://rubygems.pkg.github.com/SeleniumHQ" copy_file( - name = "manager-linux", - src = "//common/manager:selenium-manager-linux", - out = "bin/linux/selenium-manager", + name = "manager-linux-x86_64", + src = "//common/manager:selenium-manager-linux-x86_64", + out = "bin/linux-x86_64/selenium-manager", +) + +copy_file( + name = "manager-linux-arm64", + src = "//common/manager:selenium-manager-linux-arm64", + out = "bin/linux-arm64/selenium-manager", ) copy_file( @@ -75,7 +81,8 @@ rb_gem_build( "CHANGES", "README.md", ":license", - ":manager-linux", + ":manager-linux-arm64", + ":manager-linux-x86_64", ":manager-macos", ":manager-notice", ":manager-sbom", diff --git a/rb/lib/selenium/webdriver/common/selenium_manager.rb b/rb/lib/selenium/webdriver/common/selenium_manager.rb index c53b384c90190..787bfabfdd89d 100644 --- a/rb/lib/selenium/webdriver/common/selenium_manager.rb +++ b/rb/lib/selenium/webdriver/common/selenium_manager.rb @@ -77,16 +77,20 @@ def platform_location elsif Platform.mac? "#{directory}/macos/selenium-manager" elsif Platform.linux? - "#{directory}/linux/selenium-manager" + "#{directory}/#{linux_directory}/selenium-manager" elsif Platform.unix? WebDriver.logger.warn('Selenium Manager binary may not be compatible with Unix', id: %i[selenium_manager unix_binary]) - "#{directory}/linux/selenium-manager" + "#{directory}/#{linux_directory}/selenium-manager" else raise Error::WebDriverError, "unsupported platform: #{Platform.os}" end end + def linux_directory + RbConfig::CONFIG['host_cpu'].to_s.downcase == 'aarch64' ? 'linux-arm64' : 'linux-x86_64' + end + def execute_command(*command) WebDriver.logger.debug("Executing Process #{command}", id: :selenium_manager) diff --git a/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs b/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs index 713337031383f..c7d644d686df0 100644 --- a/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs +++ b/rb/sig/lib/selenium/webdriver/common/selenium_manager.rbs @@ -43,6 +43,8 @@ module Selenium def self.run: (String | Array[String] command) -> Hash[String, Array[String]] def self.platform_location: -> String + + def self.linux_directory: -> String end end end diff --git a/rb/spec/integration/selenium/webdriver/BUILD.bazel b/rb/spec/integration/selenium/webdriver/BUILD.bazel index a06ee3e9e4cdc..3c5ee1b4b4612 100644 --- a/rb/spec/integration/selenium/webdriver/BUILD.bazel +++ b/rb/spec/integration/selenium/webdriver/BUILD.bazel @@ -16,7 +16,8 @@ rb_library( "spec_support.rb", ] + glob(["spec_support/**/*"]), data = [ - "//rb:manager-linux", + "//rb:manager-linux-arm64", + "//rb:manager-linux-x86_64", "//rb:manager-macos", "//rb:manager-windows", ], diff --git a/rb/spec/unit/selenium/webdriver/common/selenium_manager_spec.rb b/rb/spec/unit/selenium/webdriver/common/selenium_manager_spec.rb index 4ed72fa9fa2a2..bbf8e6d559f56 100644 --- a/rb/spec/unit/selenium/webdriver/common/selenium_manager_spec.rb +++ b/rb/spec/unit/selenium/webdriver/common/selenium_manager_spec.rb @@ -51,11 +51,21 @@ module WebDriver end it 'detects Linux' do - allow(Platform).to receive(:assert_executable).with(a_string_ending_with('/linux/selenium-manager')) + allow(Platform).to receive(:assert_executable).with(a_string_ending_with('/linux-x86_64/selenium-manager')) .and_return(true) allow(Platform).to receive_messages(windows?: false, mac?: false, linux?: true) + allow(RbConfig::CONFIG).to receive(:[]).with('host_cpu').and_return('x86_64') - expect(described_class.send(:binary)).to match(%r{/linux/selenium-manager$}) + expect(described_class.send(:binary)).to match(%r{/linux-x86_64/selenium-manager$}) + end + + it 'detects Linux arm64' do + allow(Platform).to receive(:assert_executable) + .with(a_string_ending_with('/linux-arm64/selenium-manager')).and_return(true) + allow(Platform).to receive_messages(windows?: false, mac?: false, linux?: true) + allow(RbConfig::CONFIG).to receive(:[]).with('host_cpu').and_return('aarch64') + + expect(described_class.send(:binary)).to match(%r{/linux-arm64/selenium-manager$}) end it 'errors if cannot find' do diff --git a/rust/BUILD.bazel b/rust/BUILD.bazel index ba3c8cbb70b2f..33a3e1f086629 100644 --- a/rust/BUILD.bazel +++ b/rust/BUILD.bazel @@ -13,56 +13,33 @@ rustfmt_config( # We tag the compiled versions as `manual` so that when we do a # `bazel build //...` we don't do any additional work -# Start with the variants for each platform -alias( - name = "selenium-manager-windows", - actual = select({ - "//common:windows": ":selenium-manager", - "//conditions:default": "@download_sm_windows//file", - }), - tags = [ - "manual", - ], - visibility = [ - "//common/manager:__pkg__", - ], -) +SELENIUM_MANAGER_PLATFORMS = [ + "linux-arm64", + "linux-x86_64", + "macos", + "windows", +] -alias( - name = "selenium-manager-macos", - actual = select({ - "//common:macos": ":selenium-manager", - "//conditions:default": "@download_sm_macos//file", - }), - tags = [ - "manual", - ], - visibility = [ - "//common/manager:__pkg__", - ], -) - -alias( - name = "selenium-manager-linux", - actual = select({ - "//common:linux": ":selenium-manager", - "//conditions:default": "@download_sm_linux//file", - }), - tags = [ - "manual", - ], - visibility = [ - "//common/manager:__pkg__", - ], -) +[ + alias( + name = "selenium-manager-%s" % platform, + actual = select({ + "//common:%s" % platform.replace("-", "_"): ":selenium-manager", + "//conditions:default": "@download_sm_%s//file" % platform.replace("-", "_"), + }), + tags = [ + "manual", + ], + visibility = [ + "//common/manager:__pkg__", + ], + ) + for platform in SELENIUM_MANAGER_PLATFORMS +] filegroup( name = "selenium-manager-dev", - srcs = [ - ":selenium-manager-linux", - ":selenium-manager-macos", - ":selenium-manager-windows", - ], + srcs = [":selenium-manager-%s" % platform for platform in SELENIUM_MANAGER_PLATFORMS], tags = [ "manual", ], diff --git a/scripts/selenium_manager.py b/scripts/selenium_manager.py index 3f38d06c23f26..4eabcdb5fe671 100755 --- a/scripts/selenium_manager.py +++ b/scripts/selenium_manager.py @@ -28,15 +28,26 @@ def get_sha_json(): return json.loads(r.data) -def print_linux(base_url, sha): +def print_linux_x86_64(base_url, sha): return """ http_file( - name = "download_sm_linux", + name = "download_sm_linux_x86_64", executable = True, sha256 = "{}", url = "{}", ) -""".format(sha, base_url + "/selenium-manager-linux") +""".format(sha, base_url + "/selenium-manager-linux-x86_64") + + +def print_linux_arm64(base_url, sha): + return """ http_file( + name = "download_sm_linux_arm64", + executable = True, + sha256 = "{}", + url = "{}", + ) + +""".format(sha, base_url + "/selenium-manager-linux-arm64") def print_macos(base_url, sha): @@ -90,7 +101,8 @@ def selenium_manager(): """ base_url = get_url() sha_dict = get_sha_json() - content = content + print_linux(base_url, sha_dict["linux"]) + content = content + print_linux_x86_64(base_url, sha_dict["linux-x86_64"]) + content = content + print_linux_arm64(base_url, sha_dict["linux-arm64"]) content = content + print_macos(base_url, sha_dict["macos"]) content = content + print_windows(base_url, sha_dict["windows"]) content = content + print_sbom(base_url, sha_dict["sbom"])