diff options
Diffstat (limited to 'remote/webdriver-bidi/modules/windowglobal')
-rw-r--r-- | remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs | 228 | ||||
-rw-r--r-- | remote/webdriver-bidi/modules/windowglobal/input.sys.mjs | 4 |
2 files changed, 165 insertions, 67 deletions
diff --git a/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs index ef61954284..6dbd5440e0 100644 --- a/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs +++ b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs @@ -7,6 +7,8 @@ import { WindowGlobalBiDiModule } from "chrome://remote/content/webdriver-bidi/m const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { + accessibility: + "chrome://remote/content/shared/webdriver/Accessibility.sys.mjs", AnimationFramePromise: "chrome://remote/content/shared/Sync.sys.mjs", assert: "chrome://remote/content/shared/webdriver/Assert.sys.mjs", ClipRectangleType: @@ -48,6 +50,66 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { this.#subscribedEvents = null; } + /** + * Collect nodes using accessibility attributes. + * + * @see https://w3c.github.io/webdriver-bidi/#collect-nodes-using-accessibility-attributes + */ + async #collectNodesUsingAccessibilityAttributes( + contextNodes, + selector, + maxReturnedNodeCount, + returnedNodes + ) { + if (returnedNodes === null) { + returnedNodes = []; + } + + for (const contextNode of contextNodes) { + let match = true; + + if (contextNode.nodeType === ELEMENT_NODE) { + if ("role" in selector) { + const role = await lazy.accessibility.getComputedRole(contextNode); + + if (selector.role !== role) { + match = false; + } + } + + if ("name" in selector) { + const name = await lazy.accessibility.getAccessibleName(contextNode); + if (selector.name !== name) { + match = false; + } + } + } else { + match = false; + } + + if (match) { + if ( + maxReturnedNodeCount !== null && + returnedNodes.length === maxReturnedNodeCount + ) { + break; + } + returnedNodes.push(contextNode); + } + + const childNodes = [...contextNode.children]; + + await this.#collectNodesUsingAccessibilityAttributes( + childNodes, + selector, + maxReturnedNodeCount, + returnedNodes + ); + } + + return returnedNodes; + } + #getNavigationInfo(data) { // Note: the navigation id is collected in the parent-process and will be // added via event interception by the windowglobal-in-root module. @@ -85,75 +147,29 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { ); } - #startListening() { - if (this.#subscribedEvents.size == 0) { - this.#loadListener.startListening(); - } - } - - #stopListening() { - if (this.#subscribedEvents.size == 0) { - this.#loadListener.stopListening(); - } - } - - #subscribeEvent(event) { - switch (event) { - case "browsingContext._documentInteractive": - this.#startListening(); - this.#subscribedEvents.add("browsingContext._documentInteractive"); - break; - case "browsingContext.domContentLoaded": - this.#startListening(); - this.#subscribedEvents.add("browsingContext.domContentLoaded"); - break; - case "browsingContext.load": - this.#startListening(); - this.#subscribedEvents.add("browsingContext.load"); - break; - } - } - - #unsubscribeEvent(event) { - switch (event) { - case "browsingContext._documentInteractive": - this.#subscribedEvents.delete("browsingContext._documentInteractive"); - break; - case "browsingContext.domContentLoaded": - this.#subscribedEvents.delete("browsingContext.domContentLoaded"); - break; - case "browsingContext.load": - this.#subscribedEvents.delete("browsingContext.load"); - break; - } - - this.#stopListening(); - } - - #onDOMContentLoaded = (eventName, data) => { - if (this.#subscribedEvents.has("browsingContext._documentInteractive")) { - this.messageHandler.emitEvent("browsingContext._documentInteractive", { - baseURL: data.target.baseURI, - contextId: this.messageHandler.contextId, - documentURL: data.target.URL, - innerWindowId: this.messageHandler.innerWindowId, - readyState: data.target.readyState, - }); - } - - if (this.#subscribedEvents.has("browsingContext.domContentLoaded")) { - this.emitEvent( - "browsingContext.domContentLoaded", - this.#getNavigationInfo(data) + /** + * Locate nodes using accessibility attributes. + * + * @see https://w3c.github.io/webdriver-bidi/#locate-nodes-using-accessibility-attributes + */ + async #locateNodesUsingAccessibilityAttributes( + contextNodes, + selector, + maxReturnedNodeCount + ) { + if (!("role" in selector) && !("name" in selector)) { + throw new lazy.error.InvalidSelectorError( + "Locating nodes by accessibility attributes requires `role` or `name` arguments" ); } - }; - #onLoad = (eventName, data) => { - if (this.#subscribedEvents.has("browsingContext.load")) { - this.emitEvent("browsingContext.load", this.#getNavigationInfo(data)); - } - }; + return this.#collectNodesUsingAccessibilityAttributes( + contextNodes, + selector, + maxReturnedNodeCount, + null + ); + } /** * Locate nodes using css selector. @@ -259,6 +275,31 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { return new DOMRect(x, y, width, height); } + #onDOMContentLoaded = (eventName, data) => { + if (this.#subscribedEvents.has("browsingContext._documentInteractive")) { + this.messageHandler.emitEvent("browsingContext._documentInteractive", { + baseURL: data.target.baseURI, + contextId: this.messageHandler.contextId, + documentURL: data.target.URL, + innerWindowId: this.messageHandler.innerWindowId, + readyState: data.target.readyState, + }); + } + + if (this.#subscribedEvents.has("browsingContext.domContentLoaded")) { + this.emitEvent( + "browsingContext.domContentLoaded", + this.#getNavigationInfo(data) + ); + } + }; + + #onLoad = (eventName, data) => { + if (this.#subscribedEvents.has("browsingContext.load")) { + this.emitEvent("browsingContext.load", this.#getNavigationInfo(data)); + } + }; + /** * Create a new rectangle which will be an intersection of * rectangles specified as arguments. @@ -288,6 +329,51 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { return new DOMRect(x_min, y_min, width, height); } + #startListening() { + if (this.#subscribedEvents.size == 0) { + this.#loadListener.startListening(); + } + } + + #stopListening() { + if (this.#subscribedEvents.size == 0) { + this.#loadListener.stopListening(); + } + } + + #subscribeEvent(event) { + switch (event) { + case "browsingContext._documentInteractive": + this.#startListening(); + this.#subscribedEvents.add("browsingContext._documentInteractive"); + break; + case "browsingContext.domContentLoaded": + this.#startListening(); + this.#subscribedEvents.add("browsingContext.domContentLoaded"); + break; + case "browsingContext.load": + this.#startListening(); + this.#subscribedEvents.add("browsingContext.load"); + break; + } + } + + #unsubscribeEvent(event) { + switch (event) { + case "browsingContext._documentInteractive": + this.#subscribedEvents.delete("browsingContext._documentInteractive"); + break; + case "browsingContext.domContentLoaded": + this.#subscribedEvents.delete("browsingContext.domContentLoaded"); + break; + case "browsingContext.load": + this.#subscribedEvents.delete("browsingContext.load"); + break; + } + + this.#stopListening(); + } + /** * Internal commands */ @@ -425,7 +511,7 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { return this.#rectangleIntersection(originRect, clipRect); } - _locateNodes(params = {}) { + async _locateNodes(params = {}) { const { locator, maxNodeCount, serializationOptions, startNodes } = params; const realm = this.messageHandler.getRealm(); @@ -451,6 +537,14 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { let returnedNodes; switch (locator.type) { + case lazy.LocatorType.accessibility: { + returnedNodes = await this.#locateNodesUsingAccessibilityAttributes( + contextNodes, + locator.value, + maxNodeCount + ); + break; + } case lazy.LocatorType.css: { returnedNodes = this.#locateNodesUsingCss( contextNodes, diff --git a/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs index b91cce2310..8db2cbb30b 100644 --- a/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs +++ b/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs @@ -34,6 +34,10 @@ class InputModule extends WindowGlobalBiDiModule { const actionChain = lazy.action.Chain.fromJSON(this.#actionState, actions); await actionChain.dispatch(this.#actionState, this.messageHandler.window); + + // Terminate the current wheel transaction if there is one. Wheel + // transactions should not live longer than a single action chain. + ChromeUtils.endWheelTransaction(); } async releaseActions() { |