Skip to content

Translate locator resolution to WebDriver BiDi so locators work on Firefox - #44

Merged
TorreyBetts merged 1 commit into
mainfrom
fix/firefox-locators
Oct 24, 2026
Merged

TorreyBetts merged 1 commit into
mainfrom
fix/firefox-locators

Conversation

@TorreyBetts

@TorreyBetts TorreyBetts commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

On Firefox no locator could find an element. Every selector strategy that queries the page evaluates its query to an array of elements and reads each one back with Runtime.getProperties, which had no WebDriver BiDi translation, so locator actions, the assertions and anything built on them failed before looking at the page. That was only the first gap on the path: the call translation sent its object reference in a shape BiDi rejects and dropped any argument that was not a plain value, and results came back as BiDi typed remote values instead of JSON, so a click never got its bounding box and an object returned from script arrived as key and value pairs.

Runtime.getProperties now becomes a script.callFunction that returns the object to itself one level deep, and each element or entry becomes a property. DOM nodes are handed out by their BiDi shared id, prefixed so they can be told apart from handles when they come back as this or as an argument, which also gives an element the same id whichever query found it, so the locator's de-duplication works as on Chromium. Call arguments become BiDi local values (elements, arrays and objects included, an empty one as undefined so later ones keep their positions), results are rebuilt as the JSON a CDP call by value returns, and DOM.setFileInputFiles translates to input.setFiles. A locator rooted at the main frame is measured like a page-level one rather than through the Chromium-only box model.

GetByRole, role= selectors and the accessible name and role assertions read the accessibility tree, which BiDi does not expose. They stay Chromium-only and now fail at once on Firefox with a message that says why. The frame context id the issue mentions needed nothing, since BiDi resolves no context ids, but a Firefox page still reports no child frames, so a locator inside an iframe has no IFrame to start from. That, ILocator.ScreenshotAsync (no Page.captureScreenshot translation) and DblClickAsync (Firefox sees two single clicks) remain open and are documented.

Behavior changes: locators, locator actions and locator assertions work on Firefox apart from the cases above. On Firefox, objects and arrays returned from script arrive as plain JSON instead of BiDi remote values. On Firefox, GetByRole and role= selectors throw NotSupportedException with a new message naming the accessibility tree, and ToHaveAccessibleNameAsync and ToHaveRoleAsync throw it before resolving the element instead of after. A locator built from page.MainFrame measures and scrolls exactly like one built from the page, and on Chromium no longer sends DOM.getBoxModel for it.

Fixes #41

Signed-off-by: Torrey Betts torrey.betts@gmail.com

…refox

Every selector strategy that queries the page evaluates to an array of
elements and reads each one back with Runtime.getProperties, which had no
BiDi translation, so no locator, locator action or assertion could find an
element on Firefox. Adding that translation alone was not enough: the call
translation sent its object reference as { type: "handle", value } and
dropped any argument that was not a plain value, and results came back in
BiDi's typed remote value shape instead of plain JSON, so a bounding box,
a selected option list or an element passed as an argument never arrived.

Runtime.getProperties now becomes a script.callFunction that returns the
object to itself one level deep. Nodes are handed out by their BiDi shared
id, prefixed so they can be told apart from handles when they come back as
this or as an argument, which also gives an element the same id whichever
query found it. Arguments become BiDi local values, results are rebuilt as
the JSON a CDP call by value returns, and DOM.setFileInputFiles becomes
input.setFiles. A locator rooted at the main frame is now measured like a
page-level one instead of through the Chromium-only box model.

GetByRole, role= selectors and the accessible name and role assertions read
the accessibility tree, which BiDi does not expose. They stay Chromium-only
and now fail at once on Firefox with a message that says why.

Signed-off-by: Torrey Betts <torrey.betts@gmail.com>
@github-actions

Copy link
Copy Markdown

Summary

Summary
Generated on: 10/24/2026 - 22:02:06
Coverage date: 10/24/2026 - 21:57:10 - 10/24/2026 - 22:01:56
Parser: MultiReport (40x Cobertura)
Assemblies: 12
Classes: 579
Files: 292
Line coverage: 82.7% (9969 of 12045)
Covered lines: 9969
Uncovered lines: 2076
Coverable lines: 12045
Total lines: 43031
Branch coverage: 71.3% (3795 of 5320)
Covered branches: 3795
Total branches: 5320
Method coverage: Feature is only available for sponsors

Coverage

Motus - 81.6%
Name Line Branch
Motus 81.6% 72.9%
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% 83.3%
Motus.BiDiInboundDiscriminator 100%
Motus.BiDiInputAction 100%
Motus.BiDiInputActionSequence 100%
Motus.BiDiInputPerformActionsParams 100%
Motus.BiDiInputSetFilesParams 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.BiDiScriptRemoteValue 0%
Motus.BiDiScriptSerializationOptions 100%
Motus.BiDiScriptTarget 100%
Motus.BiDiScriptValues 84% 57.9%
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% 41.1%
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 78.2% 68.7%
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.DomSetFileInputFilesTranslation 87.5% 50%
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.EmulationSetFocusEmulationEnabledResult 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.FragmentNavigatedTranslation 100% 50%
Motus.Frame 45.9% 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.HistoryUpdatedTranslation 100% 50%
Motus.IBiDiEventTranslation 100%
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% 72.2%
Motus.Keyboard 100% 100%
Motus.KeyDefinitions 100% 100%
Motus.LifecycleHookCollection 100%
Motus.LoadEventFiredTranslation 100%
Motus.Locator 88.6% 78.1%
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 73.6% 71.3%
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.PageNavigatedWithinDocumentEvent 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 95.8% 85.7%
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.RuntimeExecutionContextDestroyedEvent 100%
Motus.RuntimeGetPropertiesParams 100%
Motus.RuntimeGetPropertiesTranslation 89.4% 78.1%
Motus.RuntimePropertyDescriptor 100%
Motus.RuntimeReleaseObjectResult 0%
Motus.RuntimeReleaseObjectTranslation 50%
Motus.RuntimeRemoteObject 100%
Motus.ScriptResultTranslator 92.8% 75%
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 100%
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.2%
Name Line Branch
Motus.Cli 82.2% 61.5%
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% 16.6%
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 95.3% 88.2%
Motus.Cli.Services.TestRunner 84% 81.2%
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.MSTest.v4 - 22.8%
Name Line Branch
Motus.Testing.MSTest.v4 22.8% 22.2%
Motus.Testing.MSTest.MotusTestBase 0% 0%
Motus.Testing.MSTest.MotusTestClassAttribute 100% 100%
Motus.Testing.MSTest.MotusTestMethodAttribute 100% 60%
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%

@TorreyBetts

Copy link
Copy Markdown
Contributor Author

Tests run for this change:

  • New FirefoxLocatorIntegrationTests (Integration and Firefox categories, so they run in the Firefox CI job): click, click through a main-frame locator, fill, every in-page strategy (CSS, XPath, text=, GetByText, GetByLabel, GetByPlaceholder, GetByTestId, GetByAltText, GetByTitle), chained and parent locators with de-duplication, click with scroll into view, check and uncheck with state confirmation, a cancelled click reported by CheckAsync, assertions that wait for an element and fail at the timeout with "element not found", element and structured arguments (SelectOptionAsync, EvaluateWithElementAsync, DispatchEventAsync), SetInputFilesAsync, hover, tap, clear, type, press and the queries, and the clear failures for GetByRole and ToHaveRoleAsync. Before the fix every locator test failed on the missing Runtime.getProperties translation and the GetByRole test on its message; all 14 pass now.
  • New unit tests in BiDiTranslationTests for this and argument references, local values, result values, Runtime.getProperties and DOM.setFileInputFiles.
  • Non-browser unit tests for the whole solution pass on net8.0 and net10.0 (Motus.Tests 1263, Mcp 368, Cli 320 with 2 skipped, Recorder 105, Codegen 59, Analyzers 29, MSTest.v4 12, xUnit 8).
  • Browser tests on macOS with Chromium and Firefox 158, net8.0 then net10.0, 340 of 340 each: the new Firefox class, FirefoxIntegrationTests, FirefoxKeyboardIntegrationTests, WaitForUrlIntegrationTests, LocatorTests, ActionabilityTests, LocatorDomScopingTests, LocatorParentNavigationTests, LocatorEvaluateWithElementTests, LocatorSetInputFilesTests, ScrollIntoViewTests, FrameLocatorTests, GetByLocatorTests, AccessibilityAssertionTests, LocatorAssertionsTests, AssertionRetryIntegrationTests and OutOfProcessFrameTests.
  • First CI run: the Firefox job failed one existing test, Firefox_ScrollIntoViewScript_ScrollsOnlyWhenNeeded, on net10.0 only (scrollY 4678 against 4679, a 1px drift between two page.EvaluateAsync reads; it passed on net8.0 in the same job). The test runs the scroll script directly and reads plain numbers, which this change does not alter, so I reran the failed jobs.

@TorreyBetts
TorreyBetts merged commit 4a75459 into main Oct 24, 2026
12 of 14 checks passed
@TorreyBetts
TorreyBetts deleted the fix/firefox-locators branch October 24, 2026 22:51
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.

No locator can find an element on Firefox, because Runtime.getProperties has no WebDriver BiDi translation

1 participant