Repository navigation
Use the browser motus install downloaded when launching - #36
Merged
Merged
Conversation
A browser downloaded with `motus install` was found by the `motus` commands but not by
`MotusLauncher.LaunchAsync`, so a test run under `dotnet test` either failed with no browser found
on a machine without Chrome or quietly ran against whatever Chrome the machine had. The launcher
looked only at system locations, and `BrowserFinder.InstalledBinariesPath`, documented as the hook
the installer used, was never set and looked for a flat file name the download never has.
The installer already records the exact executable it installed in `.installed.{channel}`, because
each build unpacks into its own versioned layout (`chromium-{version}/chrome-{platform}/...`, an
app bundle on macOS). `BrowserFinder.Resolve` now reads that marker after an explicit path and
before the system locations. With no channel the Chromium download is tried first; `Chromium` and
`Firefox` prefer a download for that browser; `Chrome` and `Edge` keep meaning the branded browser.
A marker naming a file that is gone is ignored. The cache location and marker names move into one
internal `InstalledBrowsers` class that the installer, the CLI's `BrowserPathHelper` and the
launcher all use, so they cannot drift apart, and the unused `InstalledBinariesPath` is removed.
Signed-off-by: Torrey Betts <torrey.betts@gmail.com>
SummarySummary
CoverageMotus - 80.5%
Motus.Abstractions - 87.7%
Motus.Analyzers - 91%
Motus.Cli - 82.1%
Motus.Codegen - 89.8%
Motus.Mcp - 91.9%
Motus.Mcp.Http - 98.6%
Motus.Recorder - 77.8%
Motus.Testing - 75.4%
Motus.Testing.MSTest - 79%
Motus.Testing.xUnit - 63.6%
|
Brings in the locator assertion, pointer scrolling, GetByRole/GetByLabel and Firefox key value changes. None of them touch browser discovery, and the merge applied without conflicts. Signed-off-by: Torrey Betts <torrey.betts@gmail.com>
TorreyBetts
added a commit
that referenced
this pull request
Oct 24, 2026
TorreyBetts
added a commit
that referenced
this pull request
Oct 24, 2026
Brings in #31, #32, #33, #35, #36, #37, #38 and #40. Everything merged cleanly; the frame navigation handlers in Page.Events.cs sit next to the execution context tracking from #33 without touching it, and same-document navigations still leave execution contexts alone. Signed-off-by: Torrey Betts <torrey.betts@gmail.com>
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.
A browser downloaded with
motus installwas used by themotuscommands and the MCP server, but not byMotusLauncher.LaunchAsync. A suite run withdotnet teston a fresh CI image therefore failed with "No supported browser found", and on a machine with Chrome installed it quietly ran against that Chrome instead of the build that was installed for it.The change
The launcher only looked at system locations.
BrowserFinder.InstalledBinariesPath, documented as the hook the install system used, was never assigned, and it looked for a flatchromiumorchromefile that the download never has. A Chrome for Testing archive unpacks aschromium-{version}/chrome-linux64/chromeon Linux,chrome-win64\chrome.exe(orchrome-win32) on Windows, andchrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing(orchrome-mac-x64) on macOS. We checked that against the 149.0.7827.54 archives for all five platforms. Several versions can also sit side by side.The installer already records the exact executable it installed in
~/.motus/browsers/.installed.{channel}, soBrowserFinder.Resolvenow reads that marker instead of searching the folder. The marker is read after an explicit path (which includeslaunch.executablePathandMOTUS_EXECUTABLE_PATH) and before the system locations. If a marker names a file that no longer exists, for example because the cache was cleaned by hand, it is ignored and resolution falls through as before.The cache location and marker names now live in one internal
InstalledBrowsersclass. The installer writes through it, the CLI'sBrowserPathHelperreads through it, and the launcher reads through it, so the three can't drift apart.BrowserPathHelperkeeps its public signatures.InstalledBinariesPathis gone. It was internal, so this isn't a public API change. Its place as the test seam is taken byBrowserFinder.InstallRoot, along with an overload ofResolvethat takes the cache folder and the system candidate list. That keeps the tests from depending on what is in the real~/.motusor on which browsers the machine has.Behavior changes
Channeland no executable path,LaunchAsyncnow uses the Chromium thatmotus installdownloaded before trying a system Chrome, Edge or Chromium. On a machine that has both, tests now run against the download instead of the installed Chrome. That is the build the user chose to install, and usually the pinned one. To keep using the system Chrome, setChannel = BrowserChannel.Chrome.Channel = Chromiumprefers the Chromium download over a system Chromium.Channel = Firefoxprefers a Firefox download (motus installcan only download Firefox on Windows) over a system Firefox.Channel = ChromeandChannel = Edgeare unchanged. They still mean the installed branded browser, and a missing one is still reported as missing instead of being replaced by the download. This matches whatmotus mcp --channelalready does for a named channel.motus install --pathstill needslaunch.executablePathorMOTUS_EXECUTABLE_PATH.motus install.The docs describe the new precedence and the download layout in
docs/architecture/browser-lifecycle.md.docs/guides/configuration.md,docs/reference/cli.md, the README's pinning section and theLaunchOptions.Channel/ExecutablePathXML docs are updated to match. The oldExecutablePathdoc mentioned a "bundled" browser, which doesn't exist.Tests
BrowserFinderTestsuse a temporary cache and fake system locations. They cover: the download found on a machine with no browser; the download preferred over system Chrome, Edge and Chromium; the auto-detect order; a missing marker; a stale marker pointing at a deleted folder, both with and without a system fallback; an empty marker; a trailing newline; an explicit path winning over the download;ChromiumandFirefoxpreferring their own download;ChromeandEdgeignoring the Chromium download;Firefoxnot taking the Chromium download; and auto-detect not taking a Firefox download. With the marker lookup disabled, 6 of these fail.InstalledBrowserLaunchTests(Integration, Unix) points the cache at a stand-in "browser" script and checks thatLaunchAsyncwith default options starts it. It reports Inconclusive when an executable path is already configured, since that path rightly wins.dotnet build Motus.sln: 0 errors.TestCategory!=Integration&FullyQualifiedName!~Motus.Samples), net8.0 and net10.0: all pass (Motus.Tests 1070, Motus.Mcp.Tests 366, Motus.Cli.Tests 303 with 2 skipped, Motus.Recorder.Tests 105, Motus.Codegen.Tests 59, Motus.Analyzers.Tests 29, Motus.Testing.xUnit.Tests 8 per framework).InstalledBrowserLaunchTestsandBrowserIntegrationTests7/7 on each framework, now running against the downloaded Chrome for Testing.FirefoxIntegrationTests6/6 on each framework.Fixes #30