commit 609c38bdbf7b08d1cb2474cdcfd6eb555d536b41
parent 36a1a31a845505aba93113af554560e6d42496f0
Author: Julian Descottes <jdescottes@mozilla.com>
Date: Fri, 31 Oct 2025 15:25:39 +0000
Bug 1941270 - [bidi] Add support for context locator to browsingContext.locateNodes r=Sasha
Differential Revision: https://phabricator.services.mozilla.com/D270837
Diffstat:
4 files changed, 86 insertions(+), 36 deletions(-)
diff --git a/remote/webdriver-bidi/modules/root/browsingContext.sys.mjs b/remote/webdriver-bidi/modules/root/browsingContext.sys.mjs
@@ -111,6 +111,7 @@ const DownloadEndStatus = {
*/
export const LocatorType = {
accessibility: "accessibility",
+ context: "context",
css: "css",
innerText: "innerText",
xpath: "xpath",
@@ -953,8 +954,8 @@ class BrowsingContextModule extends RootBiDiModule {
/**
* Used as an argument for browsingContext.locateNodes command, as one of the available variants
- * {AccessibilityLocator}, {CssLocator}, {InnerTextLocator} or {XPathLocator}, to represent a way of how lookup of nodes
- * is going to be performed.
+ * {AccessibilityLocator}, {ContextLocator}, {CssLocator}, {InnerTextLocator} or {XPathLocator},
+ * to represent a way of how lookup of nodes is going to be performed.
*
* @typedef Locator
*/
@@ -980,6 +981,25 @@ class BrowsingContextModule extends RootBiDiModule {
*/
/**
+ * Used as a value argument for browsingContext.locateNodes command
+ * in case of a lookup for a context container.
+ *
+ * @typedef ContextLocatorValue
+ *
+ * @property {string} context
+ */
+
+ /**
+ * Used as an argument for browsingContext.locateNodes command
+ * to represent a lookup for a context container.
+ *
+ * @typedef ContextLocator
+ *
+ * @property {LocatorType} [type=LocatorType.context]
+ * @property {ContextLocatorValue} value
+ */
+
+ /**
* Used as an argument for browsingContext.locateNodes command
* to represent a lookup by css selector.
*
@@ -1042,7 +1062,7 @@ class BrowsingContextModule extends RootBiDiModule {
*/
async locateNodes(options = {}) {
const {
- context: contextId,
+ context: navigableId,
locator,
maxNodeCount = null,
serializationOptions,
@@ -1050,11 +1070,11 @@ class BrowsingContextModule extends RootBiDiModule {
} = options;
lazy.assert.string(
- contextId,
- lazy.pprint`Expected "context" to be a string, got ${contextId}`
+ navigableId,
+ lazy.pprint`Expected "context" to be a string, got ${navigableId}`
);
- const context = this.#getBrowsingContext(contextId);
+ const context = this.#getBrowsingContext(navigableId);
lazy.assert.object(
locator,
@@ -1104,10 +1124,46 @@ class BrowsingContextModule extends RootBiDiModule {
}
}
+ if (locator.type == LocatorType.context) {
+ if (startNodes !== null) {
+ throw new lazy.error.InvalidArgumentError(
+ `Expected "startNodes" to be null when using "locator.type" "${locator.type}", ` +
+ lazy.pprint`got ${startNodes}`
+ );
+ }
+
+ lazy.assert.object(
+ locator.value,
+ `Expected "locator.value" of "locator.type" "${locator.type}" to be an object, ` +
+ lazy.pprint`got ${locator.value}`
+ );
+ const selector = locator.value;
+ const contextId = selector.context;
+ lazy.assert.string(
+ contextId,
+ `Expected "locator.value.context" of "locator.type" "${locator.type}" to be a string, ` +
+ lazy.pprint`got ${contextId}`
+ );
+
+ const childContext = this.#getBrowsingContext(contextId);
+ if (childContext.parent !== context) {
+ throw new lazy.error.InvalidArgumentError(
+ `Expected "locator.context" (${contextId}) to be a direct child context of "context" (${navigableId})`
+ );
+ }
+
+ // Replace the locator selector context value by the internal browsing
+ // context id.
+ locator.value.context = childContext.id;
+ }
+
if (
- ![LocatorType.accessibility, LocatorType.css, LocatorType.xpath].includes(
- locator.type
- )
+ ![
+ LocatorType.accessibility,
+ LocatorType.context,
+ LocatorType.css,
+ LocatorType.xpath,
+ ].includes(locator.type)
) {
throw new lazy.error.UnsupportedOperationError(
`"locator.type" argument with value: ${locator.type} is not supported yet.`
diff --git a/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs
@@ -151,6 +151,23 @@ class BrowsingContextModule extends WindowGlobalBiDiModule {
}
/**
+ * Locate the container element of a provided context id.
+ *
+ * @see https://w3c.github.io/webdriver-bidi/#locate-the-container-element
+ */
+
+ #locateContainer(contextId) {
+ const returnedNodes = [];
+ const context = BrowsingContext.get(contextId);
+ const container = context.embedderElement;
+ if (container) {
+ returnedNodes.push(container);
+ }
+
+ return returnedNodes;
+ }
+
+ /**
* Locate nodes using accessibility attributes.
*
* @see https://w3c.github.io/webdriver-bidi/#locate-nodes-using-accessibility-attributes
@@ -569,6 +586,10 @@ class BrowsingContextModule extends WindowGlobalBiDiModule {
);
break;
}
+ case lazy.LocatorType.context: {
+ returnedNodes = this.#locateContainer(locator.value.context);
+ break;
+ }
case lazy.LocatorType.css: {
returnedNodes = this.#locateNodesUsingCss(
contextNodes,
diff --git a/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/locate_nodes/invalid.py.ini b/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/locate_nodes/invalid.py.ini
@@ -3,8 +3,5 @@
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1869538
expected: FAIL
- [test_params_locator_context_value_invalid_context[non_exiting_context\]]
- expected: FAIL
-
[test_params_locator_value_invalid_value[context-value4\]]
expected: FAIL
diff --git a/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/locate_nodes/locator.py.ini b/testing/web-platform/meta/webdriver/tests/bidi/browsing_context/locate_nodes/locator.py.ini
@@ -46,27 +46,3 @@
[test_find_by_inner_text[ignore_case_false_partial_match_max_depth_two\]]
expected: FAIL
-
- [test_locate_by_context[same_origin\]]
- expected: FAIL
-
- [test_locate_by_context[cross_origin\]]
- expected: FAIL
-
- [test_locate_by_context_in_iframe[same_origin\]]
- expected: FAIL
-
- [test_locate_by_context_in_iframe[cross_origin\]]
- expected: FAIL
-
- [test_locate_by_context_in_shadow_dom[open-same_origin\]]
- expected: FAIL
-
- [test_locate_by_context_in_shadow_dom[open-cross_origin\]]
- expected: FAIL
-
- [test_locate_by_context_in_shadow_dom[closed-same_origin\]]
- expected: FAIL
-
- [test_locate_by_context_in_shadow_dom[closed-cross_origin\]]
- expected: FAIL