feat: root option in page.accessibility.snapshot() (#4318)

Going from `AXNode` -> `ElementHandle` is turning out to be controversial.

This patch instead adds a way to go from `ElementHandle` -> `AXNode`. If the API looks good, I'll add it into Firefox as well.

References #3641
This commit is contained in:
Joel Einbinder
2019-05-10 02:39:42 -04:00
committed by Andrey Lushnikov
parent b3027a6e16
commit a3cb16308c
3 changed files with 95 additions and 6 deletions

View File

@@ -60,20 +60,36 @@ class Accessibility {
}
/**
* @param {{interestingOnly?: boolean}=} options
* @param {{interestingOnly?: boolean, root?: ?Puppeteer.ElementHandle}=} options
* @return {!Promise<!SerializedAXNode>}
*/
async snapshot(options = {}) {
const {interestingOnly = true} = options;
const {
interestingOnly = true,
root = null,
} = options;
const {nodes} = await this._client.send('Accessibility.getFullAXTree');
const root = AXNode.createTree(nodes);
let backendNodeId = null;
if (root) {
const {node} = await this._client.send('DOM.describeNode', {objectId: root._remoteObject.objectId});
backendNodeId = node.backendNodeId;
}
const defaultRoot = AXNode.createTree(nodes);
let needle = defaultRoot;
if (backendNodeId) {
needle = defaultRoot.find(node => node._payload.backendDOMNodeId === backendNodeId);
if (!needle)
return null;
}
if (!interestingOnly)
return serializeTree(root)[0];
return serializeTree(needle)[0];
/** @type {!Set<!AXNode>} */
const interestingNodes = new Set();
collectInterestingNodes(interestingNodes, root, false);
return serializeTree(root, interestingNodes)[0];
collectInterestingNodes(interestingNodes, defaultRoot, false);
if (!interestingNodes.has(needle))
return null;
return serializeTree(needle, interestingNodes)[0];
}
}
@@ -179,6 +195,21 @@ class AXNode {
return this._cachedHasFocusableChild;
}
/**
* @param {function(AXNode):boolean} predicate
* @return {?AXNode}
*/
find(predicate) {
if (predicate(this))
return this;
for (const child of this._children) {
const result = child.find(predicate);
if (result)
return result;
}
return null;
}
/**
* @return {boolean}
*/