FIX: Run the browser tests on ARM64 Linux instead of reporting passes that never happened - #11
Merged
Merged
Conversation
…asses that never happened Selenium Manager, the helper the Selenium package ships to fetch a driver, had only an x64 Linux build up to Selenium.WebDriver 4.48, under a folder named for Linux with no architecture in the name. On an ARM64 Linux runner that build was picked and could not start, so every browser test died with "Exec format error" in a few milliseconds and no browser was ever launched. Selenium.WebDriver 4.49.0 splits that folder by architecture and adds an ARM64 Linux build, so the package moves to 4.49.0. A driver the machine already provides is now used ahead of Selenium Manager, from one place rather than from twelve copies of the same block. GitHub names theirs in CHROMEWEBDRIVER, GECKOWEBDRIVER and EDGEWEBDRIVER, and the ARM64 images set only GECKOWEBDRIVER, carrying Firefox and geckodriver but no Chrome, no Chromium and no Edge. Where nothing can be started the failure names the browser, the variable that was read and the file names looked for, instead of a stack trace about a helper program. Edge on ARM64 Linux says plainly that Microsoft publishes neither the browser nor the driver for it. New smoke tests start each browser against a page served from the test process, needing no cloud, no key and no example, so CI can see for itself whether a browser runs on a runner. The suite's own CI runs them on ubuntu-latest, ubuntu-22.04-arm and ubuntu-24.04-arm.
The first run proved headless Edge on the x64 Ubuntu runner accepts the session and then hangs on the first navigation until the sixty second timeout, which is the same fault the other Edge tests in this suite are already ignored for. It is a fault of its own and not the ARM64 one this class was added for.
jwrosewell
changed the base branch from
fix/contract-settings-and-skip-reasons
to
main
September 17, 2026 21:48
jwrosewell
marked this pull request as ready for review
September 17, 2026 21:49
oleksandrlazarenko-pi
added a commit
that referenced
this pull request
Sep 18, 2026
Brings in #10 (contract settings, skip reasons) and #11 (ARM64 Linux browser drivers). Three conflicts, all where both sides added: - TestsCommon/TestConfig.cs: main made every variable read through the lookup a TestConfig is given. The demo settings are added on top, and RequireFirst now reads through Optional too, so a configuration built for a test no longer ignores its lookup for the demo's resource key. Browser51Did/DemoSettingsTests.cs covers it. - Examples/ExampleApps.cs: main's BuildOptions and the demo registry are independent, and both are kept. - README.md: both new category rows are kept.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
On an ARM64 Linux runner the browser suite reported nine passes that never
happened. The job was green and the log said
Failed! - Failed: 9, Passed: 0, Total: 9 - SeleniumApiTests.dll, with everyone of the nine dying in about two milliseconds on:
Selenium Manager is the helper program the Selenium package ships to fetch a
matching driver. Up to Selenium.WebDriver 4.48 the only Linux build of it was
for x64, and it sat under
runtimes/linux/native, a folder whose name carriesno architecture. On ARM64 Linux that x64 build was picked, could not start, and
no browser was ever launched.
What this runner actually provides
Read from the runner image manifests rather than guessed at.
Ubuntu2204-Arm64-Readme.md,Ubuntu2404-Arm64-Readme.mdandUbuntu2604-Arm64-Readme.mdall carry the same short list:The x64 manifests add Google Chrome, ChromeDriver, Chromium, Microsoft Edge and
Microsoft Edge WebDriver, and fill in
CHROMEWEBDRIVERandEDGEWEBDRIVER. Soon ARM64 there is no Chrome, no Chromium, no ChromeDriver, no Edge and no Edge
driver, and the two blank rows mean the variables are unset rather than set to
nothing. The packer templates say why: the ARM64 build runs only
install-firefox.shandinstall-selenium.sh, whilst the x64 build also runsinstall-google-chrome.shandinstall-microsoft-edge.sh, and the Chromescript is hard-wired to amd64 and
linux64throughout. Adding Chrome to thoseimages is tracked at actions/runner-images#14567, still open.
.NET is not a constraint. The ARM64 images carry the same SDK list as the x64
ones, 8.0, 9.0 and 10.0.
Upstream, checked by fetching the artefacts:
linux-arm64for Chrome, ChromeDriver andchrome-headless-shell on every channel, and
chromedriver-linux-arm64.zipanswers 200.geckodriver-v0.37.1-linux-aarch64.tar.gzand alinux-aarch64Firefox.binary-arm64is zero bytes wherebinary-amd64is about a megabyte, andedgedriver_linux-arm64.zipanswers 404. Selenium Manager's own binarycarries the string "Linux arm64 is not supported yet by Microsoft Edge".
folder by architecture and adds an ARM64 build. Listing the two packages
side by side: 4.48.0 has
runtimes/linux/native/selenium-manageralone, anx86-64 ELF, and 4.49.0 has
runtimes/linux-x64/native/selenium-managerplusruntimes/linux-arm64/native/selenium-manager, an AArch64 ELF.SeleniumManager.csin 4.49 picks the folder fromRuntimeInformation.ProcessArchitecture.What changed
cause. The reason is written next to the package reference so nobody
downgrades it by accident.
Helpers/BrowserDrivers.cscreates every driver the suite uses, from oneplace. Twelve copies of the same remote-or-local block across ten files now
call it. It prefers a driver the machine already provides, named by
CHROMEWEBDRIVER,GECKOWEBDRIVERorEDGEWEBDRIVERor found on the path,because a machine that ships one is faster and steadier than downloading one
for every run, and because that is what makes Firefox work on ARM64 with no
setup at all. Handing Selenium a driver service that already knows its path
stops it calling Selenium Manager, which is the behaviour this relies on.
Only when the machine provides nothing is Selenium Manager left to fetch one.
names the browser, the variable that was read, the file names looked for on
the path and the runtime identifier of the machine, and then quotes what
Selenium said. Edge on ARM64 Linux says plainly that Microsoft publishes
neither the browser nor the driver for it, rather than failing on something
that cannot be fixed here.
Selenium/DriverSmokeTests.cs, categoryBrowser, starts each browseragainst a page served from the test process and checks the browser really ran
the script on it. No cloud, no resource key and no example application, so
the test can go on any runner and answer one question, which is whether a
browser starts there. They fail rather than skip when none can, because a run
that quietly skipped them would say nothing, and saying nothing is the fault
they were written for.
Helpers/BrowserDriversTests.cscovers the rules for finding a driver,including the case an ARM64 runner actually presents, which is
CHROMEWEBDRIVERset to nothing.Browsertests onubuntu-latest,ubuntu-22.04-armandubuntu-24.04-arm, and prints whateach runner provides before it does, so a later change of image is readable
from the log.
Which repositories skip ARM today
Two skip the browser suite on ARM64 Linux, each with a note about the missing
Selenium Manager build, and each can drop the skip once this is merged and the
Selenium version has reached them:
device-detection-dotnet,ci/run-integration-tests.ps1, the$skipSeleniumOnArmguard and the warning it prints.device-detection-node,ci/run-integration-tests.ps1, the earlyexitonLinux ARM64.
One has an ARM64 Linux job and no skip, which is where the fault was seen:
device-detection-java,ci/run-integration-tests.ps1. It was running thesuite on ARM and getting nine failures that never reached the job result,
because
dotnet testreturning non-zero does not stop a PowerShell scriptthat has not asked it to. Making the suite honest is only half of it, as a
caller that drops the exit code reports a green job either way, so that half
is device-detection-java#592.
Two run the suite but carry no ARM64 image in their matrix at all, so nothing
there needs removing, although both drop the exit code the same way and would
hide a failure if an ARM job were added:
device-detection-php,ci/run-integration-tests.ps1device-detection-python,ci/run-integration-tests.ps1rusthas no ARM64 Linux job either.How this was proved
The machine this was written on cannot run a browser, so it was proved in CI.
This repository's own CI, run
35198239429,
all four jobs green. Each browser job prints what its runner provides before it
starts anything. On
ubuntu-24.04-arm:and then:
Firefox runs on the driver the image provides. Chrome runs although the image
has none, because Selenium Manager fetches the Chrome for Testing
linux-arm64build.
ubuntu-22.04-armgives the same result in 25 seconds, andubuntu-latestin 15 seconds.The Edge smoke test was written to run, and was ignored after its first run
proved headless Edge on the x64 Ubuntu runner accepts the session and then hangs
on the first navigation for the whole sixty second timeout. That is the fault
the other Edge tests in this suite were already ignored for, and it is not the
ARM64 one, so the test is kept with its reason where a reader will find it.
End to end through a language repository, which is where the fault was
reported.
device-detection-javarun35198427368,
dispatched with
dryrun=trueon the branch ofdevice-detection-java#592,
with the suite pinned to this branch for that run only. Its
Ubuntu_ARM_Java_17job says:
The same nine tests that died in about 155 milliseconds without starting a
browser now drive a real browser for forty seconds and pass.
Locally,
dotnet build -c Releaseand the tests that need no browser pass, 30of them.
Why this is still a draft, 17 September 2026
CI is green on this head, in
https://github.com/51Degrees/selenium-api-tests/actions/runs/35198526469,
where
build-and-testand the threeBrowsers on ...jobs all pass.It stays a draft only because its base is
fix/contract-settings-and-skip-reasons, the branch behind#10, which has not
merged. Taking this out of draft would let the overnight merge push
these commits into that branch rather than into
main, which wouldrewrite what pull request 10 is asking for and throw away the run that
proved it.
Once pull request 10 has merged, retarget this one at
mainfirst andthen take it out of draft. Retargeting before the merge would be wrong
as well, because the diff would then carry pull request 10's commits
too. Do not let pull request 10 merge with its branch deleted while this
one is still pointing at it, because a stacked pull request closes when
its base branch goes and it cannot be reopened.