Skip to content

Commit

Permalink
feat: support document as startNodes in browsingContext.locateNodes
Browse files Browse the repository at this point in the history
  • Loading branch information
sadym-chromium committed May 17, 2024
1 parent 1d0e73c commit 352a429
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 20 deletions.
33 changes: 25 additions & 8 deletions src/bidiMapper/modules/context/BrowsingContextImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,12 +1105,12 @@ export class BrowsingContextImpl {
(
xPathSelector: string,
maxNodeCount: number,
...startNodes: HTMLElement[]
...startNodes: Node[]
) => {
// https://w3c.github.io/webdriver-bidi/#locate-nodes-using-xpath
const evaluator = new XPathEvaluator();
const expression = evaluator.createExpression(xPathSelector);
const locateNodesUsingXpath = (element: HTMLElement) => {
const locateNodesUsingXpath = (element: Node) => {
const xPathResult = expression.evaluate(
element,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
Expand Down Expand Up @@ -1157,16 +1157,34 @@ export class BrowsingContextImpl {
ignoreCase: boolean,
maxNodeCount: number,
maxDepth: number,
...startNodes: HTMLElement[]
...startNodes: Node[]
) => {
const searchText = ignoreCase
? innerTextSelector.toUpperCase()
: innerTextSelector;
const locateNodesUsingInnerText = (
element: HTMLElement,
const locateNodesUsingInnerText: (
node: Node,
currentMaxDepth: number
) => {
) => HTMLElement[] = (node: Node, currentMaxDepth: number) => {
const returnedNodes: HTMLElement[] = [];
if (
node instanceof DocumentFragment ||
node instanceof Document
) {
const children = [...node.children];
children.forEach((child) =>
returnedNodes.push(
...locateNodesUsingInnerText(child, currentMaxDepth - 1)
)
);
return returnedNodes;
}

if (!(node instanceof HTMLElement)) {
return [];
}

const element = node;
const nodeInnerText = ignoreCase
? element.innerText?.toUpperCase()
: element.innerText;
Expand Down Expand Up @@ -1213,9 +1231,8 @@ export class BrowsingContextImpl {
// TODO: stop search early if `maxNodeCount` is reached.
return returnedNodes;
};
// TODO: add maxDepth.
// TODO: stop search early if `maxNodeCount` is reached.
startNodes = startNodes.length > 0 ? startNodes : [document.body];
startNodes = startNodes.length > 0 ? startNodes : [document];
const returnedNodes = startNodes
.map((startNode) =>
// TODO: stop search early if `maxNodeCount` is reached.
Expand Down
27 changes: 24 additions & 3 deletions tests/browsing_context/test_locate_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,41 @@
}
},
])
@pytest.mark.parametrize('start_node_expression',
[None, 'document', 'document.body'])
@pytest.mark.asyncio
async def test_locate_nodes_locator_found(websocket, context_id, html,
locator):
async def test_locate_nodes_locator_no_start_nodes_found(
websocket, context_id, html, locator, start_node_expression):
await goto_url(
websocket, context_id,
html(
'<div data-class="one" aria-label="test" role="button">foobarBARbaz</div><div data-class="two" aria-label="test" role="button">foobarBAR<span>baz</span></div>'
))

start_nodes = None
if start_node_expression:
resp = await execute_command(
websocket, {
'method': 'script.evaluate',
'params': {
'expression': start_node_expression,
'target': {
'context': context_id
},
'awaitPromise': False
}
})
start_nodes = [{'sharedId': resp['result']['sharedId']}]

resp = await execute_command(
websocket, {
'method': 'browsingContext.locateNodes',
'params': {
'context': context_id,
'locator': locator
'locator': locator,
**({
'startNodes': start_nodes
} if start_nodes else {})
}
})

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit 352a429

Please sign in to comment.