diff --git a/packages/puppeteer-core/src/common/Accessibility.ts b/packages/puppeteer-core/src/common/Accessibility.ts index 0f49d0e6..1429ecf6 100644 --- a/packages/puppeteer-core/src/common/Accessibility.ts +++ b/packages/puppeteer-core/src/common/Accessibility.ts @@ -18,6 +18,8 @@ import {Protocol} from 'devtools-protocol'; import {ElementHandle} from '../api/ElementHandle.js'; +import {CDPSession} from './Connection.js'; + /** * Represents a Node and the properties of it that are relevant to Accessibility. * @public @@ -107,14 +109,6 @@ export interface SnapshotOptions { root?: ElementHandle; } -/** - * @internal - */ -export interface DataProvider { - getFullAXTree(): Promise; - describeNode(id: string): Promise; -} - /** * The Accessibility class provides methods for inspecting the browser's * accessibility tree. The accessibility tree is used by assistive technology @@ -138,13 +132,13 @@ export interface DataProvider { * @public */ export class Accessibility { - #dataProvider: DataProvider; + #client: CDPSession; /** * @internal */ - constructor(dataProvider: DataProvider) { - this.#dataProvider = dataProvider; + constructor(client: CDPSession) { + this.#client = client; } /** @@ -190,10 +184,12 @@ export class Accessibility { options: SnapshotOptions = {} ): Promise { const {interestingOnly = true, root = null} = options; - const {nodes} = await this.#dataProvider.getFullAXTree(); + const {nodes} = await this.#client.send('Accessibility.getFullAXTree'); let backendNodeId: number | undefined; - if (root && root.id) { - const {node} = await this.#dataProvider.describeNode(root.id); + if (root) { + const {node} = await this.#client.send('DOM.describeNode', { + objectId: root.id, + }); backendNodeId = node.backendNodeId; } const defaultRoot = AXNode.createTree(nodes); diff --git a/packages/puppeteer-core/src/common/Page.ts b/packages/puppeteer-core/src/common/Page.ts index f922a19d..f8d657b2 100644 --- a/packages/puppeteer-core/src/common/Page.ts +++ b/packages/puppeteer-core/src/common/Page.ts @@ -167,16 +167,7 @@ export class CDPPage extends Page { this.#keyboard = new Keyboard(client); this.#mouse = new Mouse(client, this.#keyboard); this.#touchscreen = new Touchscreen(client, this.#keyboard); - this.#accessibility = new Accessibility({ - describeNode(id: string) { - return client.send('DOM.describeNode', { - objectId: id, - }); - }, - getFullAXTree() { - return client.send('Accessibility.getFullAXTree'); - }, - }); + this.#accessibility = new Accessibility(client); this.#frameManager = new FrameManager( client, this, @@ -184,25 +175,7 @@ export class CDPPage extends Page { this.#timeoutSettings ); this.#emulationManager = new EmulationManager(client); - this.#tracing = new Tracing({ - read: opts => { - return this.#client.send('IO.read', opts); - }, - close: opts => { - return this.#client.send('IO.close', opts); - }, - start: opts => { - return client.send('Tracing.start', opts); - }, - stop: async () => { - const deferred = Deferred.create(); - this.#client.once('Tracing.tracingComplete', event => { - deferred.resolve(event); - }); - await this.#client.send('Tracing.end'); - return deferred.valueOrThrow() as Promise; - }, - }); + this.#tracing = new Tracing(client); this.#coverage = new Coverage(client); this.#screenshotTaskQueue = screenshotTaskQueue; this.#viewport = null; @@ -1494,17 +1467,7 @@ export class CDPPage extends Page { } assert(result.stream, '`stream` is missing from `Page.printToPDF'); - return getReadableFromProtocolStream( - { - read: opts => { - return this.#client.send('IO.read', opts); - }, - close: opts => { - return this.#client.send('IO.close', opts); - }, - }, - result.stream - ); + return getReadableFromProtocolStream(this.#client, result.stream); } override async pdf(options: PDFOptions = {}): Promise { diff --git a/packages/puppeteer-core/src/common/Tracing.ts b/packages/puppeteer-core/src/common/Tracing.ts index aabcd629..18de4abb 100644 --- a/packages/puppeteer-core/src/common/Tracing.ts +++ b/packages/puppeteer-core/src/common/Tracing.ts @@ -13,15 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Protocol from 'devtools-protocol'; - import {assert} from '../util/assert.js'; +import {Deferred} from '../util/Deferred.js'; +import {isErrorLike} from '../util/ErrorLike.js'; -import { - getReadableAsBuffer, - getReadableFromProtocolStream, - ProtocolReadable, -} from './util.js'; +import {CDPSession} from './Connection.js'; +import {getReadableAsBuffer, getReadableFromProtocolStream} from './util.js'; /** * @public @@ -32,14 +29,6 @@ export interface TracingOptions { categories?: string[]; } -/** - * @internal - */ -export interface TracingSource extends ProtocolReadable { - start(opts: Protocol.Tracing.StartRequest): Promise; - stop(): Promise; -} - /** * The Tracing class exposes the tracing audit interface. * @remarks @@ -57,15 +46,15 @@ export interface TracingSource extends ProtocolReadable { * @public */ export class Tracing { - #source: TracingSource; + #client: CDPSession; #recording = false; #path?: string; /** * @internal */ - constructor(source: TracingSource) { - this.#source = source; + constructor(client: CDPSession) { + this.#client = client; } /** @@ -113,7 +102,7 @@ export class Tracing { this.#path = path; this.#recording = true; - await this.#source.start({ + await this.#client.send('Tracing.start', { transferMode: 'ReturnAsStream', traceConfig: { excludedCategories, @@ -127,13 +116,25 @@ export class Tracing { * @returns Promise which resolves to buffer with trace data. */ async stop(): Promise { - const result = await this.#source.stop(); - const readable = await getReadableFromProtocolStream( - this.#source, - result.stream! - ); - const buffer = await getReadableAsBuffer(readable, this.#path); + const contentDeferred = Deferred.create(); + this.#client.once('Tracing.tracingComplete', async event => { + try { + const readable = await getReadableFromProtocolStream( + this.#client, + event.stream + ); + const buffer = await getReadableAsBuffer(readable, this.#path); + contentDeferred.resolve(buffer ?? undefined); + } catch (error) { + if (isErrorLike(error)) { + contentDeferred.reject(error); + } else { + contentDeferred.reject(new Error(`Unknown error: ${error}`)); + } + } + }); + await this.#client.send('Tracing.end'); this.#recording = false; - return buffer ?? undefined; + return contentDeferred.valueOrThrow(); } } diff --git a/packages/puppeteer-core/src/common/bidi/Page.ts b/packages/puppeteer-core/src/common/bidi/Page.ts index a687cf39..c10bda97 100644 --- a/packages/puppeteer-core/src/common/bidi/Page.ts +++ b/packages/puppeteer-core/src/common/bidi/Page.ts @@ -17,7 +17,6 @@ import type {Readable} from 'stream'; import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js'; -import Protocol from 'devtools-protocol'; import { Page as PageBase, @@ -144,41 +143,10 @@ export class Page extends PageBase { } // TODO: https://github.com/w3c/webdriver-bidi/issues/443 - this.#accessibility = new Accessibility({ - describeNode: (id: string) => { - return this.mainFrame().context().sendCDPCommand('DOM.describeNode', { - objectId: id, - }); - }, - getFullAXTree: () => { - return this.mainFrame() - .context() - .sendCDPCommand('Accessibility.getFullAXTree'); - }, - }); - - this.#tracing = new Tracing({ - read: opts => { - return this.mainFrame().context().sendCDPCommand('IO.read', opts); - }, - close: opts => { - return this.mainFrame().context().sendCDPCommand('IO.close', opts); - }, - start: opts => { - return this.mainFrame().context().sendCDPCommand('Tracing.start', opts); - }, - stop: async () => { - const deferred = Deferred.create(); - this.mainFrame() - .context() - .cdpSession.once('Tracing.tracingComplete', event => { - deferred.resolve(event); - }); - await this.mainFrame().context().sendCDPCommand('Tracing.end'); - return deferred.valueOrThrow() as Promise; - }, - }); - + this.#accessibility = new Accessibility( + this.mainFrame().context().cdpSession + ); + this.#tracing = new Tracing(this.mainFrame().context().cdpSession); this.#coverage = new Coverage(this.mainFrame().context().cdpSession); } diff --git a/packages/puppeteer-core/src/common/util.ts b/packages/puppeteer-core/src/common/util.ts index 74ee1486..a1077a58 100644 --- a/packages/puppeteer-core/src/common/util.ts +++ b/packages/puppeteer-core/src/common/util.ts @@ -574,19 +574,11 @@ export async function getReadableAsBuffer( } } -/** - * @internal - */ -export interface ProtocolReadable { - read(opts: {handle: string; size: number}): Promise; - close(opts: {handle: string}): Promise; -} - /** * @internal */ export async function getReadableFromProtocolStream( - source: ProtocolReadable, + client: CDPSession, handle: string ): Promise { // TODO: Once Node 18 becomes the lowest supported version, we can migrate to @@ -605,11 +597,11 @@ export async function getReadableFromProtocolStream( } try { - const response = await source.read({handle, size}); + const response = await client.send('IO.read', {handle, size}); this.push(response.data, response.base64Encoded ? 'base64' : undefined); if (response.eof) { eof = true; - await source.close({handle}); + await client.send('IO.close', {handle}); this.push(null); } } catch (error) {