From 1bfc70e45a301d40a3f3dd4251fa3595314f4c30 Mon Sep 17 00:00:00 2001 From: Torrey Betts Date: Sat, 24 Oct 2026 17:53:34 -0400 Subject: [PATCH] Translate locator resolution to WebDriver BiDi so locators work on Firefox 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 --- docs/architecture/selectors-and-assertions.md | 10 +- docs/architecture/transport-and-protocol.md | 4 + docs/getting-started.md | 2 +- docs/guides/frames-and-iframes.md | 2 + docs/guides/mcp-server.md | 4 +- src/Motus/Locator/Locator.cs | 17 +- src/Motus/Selectors/RoleSelectorStrategy.cs | 4 +- src/Motus/Transport/BiDi/BiDiJsonContext.cs | 20 +- src/Motus/Transport/BiDi/BiDiScriptValues.cs | 319 ++++++++++++++++ .../Transport/BiDi/BiDiTranslationRegistry.cs | 210 ++++++---- src/Motus/Transport/MotusCapabilities.cs | 18 + .../Browser/FirefoxIntegrationTests.cs | 2 +- .../Locator/FirefoxLocatorIntegrationTests.cs | 358 ++++++++++++++++++ .../Transport/BiDi/BiDiTranslationTests.cs | 158 ++++++++ 14 files changed, 1031 insertions(+), 97 deletions(-) create mode 100644 src/Motus/Transport/BiDi/BiDiScriptValues.cs create mode 100644 tests/Motus.Tests/Locator/FirefoxLocatorIntegrationTests.cs diff --git a/docs/architecture/selectors-and-assertions.md b/docs/architecture/selectors-and-assertions.md index a33aa03..a90183b 100644 --- a/docs/architecture/selectors-and-assertions.md +++ b/docs/architecture/selectors-and-assertions.md @@ -51,7 +51,7 @@ The text-based factories write their text as a JSON string literal followed by a `GetByLabel` reads an element's labels in the same order of precedence a browser computes a name from: the elements named by `aria-labelledby` when it resolves to any, otherwise a non-empty `aria-label`, otherwise the `