mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: implement ARIA queries in BiDi (#11999)
This commit is contained in:
parent
53cf9ce5d7
commit
414f43388b
@ -36,6 +36,10 @@ export interface Commands extends BidiCommands {
|
|||||||
params: Bidi.Cdp.GetSessionParameters;
|
params: Bidi.Cdp.GetSessionParameters;
|
||||||
returnType: Bidi.Cdp.GetSessionResult;
|
returnType: Bidi.Cdp.GetSessionResult;
|
||||||
};
|
};
|
||||||
|
'cdp.resolveRealm': {
|
||||||
|
params: Bidi.Cdp.ResolveRealmParameters;
|
||||||
|
returnType: Bidi.Cdp.ResolveRealmResult;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -428,7 +428,7 @@ export class BidiFrame extends Frame {
|
|||||||
selector: Selector,
|
selector: Selector,
|
||||||
options?: WaitForSelectorOptions
|
options?: WaitForSelectorOptions
|
||||||
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
||||||
if (selector.startsWith('aria')) {
|
if (selector.startsWith('aria') && !this.page().browser().cdpSupported) {
|
||||||
throw new UnsupportedOperation(
|
throw new UnsupportedOperation(
|
||||||
'ARIA selector is not supported for BiDi!'
|
'ARIA selector is not supported for BiDi!'
|
||||||
);
|
);
|
||||||
|
@ -7,6 +7,7 @@ import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
|||||||
|
|
||||||
import type {JSHandle} from '../api/JSHandle.js';
|
import type {JSHandle} from '../api/JSHandle.js';
|
||||||
import {Realm} from '../api/Realm.js';
|
import {Realm} from '../api/Realm.js';
|
||||||
|
import {ARIAQueryHandler} from '../cdp/AriaQueryHandler.js';
|
||||||
import {LazyArg} from '../common/LazyArg.js';
|
import {LazyArg} from '../common/LazyArg.js';
|
||||||
import {scriptInjector} from '../common/ScriptInjector.js';
|
import {scriptInjector} from '../common/ScriptInjector.js';
|
||||||
import type {TimeoutSettings} from '../common/TimeoutSettings.js';
|
import type {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||||
@ -20,6 +21,7 @@ import {
|
|||||||
SOURCE_URL_REGEX,
|
SOURCE_URL_REGEX,
|
||||||
} from '../common/util.js';
|
} from '../common/util.js';
|
||||||
import type PuppeteerUtil from '../injected/injected.js';
|
import type PuppeteerUtil from '../injected/injected.js';
|
||||||
|
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
|
||||||
import {stringifyFunction} from '../util/Function.js';
|
import {stringifyFunction} from '../util/Function.js';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
@ -30,6 +32,7 @@ import type {
|
|||||||
import type {WindowRealm} from './core/Realm.js';
|
import type {WindowRealm} from './core/Realm.js';
|
||||||
import {BidiDeserializer} from './Deserializer.js';
|
import {BidiDeserializer} from './Deserializer.js';
|
||||||
import {BidiElementHandle} from './ElementHandle.js';
|
import {BidiElementHandle} from './ElementHandle.js';
|
||||||
|
import {ExposeableFunction} from './ExposedFunction.js';
|
||||||
import type {BidiFrame} from './Frame.js';
|
import type {BidiFrame} from './Frame.js';
|
||||||
import {BidiJSHandle} from './JSHandle.js';
|
import {BidiJSHandle} from './JSHandle.js';
|
||||||
import {BidiSerializer} from './Serializer.js';
|
import {BidiSerializer} from './Serializer.js';
|
||||||
@ -277,12 +280,49 @@ export class BidiFrameRealm extends BidiRealm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#initialize() {
|
#initialize() {
|
||||||
|
super.initialize();
|
||||||
|
|
||||||
// This should run first.
|
// This should run first.
|
||||||
this.realm.on('updated', () => {
|
this.realm.on('updated', () => {
|
||||||
this.environment.clearDocumentHandle();
|
this.environment.clearDocumentHandle();
|
||||||
|
this.#bindingsInstalled = false;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
super.initialize();
|
#bindingsInstalled = false;
|
||||||
|
override get puppeteerUtil(): Promise<BidiJSHandle<PuppeteerUtil>> {
|
||||||
|
let promise = Promise.resolve() as Promise<unknown>;
|
||||||
|
if (!this.#bindingsInstalled) {
|
||||||
|
promise = Promise.all([
|
||||||
|
ExposeableFunction.from(
|
||||||
|
this.environment as BidiFrame,
|
||||||
|
'__ariaQuerySelector',
|
||||||
|
ARIAQueryHandler.queryOne,
|
||||||
|
!!this.sandbox
|
||||||
|
),
|
||||||
|
ExposeableFunction.from(
|
||||||
|
this.environment as BidiFrame,
|
||||||
|
'__ariaQuerySelectorAll',
|
||||||
|
async (
|
||||||
|
element: BidiElementHandle<Node>,
|
||||||
|
selector: string
|
||||||
|
): Promise<JSHandle<Node[]>> => {
|
||||||
|
const results = ARIAQueryHandler.queryAll(element, selector);
|
||||||
|
return await element.realm.evaluateHandle(
|
||||||
|
(...elements) => {
|
||||||
|
return elements;
|
||||||
|
},
|
||||||
|
...(await AsyncIterableUtil.collect(results))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
!!this.sandbox
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
this.#bindingsInstalled = true;
|
||||||
|
}
|
||||||
|
return promise.then(() => {
|
||||||
|
return super.puppeteerUtil;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get sandbox(): string | undefined {
|
get sandbox(): string | undefined {
|
||||||
@ -298,14 +338,19 @@ export class BidiFrameRealm extends BidiRealm {
|
|||||||
): Promise<JSHandle<Node>> {
|
): Promise<JSHandle<Node>> {
|
||||||
const {object} = await this.#frame.client.send('DOM.resolveNode', {
|
const {object} = await this.#frame.client.send('DOM.resolveNode', {
|
||||||
backendNodeId,
|
backendNodeId,
|
||||||
|
executionContextId: await this.realm.resolveExecutionContextId(),
|
||||||
});
|
});
|
||||||
return BidiElementHandle.from(
|
using handle = BidiElementHandle.from(
|
||||||
{
|
{
|
||||||
handle: object.objectId,
|
handle: object.objectId,
|
||||||
type: 'node',
|
type: 'node',
|
||||||
},
|
},
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
// We need the sharedId, so we perform the following to obtain it.
|
||||||
|
return await handle.evaluateHandle(element => {
|
||||||
|
return element;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import type * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
|||||||
import {EventEmitter} from '../../common/EventEmitter.js';
|
import {EventEmitter} from '../../common/EventEmitter.js';
|
||||||
import {inertIfDisposed, throwIfDisposed} from '../../util/decorators.js';
|
import {inertIfDisposed, throwIfDisposed} from '../../util/decorators.js';
|
||||||
import {DisposableStack, disposeSymbol} from '../../util/disposable.js';
|
import {DisposableStack, disposeSymbol} from '../../util/disposable.js';
|
||||||
|
import type {BidiConnection} from '../Connection.js';
|
||||||
|
|
||||||
import type {Browser} from './Browser.js';
|
import type {Browser} from './Browser.js';
|
||||||
import type {BrowsingContext} from './BrowsingContext.js';
|
import type {BrowsingContext} from './BrowsingContext.js';
|
||||||
@ -121,6 +122,18 @@ export abstract class Realm extends EventEmitter<{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@throwIfDisposed<Realm>(realm => {
|
||||||
|
// SAFETY: Disposal implies this exists.
|
||||||
|
return realm.#reason!;
|
||||||
|
})
|
||||||
|
async resolveExecutionContextId(): Promise<number> {
|
||||||
|
const {result} = await (this.session.connection as BidiConnection).send(
|
||||||
|
'cdp.resolveRealm',
|
||||||
|
{realm: this.id}
|
||||||
|
);
|
||||||
|
return result.executionContextId;
|
||||||
|
}
|
||||||
|
|
||||||
[disposeSymbol](): void {
|
[disposeSymbol](): void {
|
||||||
this.#reason ??=
|
this.#reason ??=
|
||||||
'Realm already destroyed, probably because all associated browsing contexts closed.';
|
'Realm already destroyed, probably because all associated browsing contexts closed.';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) *",
|
"testIdPattern": "[ariaqueryhandler.spec] *",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -180,37 +180,13 @@
|
|||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] *",
|
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"button\"",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["firefox", "webDriverBiDi"],
|
|
||||||
"expectations": ["SKIP"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] *",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["cdp", "firefox"],
|
|
||||||
"expectations": ["SKIP"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should have an error message specifically for awaiting an element to be hidden",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should have correct stack trace for timeout",
|
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"heading\"",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should respect timeout",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should throw when frame is detached",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
@ -725,25 +701,25 @@
|
|||||||
{
|
{
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors",
|
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors with name and role",
|
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors with name and role",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors with role",
|
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors with role",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work for ARIA selectors in multiple isolated worlds",
|
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work for ARIA selectors in multiple isolated worlds",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -844,18 +820,6 @@
|
|||||||
"parameters": ["chrome", "webDriverBiDi"],
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"button\"",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"heading\"",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[bfcache.spec] BFCache can navigate to a BFCached page containing an OOPIF and a worker",
|
"testIdPattern": "[bfcache.spec] BFCache can navigate to a BFCached page containing an OOPIF and a worker",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -3003,30 +2967,6 @@
|
|||||||
"parameters": ["firefox", "webDriverBiDi"],
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["cdp", "firefox"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors with name and role",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["cdp", "firefox"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work ARIA selectors with role",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["cdp", "firefox"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work for ARIA selectors in multiple isolated worlds",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["cdp", "firefox"],
|
|
||||||
"expectations": ["SKIP"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[queryObjects.spec] page.queryObjects should fail for disposed handles",
|
"testIdPattern": "[queryObjects.spec] page.queryObjects should fail for disposed handles",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
Loading…
Reference in New Issue
Block a user