Skip to content

Use the browser motus install downloaded when launching - #36

Merged
TorreyBetts merged 2 commits into
mainfrom
fix/installed-browser
Oct 24, 2026
Merged

TorreyBetts merged 2 commits into
mainfrom
fix/installed-browser

Conversation

@TorreyBetts

Copy link
Copy Markdown
Contributor

A browser downloaded with motus install was used by the motus commands and the MCP server, but not by MotusLauncher.LaunchAsync. A suite run with dotnet test on 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 flat chromium or chrome file that the download never has. A Chrome for Testing archive unpacks as chromium-{version}/chrome-linux64/chrome on Linux, chrome-win64\chrome.exe (or chrome-win32) on Windows, and chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing (or chrome-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}, so BrowserFinder.Resolve now reads that marker instead of searching the folder. The marker is read after an explicit path (which includes launch.executablePath and MOTUS_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 InstalledBrowsers class. The installer writes through it, the CLI's BrowserPathHelper reads through it, and the launcher reads through it, so the three can't drift apart. BrowserPathHelper keeps its public signatures. InstalledBinariesPath is gone. It was internal, so this isn't a public API change. Its place as the test seam is taken by BrowserFinder.InstallRoot, along with an overload of Resolve that takes the cache folder and the system candidate list. That keeps the tests from depending on what is in the real ~/.motus or on which browsers the machine has.

Behavior changes

  • With no Channel and no executable path, LaunchAsync now uses the Chromium that motus install downloaded 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, set Channel = BrowserChannel.Chrome.
  • Channel = Chromium prefers the Chromium download over a system Chromium. Channel = Firefox prefers a Firefox download (motus install can only download Firefox on Windows) over a system Firefox.
  • Channel = Chrome and Channel = Edge are 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 what motus mcp --channel already does for a named channel.
  • Auto-detect still never picks Firefox, whether downloaded or not.
  • Only the default cache is read. A browser installed with motus install --path still needs launch.executablePath or MOTUS_EXECUTABLE_PATH.
  • The "No supported browser found" message now suggests 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 the LaunchOptions.Channel / ExecutablePath XML docs are updated to match. The old ExecutablePath doc mentioned a "bundled" browser, which doesn't exist.

Tests

  • New BrowserFinderTests use 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; Chromium and Firefox preferring their own download; Chrome and Edge ignoring the Chromium download; Firefox not taking the Chromium download; and auto-detect not taking a Firefox download. With the marker lookup disabled, 6 of these fail.
  • New InstalledBrowserLaunchTests (Integration, Unix) points the cache at a stand-in "browser" script and checks that LaunchAsync with 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.
  • Non-browser unit tests (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).
  • Browser tests on macOS, net8.0 then net10.0: InstalledBrowserLaunchTests and BrowserIntegrationTests 7/7 on each framework, now running against the downloaded Chrome for Testing. FirefoxIntegrationTests 6/6 on each framework.

Fixes #30

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>
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Summary

Summary
Generated on: 10/24/2026 - 18:20:08
Coverage date: 10/24/2026 - 18:16:39 - 10/24/2026 - 18:20:01
Parser: MultiReport (36x Cobertura)
Assemblies: 11
Classes: 566
Files: 290
Line coverage: 82.5% (9659 of 11706)
Covered lines: 9659
Uncovered lines: 2047
Coverable lines: 11706
Total lines: 41818
Branch coverage: 70.9% (3561 of 5022)
Covered branches: 3561
Total branches: 5022
Method coverage: Feature is only available for sponsors

Coverage

Motus - 80.5%
Name Line Branch
Motus 80.5% 71.6%
Motus.AccessibilityAuditHook 62% 40%
Motus.AccessibilityAXNode 100%
Motus.AccessibilityAXNodeSimple 100%
Motus.AccessibilityAXProperty 100%
Motus.AccessibilityAXRelatedNode 100%
Motus.AccessibilityAXValue 100%
Motus.AccessibilityAXValueSimple 100%
Motus.AccessibilityEnableResult 100%
Motus.AccessibilityGetFullAXTreeParams 100%
Motus.AccessibilityQueryAXTreeParams 100%
Motus.AccessibilityRoleNames 100% 50%
Motus.AccessibilityRuleCollection 100%
Motus.AccessibilityRuleEngine 100% 100%
Motus.AccessibilityRulesPlugin 75%
Motus.AccessibilitySelectorHelper 0% 0%
Motus.AccessibilityTreeQuery 98.8% 98.6%
Motus.AccessibilityTreeResult 100%
Motus.AccessibilityViolationSink 100% 100%
Motus.ActionContext 100%
Motus.AltTextAccessibilityRule 94.1% 100%
Motus.Assertions.AccessibilityAssertionOptions 100%
Motus.Assertions.AssertionRetryHelper 100% 75%
Motus.Assertions.Expect 100%
Motus.Assertions.LocatorAssertions 90.9% 100%
Motus.Assertions.PageAssertions 98.1% 85.7%
Motus.Assertions.ResponseAssertions 100% 100%
Motus.AttachedToTargetTranslation 100% 50%
Motus.BackendNodeIdSelectorStrategy 50% 0%
Motus.BiDiBrowsingContextCloseParams 0%
Motus.BiDiBrowsingContextCreateParams 0%
Motus.BiDiBrowsingContextCreateResult 0%
Motus.BiDiBrowsingContextNavigateParams 0%
Motus.BiDiBrowsingContextNavigateResult 0%
Motus.BiDiBrowsingContextReloadParams 0%
Motus.BiDiCommandEnvelope 100%
Motus.BiDiDisconnectedException 50%
Motus.BiDiEventMap 100% 100%
Motus.BiDiInboundDiscriminator 100%
Motus.BiDiInputAction 100%
Motus.BiDiInputActionSequence 100%
Motus.BiDiInputPerformActionsParams 100%
Motus.BiDiInputSourceParameters 100%
Motus.BiDiKeyValues 100% 100%
Motus.BiDiNetworkAddInterceptParams 100%
Motus.BiDiNetworkAddInterceptResult 0%
Motus.BiDiNetworkBytesValue 100%
Motus.BiDiNetworkContinueRequestParams 100%
Motus.BiDiNetworkFailRequestParams 100%
Motus.BiDiNetworkHeader 0%
Motus.BiDiNetworkProvideResponseParams 100%
Motus.BiDiNetworkUrlPattern 0%
Motus.BiDiProtocolException 75%
Motus.BiDiScriptCallFunctionParams 100%
Motus.BiDiScriptCallFunctionResult 0%
Motus.BiDiScriptEvaluateParams 0%
Motus.BiDiScriptEvaluateResult 0%
Motus.BiDiScriptExceptionDetails 0%
Motus.BiDiScriptLocalValue 0%
Motus.BiDiScriptRemoteValue 0%
Motus.BiDiScriptTarget 100%
Motus.BiDiSession 100% 100%
Motus.BiDiSessionCapabilitiesRequest 0%
Motus.BiDiSessionNewParams 0%
Motus.BiDiSessionNewResult 0%
Motus.BiDiSessionRegistry 84.6%
Motus.BiDiSessionStatusResult 0%
Motus.BiDiSessionSubscribeParams 100%
Motus.BiDiTranslationRegistry 100%
Motus.BiDiTransport 98.2% 90%
Motus.Browser 54% 42.8%
Motus.BrowserCloseResult 100%
Motus.BrowserCloseTranslation 50%
Motus.BrowserContext 74% 35.2%
Motus.BrowserFinder 50.4% 65.8%
Motus.BrowserGetVersionResult 100%
Motus.BrowserGetVersionTranslation 83.3% 50%
Motus.BrowserGrantPermissionsParams 100%
Motus.BrowserGrantPermissionsResult 100%
Motus.BrowserHeartbeat 100%
Motus.BrowserLease 100%
Motus.BrowserOutputDrain 100% 100%
Motus.BrowserPool 20% 0%
Motus.BrowserResetPermissionsResult 0%
Motus.BuiltinSelectorsPlugin 75%
Motus.CapabilityGuard 88.8% 83.3%
Motus.CdpCommandEnvelope 100%
Motus.CdpDisconnectedException 50%
Motus.CdpEndpointPoller 75% 50%
Motus.CdpErrorPayload 100%
Motus.CdpInboundEnvelope 100%
Motus.CdpPipeSocket 96.5% 87.5%
Motus.CdpProtocolException 75%
Motus.CdpSession 100% 83.3%
Motus.CdpSessionRegistry 100%
Motus.CdpSocket 75% 0%
Motus.CdpTransport 100% 97%
Motus.ChromiumArgs 100% 100%
Motus.ColorContrastRule 93.1% 89.2%
Motus.ComputedStyleCollector 100%
Motus.ConfigMerge 37.7% 45.8%
Motus.ConsoleApiCalledTranslation 84.2% 25%
Motus.ContrastCalculator 91% 72.5%
Motus.CoverageAggregator 95% 87.2%
Motus.CoverageCollector 95.2% 100%
Motus.CoverageRemapper 96.2% 87.8%
Motus.CoverageSink 72.7% 50%
Motus.CoverageThresholdResult 100%
Motus.CoverageThresholds 100% 100%
Motus.CssEnableResult 0%
Motus.CssRuleUsageEntry 0%
Motus.CssSelectorStrategy 100%
Motus.CssStartRuleUsageTrackingResult 0%
Motus.DebuggerDisableResult 0%
Motus.DetachedFromTargetTranslation 25% 0%
Motus.Dialog 100%
Motus.DialogClosedTranslation 100%
Motus.DialogOpeningTranslation 100% 50%
Motus.DomBoxModel 0%
Motus.DomContentLoadedTranslation 50%
Motus.DomDebuggerEventListener 0%
Motus.DomDebuggerGetEventListenersParams 0%
Motus.DomDebuggerGetEventListenersResult 0%
Motus.DomDescribeNodeParams 100%
Motus.DomDocumentNode 0%
Motus.DomEnableResult 0%
Motus.DomFocusResult 0%
Motus.DomGetBoxModelParams 0%
Motus.DomGetNodeForLocationParams 100%
Motus.DomGetNodeForLocationResult 100%
Motus.DomGetOuterHtmlParams 100%
Motus.DomHideHighlightResult 0%
Motus.DomHighlightConfig 0%
Motus.DomHighlightNodeParams 0%
Motus.DomHighlightNodeResult 0%
Motus.DomNodeDescription 100%
Motus.DomResolveNodeParams 100%
Motus.DomScrollIntoViewIfNeededResult 0%
Motus.DomSetFileInputFilesParams 100%
Motus.DomSetFileInputFilesResult 100%
Motus.Download 40% 0%
Motus.DuplicateIdRule 88.8% 90%
Motus.ElementHandle 100%
Motus.EmptyButtonRule 94.1% 100%
Motus.EmptyLinkRule 94.1% 100%
Motus.EmulationSetDeviceMetricsOverrideParams 100%
Motus.EmulationSetDeviceMetricsOverrideResult 100%
Motus.EmulationSetEmulatedMediaParams 100%
Motus.EmulationSetEmulatedMediaResult 100%
Motus.EmulationSetGeolocationOverrideParams 0%
Motus.EmulationSetGeolocationOverrideResult 0%
Motus.EmulationSetLocaleOverrideResult 100%
Motus.EmulationSetTimezoneOverrideResult 100%
Motus.EmulationSetUserAgentOverrideParams 100%
Motus.EmulationSetUserAgentOverrideResult 100%
Motus.FailureArtifactName 91.3% 94.7%
Motus.FetchAuthChallenge 0%
Motus.FetchAuthChallengeResponse 0%
Motus.FetchAuthRequiredEvent 0%
Motus.FetchContinueRequestParams 100%
Motus.FetchContinueRequestResult 100%
Motus.FetchContinueRequestTranslation 67.8% 42.8%
Motus.FetchContinueWithAuthParams 0%
Motus.FetchContinueWithAuthResult 0%
Motus.FetchDisableResult 100%
Motus.FetchEnableParams 100%
Motus.FetchEnableResult 100%
Motus.FetchEnableTranslation 58.8% 30%
Motus.FetchFailRequestParams 100%
Motus.FetchFailRequestResult 100%
Motus.FetchFailRequestTranslation 71.4% 50%
Motus.FetchFulfillRequestParams 100%
Motus.FetchFulfillRequestResult 100%
Motus.FetchFulfillRequestTranslation 67.8% 42.8%
Motus.FetchRequestPattern 100%
Motus.FetchRequestPausedEvent 100%
Motus.FileChooser 0% 0%
Motus.FirefoxArgs 100% 100%
Motus.FirefoxProfileManager 100% 100%
Motus.Frame 30% 12.5%
Motus.FrameNavigatedTranslation 100% 50%
Motus.GetBySelectors 100% 100%
Motus.GetBySelectorStrategy 96.9% 96.1%
Motus.HarContent 100%
Motus.HarEntry 100%
Motus.HarLog 100%
Motus.HarPage 0%
Motus.HarRecorder 96.4% 79.5%
Motus.HarRequest 100%
Motus.HarResponse 100%
Motus.HarTimings 100%
Motus.HeaderCollection 95.8% 100%
Motus.HeadingHierarchyRule 91.1% 80%
Motus.IMotusSession 0%
Motus.InputDispatchKeyEventParams 100%
Motus.InputDispatchKeyEventResult 100%
Motus.InputDispatchKeyEventTranslation 100% 83.3%
Motus.InputDispatchMouseEventParams 100%
Motus.InputDispatchMouseEventResult 100%
Motus.InputDispatchMouseEventTranslation 72.5% 33.3%
Motus.InputDispatchTouchEventParams 100%
Motus.InputDispatchTouchEventResult 100%
Motus.InputDispatchTouchEventTranslation 83.7% 50%
Motus.InputInsertTextResult 100%
Motus.InputTouchPoint 100%
Motus.InstalledBrowsers 81.8% 100%
Motus.IoCloseResult 100%
Motus.IoReadParams 100%
Motus.IoReadResult 100%
Motus.JsHandle 66.6% 30%
Motus.JsonBuilder 100% 66.6%
Motus.Keyboard 100% 100%
Motus.KeyDefinitions 100% 100%
Motus.LifecycleHookCollection 100%
Motus.LoadEventFiredTranslation 100%
Motus.Locator 88.5% 78.6%
Motus.MappingSegment 100%
Motus.MissingDocumentLanguageRule 92.8% 100%
Motus.MissingLandmarkRule 93.7% 100%
Motus.MjpegAviWriter 100% 50%
Motus.MotusAccessibilityConfig 100%
Motus.MotusAssertionsConfig 100%
Motus.MotusConfigLoader 89.4% 88.5%
Motus.MotusContextConfig 100%
Motus.MotusCoverageConfig 100%
Motus.MotusCoverageCssConfig 0%
Motus.MotusCoverageJsConfig 0%
Motus.MotusFailureConfig 100%
Motus.MotusFlakyConfig 100%
Motus.MotusLaunchConfig 100%
Motus.MotusLauncher 56.2% 100%
Motus.MotusLocatorConfig 100%
Motus.MotusMcpConfig 100%
Motus.MotusPerformanceConfig 100%
Motus.MotusRecorderConfig 100%
Motus.MotusReporterConfig 100%
Motus.MotusRequest 100%
Motus.MotusResponse 100% 50%
Motus.MotusRootConfig 100%
Motus.MotusRoute 58% 45.6%
Motus.MotusShardConfig 100%
Motus.MotusVideo 100%
Motus.MotusViewportConfig 100%
Motus.Mouse 92.8% 78.5%
Motus.NetworkClearBrowserCookiesResult 0%
Motus.NetworkCookieData 100%
Motus.NetworkEmulateNetworkConditionsParams 100%
Motus.NetworkEmulateNetworkConditionsResult 100%
Motus.NetworkEnableParams 100%
Motus.NetworkEnableResult 100%
Motus.NetworkLoadingFailedEvent 100%
Motus.NetworkLoadingFinishedEvent 100%
Motus.NetworkManager 98% 75%
Motus.NetworkRequestData 100%
Motus.NetworkRequestWillBeSentEvent 100%
Motus.NetworkResponseData 100%
Motus.NetworkResponseReceivedEvent 100%
Motus.NetworkSetCookieParams 100%
Motus.NetworkSetExtraHttpHeadersParams 100%
Motus.NetworkSetExtraHttpHeadersResult 100%
Motus.NoOpTranslation 60%
Motus.NullMotusLogger 40%
Motus.NullTracing 0%
Motus.Page 70.1% 65%
Motus.PageBringToFrontResult 0%
Motus.PageCaptureScreenshotParams 0%
Motus.PageCaptureScreenshotWithClipParams 100%
Motus.PageClipRect 100%
Motus.PageCreateIsolatedWorldParams 0%
Motus.PageDownloadProgressEvent 0%
Motus.PageDownloadWillBeginEvent 100%
Motus.PageEnableResult 100%
Motus.PageFileChooserOpenedEvent 0%
Motus.PageFrameInfo 100%
Motus.PageFrameTreeNode 100%
Motus.PageGetFrameTreeTranslation 100% 75%
Motus.PageGetNavigationHistoryResult 0%
Motus.PageHandleJavaScriptDialogResult 0%
Motus.PageJavascriptDialogOpeningEvent 100%
Motus.PageNavigateParams 100%
Motus.PageNavigateResult 100%
Motus.PageNavigateToHistoryEntryResult 0%
Motus.PageNavigateTranslation 100% 50%
Motus.PageReloadResult 100%
Motus.PageReloadTranslation 75% 50%
Motus.PageScreencastFrameAckResult 0%
Motus.PageScreencastFrameEvent 0%
Motus.PageScreencastFrameMetadata 0%
Motus.PageSetInterceptFileChooserDialogResult 0%
Motus.PageStartScreencastParams 100%
Motus.PageStartScreencastResult 100%
Motus.PageStopScreencastResult 0%
Motus.PerformanceBudgetContext 100% 100%
Motus.PerformanceEnableResult 100%
Motus.PerformanceMetricsCollector 94.7% 100%
Motus.PerformanceMetricsSink 100%
Motus.PluginContext 87.5%
Motus.PluginHost 100%
Motus.ProcessStderrAdapter 0%
Motus.ProfilerCoverageRange 0%
Motus.ProfilerEnableResult 0%
Motus.ProfilerFunctionCoverage 0%
Motus.ProfilerScriptCoverage 0%
Motus.ProfilerStartPreciseCoverageParams 0%
Motus.ProfilerStopPreciseCoverageResult 0%
Motus.ProfilerTakePreciseCoverageResult 0%
Motus.ProtocolLog 77.7% 81.4%
Motus.ProtocolLogFile 88.4% 68.7%
Motus.ProtocolLogFormatter 96.5% 93.7%
Motus.ProtocolLogSettings 100% 95.4%
Motus.ProtocolLogSink 86.6% 76.4%
Motus.ReporterCollection 100%
Motus.RequestPausedTranslation 100% 60%
Motus.RequestWillBeSentTranslation 13.3% 0%
Motus.ResponseReceivedTranslation 7.4% 0%
Motus.RoleSelectorStrategy 95.2% 94.4%
Motus.RuntimeAddBindingResult 100%
Motus.RuntimeBindingCalledEvent 0%
Motus.RuntimeCallArgument 100%
Motus.RuntimeCallFunctionOnParams 100%
Motus.RuntimeCallFunctionOnResult 100%
Motus.RuntimeCallFunctionOnTranslation 46.3% 23%
Motus.RuntimeConsoleApiCalledEvent 100%
Motus.RuntimeEnableResult 100%
Motus.RuntimeEvaluateParams 100%
Motus.RuntimeEvaluateResult 100%
Motus.RuntimeEvaluateTranslation 92.3% 50%
Motus.RuntimeExceptionDetails 100%
Motus.RuntimeExceptionThrownEvent 100%
Motus.RuntimeExecutionContextCreatedEvent 100%
Motus.RuntimeExecutionContextDescription 100%
Motus.RuntimeGetPropertiesParams 100%
Motus.RuntimePropertyDescriptor 100%
Motus.RuntimeReleaseObjectResult 0%
Motus.RuntimeReleaseObjectTranslation 50%
Motus.RuntimeRemoteObject 100%
Motus.ScriptResultTranslator 57.6% 22.3%
Motus.SecurityEnableResult 100%
Motus.SecuritySetIgnoreCertificateErrorsResult 100%
Motus.Selectors.DomFingerprint 100%
Motus.Selectors.DomFingerprintBuilder 98% 91.6%
Motus.Selectors.SelectorEntry 100%
Motus.SelectorStrategyHelpers 100%
Motus.SelectorStrategyRegistry 100%
Motus.SourceMap 100%
Motus.SourceMapFetcher 0% 0%
Motus.SourceMapJsonDto 100%
Motus.SourceMapParser 90.3% 77.5%
Motus.SourceMapResolver 93.3% 87.5%
Motus.TargetAttachedToTargetEvent 100%
Motus.TargetAttachToTargetTranslation 62.5% 100%
Motus.TargetCloseTargetTranslation 60% 50%
Motus.TargetCreateBrowserContextParams 100%
Motus.TargetCreateBrowserContextTranslation 50%
Motus.TargetCreateTargetParams 100%
Motus.TargetCreateTargetTranslation 60% 50%
Motus.TargetDetachedFromTargetEvent 0%
Motus.TargetDisposeBrowserContextResult 100%
Motus.TargetDisposeBrowserContextTranslation 50%
Motus.TargetInfo 100%
Motus.TargetSetAutoAttachParams 100%
Motus.TargetSetAutoAttachResult 100%
Motus.TargetSetAutoAttachTranslation 50%
Motus.TargetSetDiscoverTargetsResult 100%
Motus.TestIdSelectorStrategy 100%
Motus.TestMethodNameContext 100%
Motus.TextSelectorStrategy 100%
Motus.Touchscreen 100%
Motus.Tracing 82.6% 77%
Motus.TracingEndResult 100%
Motus.TracingStartParams 100%
Motus.TracingStartResult 100%
Motus.TracingTraceConfig 100%
Motus.TracingTracingCompleteEvent 100%
Motus.UnlabeledFormControlRule 95.4% 100%
Motus.VideoRecorder 90.9% 100%
Motus.Vlq 100% 100%
Motus.WindowsProcessGuard 0% 0%
Motus.XPathSelectorStrategy 100%
System.Text.Json.Serialization.JsonStringEnumConverter`1 0% 0%
System.Text.Json.Serialization.JsonStringEnumMemberNameAttribute 0%
Motus.Abstractions - 87.7%
Name Line Branch
Motus.Abstractions 87.7% 100%
Motus.Abstractions.AccessibilityAuditContext 100%
Motus.Abstractions.AccessibilityAuditResult 100%
Motus.Abstractions.AccessibilityNode 100%
Motus.Abstractions.AccessibilitySnapshot 100%
Motus.Abstractions.AccessibilityViolation 100%
Motus.Abstractions.ActionTimeoutException 50%
Motus.Abstractions.AmbiguousSelectorException 50%
Motus.Abstractions.BrowserFailure 100% 100%
Motus.Abstractions.ComputedStyleInfo 100%
Motus.Abstractions.Cookie 100%
Motus.Abstractions.CoverageData 100% 100%
Motus.Abstractions.CoverageSummary 100%
Motus.Abstractions.ElementNotFoundException 100%
Motus.Abstractions.IBrowser 0%
Motus.Abstractions.LayoutShiftEntry 100%
Motus.Abstractions.MotusAssertionException 50%
Motus.Abstractions.MotusException 100%
Motus.Abstractions.MotusNavigationException 50%
Motus.Abstractions.MotusProtocolException 100%
Motus.Abstractions.MotusSelectorException 100%
Motus.Abstractions.MotusTargetClosedException 100%
Motus.Abstractions.MotusTimeoutException 50%
Motus.Abstractions.MouseButtonOptions 100%
Motus.Abstractions.MouseMoveOptions 100%
Motus.Abstractions.NavigationTimeoutException 50%
Motus.Abstractions.OriginalFileCoverage 100%
Motus.Abstractions.PerformanceBudget 100%
Motus.Abstractions.PerformanceBudgetAttribute 100% 100%
Motus.Abstractions.PerformanceBudgetEntry 100%
Motus.Abstractions.PerformanceBudgetResult 100%
Motus.Abstractions.PerformanceMetrics 100%
Motus.Abstractions.ProxySettings 100%
Motus.Abstractions.RouteContinueOptions 100%
Motus.Abstractions.ScriptCoverage 100%
Motus.Abstractions.StorageState 100%
Motus.Abstractions.StylesheetCoverage 100%
Motus.Abstractions.TestInfo 100%
Motus.Abstractions.TestResult 100%
Motus.Abstractions.TestRunSummary 100%
Motus.Abstractions.TestSuiteInfo 100%
Motus.Abstractions.WaitTimeoutException 50%
Motus.Analyzers - 91%
Name Line Branch
Motus.Analyzers 91% 72.4%
Motus.Analyzers.Analyzers.DeprecatedSelectorAnalyzer 90.6% 61.1%
Motus.Analyzers.Analyzers.FragileSelectorAnalyzer 92.1% 65%
Motus.Analyzers.Analyzers.HardcodedDelayAnalyzer 96.1% 81.2%
Motus.Analyzers.Analyzers.MissingDisposalAnalyzer 100% 100%
Motus.Analyzers.Analyzers.NavigationWaitAnalyzer 93.4% 77%
Motus.Analyzers.Analyzers.NonAwaitedCallAnalyzer 90.9% 75%
Motus.Analyzers.Analyzers.UnusedLocatorAnalyzer 94.5% 64.2%
Motus.Analyzers.CodeFixes.AddAwaitCodeFix 0%
Motus.Analyzers.CodeFixes.ReplaceDelayCodeFix 56.2% 50%
Motus.Analyzers.CodeFixes.WrapAwaitUsingCodeFix 0%
Motus.Analyzers.SymbolHelper 100% 82.1%
Motus.Cli - 82.1%
Name Line Branch
Motus.Cli 82.1% 61%
Motus.Cli.Commands.BrowserPathHelper 88.8% 50%
Motus.Cli.Commands.CheckSelectorsCommand 100%
Motus.Cli.Commands.CodegenCommand 93.8% 0%
Motus.Cli.Commands.InstallCommand 100%
Motus.Cli.Commands.McpCommand 96.8% 60.8%
Motus.Cli.Commands.PdfCommand 100%
Motus.Cli.Commands.RecordCommand 94.2%
Motus.Cli.Commands.RunCommand 94.4% 0%
Motus.Cli.Commands.ScreenshotCommand 100%
Motus.Cli.Commands.ShardCommand 0%
Motus.Cli.Commands.TraceCommand 0%
Motus.Cli.Commands.TrxCommand 100%
Motus.Cli.Commands.UpdateProtocolCommand 100%
Motus.Cli.Services.BrowserInstaller 2.1% 0%
Motus.Cli.Services.CheckSelectorsRunner 0% 0%
Motus.Cli.Services.DomainDiff 100%
Motus.Cli.Services.FingerprintCandidate 100%
Motus.Cli.Services.FingerprintMatch 0%
Motus.Cli.Services.FingerprintScanner 0% 0%
Motus.Cli.Services.FlakeHistoryReporter 86.6% 100%
Motus.Cli.Services.InteractiveRepairApplier 85.7% 75%
Motus.Cli.Services.LocatorDispatcher 26.3% 10.8%
Motus.Cli.Services.ParsedSelector 100%
Motus.Cli.Services.ProtocolDiff 100% 100%
Motus.Cli.Services.ProtocolDiffer 97.2% 95.4%
Motus.Cli.Services.ProtocolUpdater 0% 0%
Motus.Cli.Services.RepairSuggestion 100%
Motus.Cli.Services.RepairSuggestionPipeline 75% 75%
Motus.Cli.Services.Reporters.CoberturaReporter 62.5% 54.1%
Motus.Cli.Services.Reporters.CompositeReporter 100%
Motus.Cli.Services.Reporters.ConsoleReporter 63.1% 50%
Motus.Cli.Services.Reporters.CoverageConsoleReporter 88.6% 70.8%
Motus.Cli.Services.Reporters.CoverageHtmlReporter 91.4% 88.2%
Motus.Cli.Services.Reporters.CoverageReporterFactory 100% 95.8%
Motus.Cli.Services.Reporters.HtmlReporter 92.3% 100%
Motus.Cli.Services.Reporters.JUnitReporter 100% 100%
Motus.Cli.Services.Reporters.ReporterFactory 100% 100%
Motus.Cli.Services.Reporters.TrxReporter 100%
Motus.Cli.Services.SelectorCheckResult 100%
Motus.Cli.Services.SelectorCheckTablePrinter 93.6% 78.3%
Motus.Cli.Services.SelectorManifestWriter 100% 87.5%
Motus.Cli.Services.SelectorParser 94.2% 88.8%
Motus.Cli.Services.SelectorParseResult 100%
Motus.Cli.Services.SelectorParseWarning 100%
Motus.Cli.Services.SelectorRewriter 77.6% 67.1%
Motus.Cli.Services.ShardMerger 91.3% 66.4%
Motus.Cli.Services.ShardMergeResult 100% 100%
Motus.Cli.Services.ShardSelector 93.3% 86.3%
Motus.Cli.Services.SuggestionBuilder 100% 91.6%
Motus.Cli.Services.TestDiscovery 93.1% 80%
Motus.Cli.Services.TestRunner 82.6% 85.7%
Motus.Codegen - 89.8%
Name Line Branch
Motus.Codegen 89.8% 70.6%
Motus.Codegen.CdpGenerator 100%
Motus.Codegen.Emit.DomainEmitter 84.9% 71.4%
Motus.Codegen.Emit.NamingHelper 100% 92.8%
Motus.Codegen.Emit.PluginRegistryEmitter 100% 100%
Motus.Codegen.Emit.TypeResolver 75% 55%
Motus.Codegen.Model.PluginTypeInfo 44.4% 0%
Motus.Codegen.Parser.CdpSchemaParser 93.4% 85.2%
Motus.Codegen.PluginDiscoveryGenerator 97.5% 91.1%
Motus.Mcp - 91.9%
Name Line Branch
Motus.Mcp 91.9% 80.2%
Motus.Mcp.AccessibilityTools 100% 50%
Motus.Mcp.ActionReport 89.7% 69.4%
Motus.Mcp.ActionRunner 100%
Motus.Mcp.ActivePageService 88.8% 100%
Motus.Mcp.BrowserSessionManager 78.2% 75%
Motus.Mcp.ConsoleEntry 50% 0%
Motus.Mcp.ConsoleService 96.8% 94.4%
Motus.Mcp.ConsoleTools 100% 100%
Motus.Mcp.ContextTools 92.8% 87.5%
Motus.Mcp.CoordinateTools 100%
Motus.Mcp.CoreTools 100%
Motus.Mcp.DialogNotice 97.3% 94.7%
Motus.Mcp.DialogService 100% 95%
Motus.Mcp.FrameCollector 100% 100%
Motus.Mcp.InlineFrames 75% 100%
Motus.Mcp.InteractionTools 66.6% 13.8%
Motus.Mcp.LogText 90% 83.3%
Motus.Mcp.McpServerConfiguration 100% 81.8%
Motus.Mcp.McpServerHost 0%
Motus.Mcp.McpServerLaunchOptions 85% 87.5%
Motus.Mcp.McpSessionBundle 100% 50%
Motus.Mcp.McpSessionRegistry 83.3% 50%
Motus.Mcp.NetworkEntry 100% 87.5%
Motus.Mcp.NetworkService 91.5% 90.6%
Motus.Mcp.NetworkTools 100% 100%
Motus.Mcp.PageDescription 100% 100%
Motus.Mcp.PageSnapshotService 94.1% 92.8%
Motus.Mcp.PageTools 100% 100%
Motus.Mcp.PerformanceTools 100% 100%
Motus.Mcp.SecurityPolicy 88.1% 82.2%
Motus.Mcp.SerializedSnapshot 100%
Motus.Mcp.SnapshotNotTakenException 100%
Motus.Mcp.SnapshotSerializer 94.9% 91.3%
Motus.Mcp.StaleRefException 100%
Motus.Mcp.ToolArguments 92% 96.8%
Motus.Mcp.ToolCapabilities 100% 80%
Motus.Mcp.ToolResultHelper 100% 100%
Motus.Mcp.Http - 98.6%
Name Line Branch
Motus.Mcp.Http 98.6% 80%
Motus.Mcp.Http.McpHttpServerHost 98.6% 80%
Motus.Recorder - 77.8%
Name Line Branch
Motus.Recorder 77.8% 70.8%
Motus.Recorder.ActionCapture.ActionCaptureEngine 45.1% 28.2%
Motus.Recorder.ActionCapture.InputStateMachine 99.4% 91.7%
Motus.Recorder.ActionCapture.RecorderScript 100%
Motus.Recorder.CodeEmit.ActionLineEmitter 79.6% 77.5%
Motus.Recorder.CodeEmit.CodeEmitter 83.3% 78.9%
Motus.Recorder.CodeEmit.EmittedLocator 100%
Motus.Recorder.CodeEmit.FrameworkTemplate 97.4% 83.3%
Motus.Recorder.PageAnalysis.DiscoveredElement 100%
Motus.Recorder.PageAnalysis.MemberNameDeriver 94.8% 90.7%
Motus.Recorder.PageAnalysis.PageAnalysisEngine 0.7% 0%
Motus.Recorder.PageAnalysis.PageClassNameDeriver 91.3% 88.8%
Motus.Recorder.PageAnalysis.PageElementInfo 100%
Motus.Recorder.PageAnalysis.SelectorStrategyOrdering 100% 100%
Motus.Recorder.PomEmit.FormGrouper 90.3% 49.3%
Motus.Recorder.PomEmit.PomEmitter 95.6% 86.3%
Motus.Recorder.Records.ActionRecord 100%
Motus.Recorder.Records.CheckAction 100%
Motus.Recorder.Records.ClickAction 100%
Motus.Recorder.Records.DialogAction 100%
Motus.Recorder.Records.FileUploadAction 100%
Motus.Recorder.Records.FillAction 100%
Motus.Recorder.Records.KeyPressAction 100%
Motus.Recorder.Records.NavigationAction 100%
Motus.Recorder.Records.ResolvedAction 100%
Motus.Recorder.Records.ScrollAction 100%
Motus.Recorder.Records.SelectAction 100%
Motus.Recorder.SelectorInference.SelectorInferenceEngine 100% 100%
Motus.Recorder.SelectorInference.SelectorInferenceResult 100%
Motus.Testing - 75.4%
Name Line Branch
Motus.Testing 75.4% 61.1%
Motus.Testing.BrowserFixture 88.6% 78.5%
Motus.Testing.FailureTracing 30.7% 0%
Motus.Testing.MSTest - 79%
Name Line Branch
Motus.Testing.MSTest 79% 79.4%
Motus.Testing.MSTest.MotusTestBase 70.4% 75%
Motus.Testing.MSTest.MotusTestClassAttribute 100% 100%
Motus.Testing.MSTest.MotusTestMethodAttribute 100% 87.5%
Motus.Testing.xUnit - 63.6%
Name Line Branch
Motus.Testing.xUnit 63.6% 33.3%
Motus.Testing.xUnit.BrowserContextFixture 71.4% 33.3%
Motus.Testing.xUnit.BrowserContextFixture`1 100%
Motus.Testing.xUnit.DefaultBrowser 0%
Motus.Testing.xUnit.SharedBrowserFixture 25%

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
TorreyBetts merged commit 9b4b96d into main Oct 24, 2026
5 checks passed
@TorreyBetts
TorreyBetts deleted the fix/installed-browser branch October 24, 2026 18:28
TorreyBetts added a commit that referenced this pull request Oct 24, 2026
Brings in #31, #32, #33, #35, #36, #37 and #38, including the MSTest 4 package, before merging. No conflicts.

Signed-off-by: Torrey Betts <torrey.betts@gmail.com>
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tests run with dotnet test don't use the browser that motus install downloaded

1 participant