feat: include iframes into the a11y snapshot

This commit is contained in:
Alex Rudenko 2024-06-12 17:13:17 +02:00
parent e36ce8bee1
commit 9d187fc09a
2 changed files with 54 additions and 0 deletions

View File

@ -195,6 +195,34 @@ export class Accessibility {
backendNodeId = node.backendNodeId; backendNodeId = node.backendNodeId;
} }
const defaultRoot = AXNode.createTree(this.#realm, nodes); const defaultRoot = AXNode.createTree(this.#realm, nodes);
const resolveIframes = async (root: AXNode): Promise<void> => {
if (root.payload.role?.value === 'Iframe') {
if (!root.payload.backendDOMNodeId) {
return;
}
console.log(root.payload)
using handle = await this.#realm.adoptBackendNode(
root.payload.backendDOMNodeId
) as ElementHandle<Element>;
if (!handle || !('contentFrame' in handle)) {
return;
}
const frame = await handle.contentFrame();
if (!frame) {
return;
}
const iframeSnapshot = await frame.accessibility.snapshot(options);
root.iframeSnapshot = iframeSnapshot ?? undefined;
console.log('iframe', root.iframeSnapshot)
}
for (const child of root.children) {
await resolveIframes(child);
}
}
await resolveIframes(defaultRoot);
let needle: AXNode | null = defaultRoot; let needle: AXNode | null = defaultRoot;
if (backendNodeId) { if (backendNodeId) {
needle = defaultRoot.find(node => { needle = defaultRoot.find(node => {
@ -233,6 +261,12 @@ export class Accessibility {
if (children.length) { if (children.length) {
serializedNode.children = children; serializedNode.children = children;
} }
if (node.iframeSnapshot) {
if (!serializedNode.children) {
serializedNode.children = [];
}
serializedNode.children.push(node.iframeSnapshot);
}
return [serializedNode]; return [serializedNode];
} }
@ -257,6 +291,7 @@ export class Accessibility {
class AXNode { class AXNode {
public payload: Protocol.Accessibility.AXNode; public payload: Protocol.Accessibility.AXNode;
public children: AXNode[] = []; public children: AXNode[] = [];
public iframeSnapshot?: SerializedAXNode;
#richlyEditable = false; #richlyEditable = false;
#editable = false; #editable = false;

View File

@ -10,6 +10,7 @@ import expect from 'expect';
import type {SerializedAXNode} from 'puppeteer-core/internal/cdp/Accessibility.js'; import type {SerializedAXNode} from 'puppeteer-core/internal/cdp/Accessibility.js';
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import { attachFrame } from './utils.js';
describe('Accessibility', function () { describe('Accessibility', function () {
setupTestBrowserHooks(); setupTestBrowserHooks();
@ -242,6 +243,24 @@ describe('Accessibility', function () {
assert(snapshot.children[0]); assert(snapshot.children[0]);
expect(snapshot.children[0]!.multiselectable).toEqual(true); expect(snapshot.children[0]!.multiselectable).toEqual(true);
}); });
it.only('iframes', async () => {
const {page, server} = await getTestState();
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
const frame1 = page.frames()[1];
await frame1!.evaluate(() => {
const button = document.createElement('button');
button.innerText = 'value1';
document.body.appendChild(button)
});
const snapshot = await page.accessibility.snapshot();
console.log(JSON.stringify(snapshot, null, 2))
expect(snapshot).toMatchObject({
});
});
it('keyshortcuts', async () => { it('keyshortcuts', async () => {
const {page} = await getTestState(); const {page} = await getTestState();