diff options
Diffstat (limited to 'remote/test/puppeteer/packages/puppeteer-core/src/cdp')
14 files changed, 127 insertions, 55 deletions
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Binding.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Binding.ts index 7a6a6f8582..7fe372788f 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Binding.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Binding.ts @@ -1,3 +1,8 @@ +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ import {JSHandle} from '../api/JSHandle.js'; import {debugError} from '../common/util.js'; import {DisposableStack} from '../util/disposable.js'; diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts index 7698acd164..5c8a4c24da 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts @@ -18,7 +18,6 @@ import { type IsPageTargetCallback, type Permission, type TargetFilterCallback, - type WaitForTargetOptions, } from '../api/Browser.js'; import {BrowserContext, BrowserContextEvent} from '../api/BrowserContext.js'; import {CDPSessionEvent, type CDPSession} from '../api/CDPSession.js'; @@ -201,7 +200,7 @@ export class CdpBrowser extends BrowserBase { return this.#isPageTargetCallback; } - override async createIncognitoBrowserContext( + override async createBrowserContext( options: BrowserContextOptions = {} ): Promise<CdpBrowserContext> { const {proxyServer, proxyBypassList} = options; @@ -451,15 +450,6 @@ export class CdpBrowserContext extends BrowserContext { }); } - override waitForTarget( - predicate: (x: Target) => boolean | Promise<boolean>, - options: WaitForTargetOptions = {} - ): Promise<Target> { - return this.#browser.waitForTarget(target => { - return target.browserContext() === this && predicate(target); - }, options); - } - override async pages(): Promise<Page[]> { const pages = await Promise.all( this.targets() diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/EmulationManager.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/EmulationManager.ts index 8598967fe7..823b3b462e 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/EmulationManager.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/EmulationManager.ts @@ -267,13 +267,23 @@ export class EmulationManager { const hasTouch = viewport.hasTouch || false; await Promise.all([ - client.send('Emulation.setDeviceMetricsOverride', { - mobile, - width, - height, - deviceScaleFactor, - screenOrientation, - }), + client + .send('Emulation.setDeviceMetricsOverride', { + mobile, + width, + height, + deviceScaleFactor, + screenOrientation, + }) + .catch(err => { + if ( + err.message.includes('Target does not support metrics override') + ) { + debugError(err); + return; + } + throw err; + }), client.send('Emulation.setTouchEmulationEnabled', { enabled: hasTouch, }), diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts index 844120d7ff..edc7009b11 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts @@ -20,6 +20,7 @@ import type { DeviceRequestPromptManager, } from './DeviceRequestPrompt.js'; import type {FrameManager} from './FrameManager.js'; +import type {IsolatedWorldChart} from './IsolatedWorld.js'; import {IsolatedWorld} from './IsolatedWorld.js'; import {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js'; import { @@ -35,6 +36,7 @@ export class CdpFrame extends Frame { #url = ''; #detached = false; #client!: CDPSession; + worlds!: IsolatedWorldChart; _frameManager: FrameManager; override _id: string; diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts index 029e77470b..1331513e19 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts @@ -28,6 +28,7 @@ import type {CdpHTTPResponse} from './HTTPResponse.js'; * @internal */ export class CdpHTTPRequest extends HTTPRequest { + override id: string; declare _redirectChain: CdpHTTPRequest[]; declare _response: CdpHTTPResponse | null; @@ -91,7 +92,7 @@ export class CdpHTTPRequest extends HTTPRequest { ) { super(); this.#client = client; - this._requestId = data.requestId; + this.id = data.requestId; this.#isNavigationRequest = data.requestId === data.loaderId && data.type === 'Document'; this._interceptionId = interceptionId; @@ -188,7 +189,7 @@ export class CdpHTTPRequest extends HTTPRequest { override async fetchPostData(): Promise<string | undefined> { try { const result = await this.#client.send('Network.getRequestPostData', { - requestId: this._requestId, + requestId: this.id, }); return result.postData; } catch (err) { diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPResponse.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPResponse.ts index 2b2264ffd4..eb92ab07e3 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPResponse.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPResponse.ts @@ -130,7 +130,7 @@ export class CdpHTTPResponse extends HTTPResponse { const response = await this.#client.send( 'Network.getResponseBody', { - requestId: this.#request._requestId, + requestId: this.#request.id, } ); return Buffer.from( diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Input.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Input.ts index 9bfafddcf3..0674ef4634 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Input.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Input.ts @@ -10,16 +10,16 @@ import type {CDPSession} from '../api/CDPSession.js'; import type {Point} from '../api/ElementHandle.js'; import { Keyboard, - type KeyDownOptions, - type KeyPressOptions, Mouse, MouseButton, + Touchscreen, + type KeyDownOptions, + type KeyPressOptions, + type KeyboardTypeOptions, type MouseClickOptions, type MouseMoveOptions, type MouseOptions, type MouseWheelOptions, - Touchscreen, - type KeyboardTypeOptions, } from '../api/Input.js'; import { _keyDefinitions, @@ -573,6 +573,7 @@ export class CdpTouchscreen extends Touchscreen { y: Math.round(y), radiusX: 0.5, radiusY: 0.5, + force: 0.5, }, ], modifiers: this.#keyboard._modifiers, @@ -588,6 +589,7 @@ export class CdpTouchscreen extends Touchscreen { y: Math.round(y), radiusX: 0.5, radiusY: 0.5, + force: 0.5, }, ], modifiers: this.#keyboard._modifiers, diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/LifecycleWatcher.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/LifecycleWatcher.ts index a4f5aaa468..fe71ca52fc 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/LifecycleWatcher.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/LifecycleWatcher.ts @@ -191,14 +191,14 @@ export class LifecycleWatcher { } #onRequestFailed(request: HTTPRequest): void { - if (this.#navigationRequest?._requestId !== request._requestId) { + if (this.#navigationRequest?.id !== request.id) { return; } this.#navigationResponseReceived?.resolve(); } #onResponse(response: HTTPResponse): void { - if (this.#navigationRequest?._requestId !== response.request()._requestId) { + if (this.#navigationRequest?.id !== response.request().id) { return; } this.#navigationResponseReceived?.resolve(); diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.test.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.test.ts index c3e9a8f609..96f0d20963 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.test.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.test.ts @@ -128,6 +128,7 @@ describe('NetworkManager', () => { url: 'http://localhost:8907/redirect/1.html', status: 302, statusText: 'Found', + charset: 'utf-8', headers: { location: '/redirect/2.html', Date: 'Fri, 19 Nov 2021 09:53:58 GMT', @@ -217,6 +218,7 @@ describe('NetworkManager', () => { url: 'http://localhost:8907/redirect/2.html', status: 302, statusText: 'Found', + charset: 'utf-8', headers: { location: '/redirect/3.html', Date: 'Fri, 19 Nov 2021 09:53:58 GMT', @@ -321,6 +323,7 @@ describe('NetworkManager', () => { url: 'http://localhost:8907/redirect/3.html', status: 302, statusText: 'Found', + charset: 'utf-8', headers: { location: 'http://localhost:8907/empty.html', Date: 'Fri, 19 Nov 2021 09:53:58 GMT', @@ -433,6 +436,7 @@ describe('NetworkManager', () => { 'Keep-Alive': 'timeout=5', 'Content-Length': '0', }, + charset: 'utf-8', mimeType: 'text/html', connectionReused: true, connectionId: 322, @@ -613,6 +617,7 @@ describe('NetworkManager', () => { connection: 'keep-alive', 'content-length': '85862', }, + charset: 'utf-8', mimeType: 'text/plain', connectionReused: false, connectionId: 119, @@ -725,6 +730,7 @@ describe('NetworkManager', () => { url: 'http://10.1.0.39:42915/empty.html', status: 200, statusText: 'OK', + charset: 'utf-8', headers: { 'Cache-Control': 'no-cache, no-store', Connection: 'keep-alive', @@ -932,6 +938,7 @@ describe('NetworkManager', () => { url: 'http://127.0.0.1:54590/empty.html', status: 200, statusText: 'OK', + charset: 'utf-8', headers: { 'Cache-Control': 'no-cache, no-store', Connection: 'keep-alive', @@ -1036,6 +1043,7 @@ describe('NetworkManager', () => { url: 'http://localhost:56295/empty.html', status: 200, statusText: 'OK', + charset: 'utf-8', headers: { 'Cache-Control': 'no-cache, no-store', Connection: 'keep-alive', @@ -1221,6 +1229,7 @@ describe('NetworkManager', () => { url: 'http://localhost:3000/', status: 200, statusText: 'OK', + charset: 'utf-8', headers: { 'Cache-Control': 'max-age=5', Connection: 'keep-alive', @@ -1394,6 +1403,7 @@ describe('NetworkManager', () => { url: 'http://localhost:3000/redirect', status: 302, statusText: 'Found', + charset: 'utf-8', headers: { Connection: 'keep-alive', Date: 'Wed, 05 Apr 2023 12:39:13 GMT', @@ -1457,6 +1467,7 @@ describe('NetworkManager', () => { url: 'http://localhost:3000/', status: 200, statusText: 'OK', + charset: 'utf-8', headers: { 'Cache-Control': 'max-age=5', 'Content-Type': 'text/html; charset=utf-8', diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts index 8b24b9a748..4fd61116d2 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts @@ -36,11 +36,17 @@ export interface Credentials { * @public */ export interface NetworkConditions { - // Download speed (bytes/s) + /** + * Download speed (bytes/s) + */ download: number; - // Upload speed (bytes/s) + /** + * Upload speed (bytes/s) + */ upload: number; - // Latency (ms) + /** + * Latency (ms) + */ latency: number; } @@ -631,7 +637,7 @@ export class NetworkManager extends EventEmitter<NetworkManagerEvents> { } #forgetRequest(request: CdpHTTPRequest, events: boolean): void { - const requestId = request._requestId; + const requestId = request.id; const interceptionId = request._interceptionId; this.#networkEventManager.forgetRequest(requestId); diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts index 491637f0ea..d5341cf3bb 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {Readable} from 'stream'; - import type {Protocol} from 'devtools-protocol'; import {firstValueFrom, from, raceWith} from '../../third_party/rxjs/rxjs.js'; @@ -32,6 +30,11 @@ import { ConsoleMessage, type ConsoleMessageType, } from '../common/ConsoleMessage.js'; +import type { + Cookie, + DeleteCookiesRequest, + CookieParam, +} from '../common/Cookie.js'; import {TargetCloseError} from '../common/Errors.js'; import {FileChooser} from '../common/FileChooser.js'; import {NetworkManagerEvent} from '../common/NetworkManagerEvents.js'; @@ -80,6 +83,15 @@ import { } from './utils.js'; import {CdpWebWorker} from './WebWorker.js'; +function convertConsoleMessageLevel(method: string): ConsoleMessageType { + switch (method) { + case 'warning': + return 'warn'; + default: + return method as ConsoleMessageType; + } +} + /** * @internal */ @@ -346,6 +358,8 @@ export class CdpPage extends Page { const worker = new CdpWebWorker( session, session._target().url(), + session._target()._targetId, + session._target().type(), this.#addConsoleMessage.bind(this), this.#handleException.bind(this) ); @@ -470,7 +484,12 @@ export class CdpPage extends Page { if (source !== 'worker') { this.emit( PageEvent.Console, - new ConsoleMessage(level, text, [], [{url, lineNumber}]) + new ConsoleMessage( + convertConsoleMessageLevel(level), + text, + [], + [{url, lineNumber}] + ) ); } } @@ -572,16 +591,14 @@ export class CdpPage extends Page { ) as HandleFor<Prototype[]>; } - override async cookies( - ...urls: string[] - ): Promise<Protocol.Network.Cookie[]> { + override async cookies(...urls: string[]): Promise<Cookie[]> { const originalCookies = ( await this.#primaryTargetClient.send('Network.getCookies', { urls: urls.length ? urls : [this.url()], }) ).cookies; - const unsupportedCookieAttributes = ['priority']; + const unsupportedCookieAttributes = ['sourcePort']; const filterUnsupportedAttributes = ( cookie: Protocol.Network.Cookie ): Protocol.Network.Cookie => { @@ -594,7 +611,7 @@ export class CdpPage extends Page { } override async deleteCookie( - ...cookies: Protocol.Network.DeleteCookiesRequest[] + ...cookies: DeleteCookiesRequest[] ): Promise<void> { const pageURL = this.url(); for (const cookie of cookies) { @@ -606,9 +623,7 @@ export class CdpPage extends Page { } } - override async setCookie( - ...cookies: Protocol.Network.CookieParam[] - ): Promise<void> { + override async setCookie(...cookies: CookieParam[]): Promise<void> { const pageURL = this.url(); const startsWithHTTP = pageURL.startsWith('http'); const items = cookies.map(cookie => { @@ -810,7 +825,11 @@ export class CdpPage extends Page { const values = event.args.map(arg => { return createCdpHandle(context._world, arg); }); - this.#addConsoleMessage(event.type, values, event.stackTrace); + this.#addConsoleMessage( + convertConsoleMessageLevel(event.type), + values, + event.stackTrace + ); } async #onBindingCalled( @@ -842,7 +861,7 @@ export class CdpPage extends Page { } #addConsoleMessage( - eventType: ConsoleMessageType, + eventType: string, args: JSHandle[], stackTrace?: Protocol.Runtime.StackTrace ): void { @@ -874,7 +893,7 @@ export class CdpPage extends Page { } } const message = new ConsoleMessage( - eventType, + convertConsoleMessageLevel(eventType), textTokens.join(' '), args, stackTraceLocations @@ -1086,7 +1105,9 @@ export class CdpPage extends Page { return data; } - override async createPDFStream(options: PDFOptions = {}): Promise<Readable> { + override async createPDFStream( + options: PDFOptions = {} + ): Promise<ReadableStream<Uint8Array>> { const {timeout: ms = this._timeoutSettings.timeout()} = options; const { landscape, @@ -1102,6 +1123,7 @@ export class CdpPage extends Page { preferCSSPageSize, omitBackground, tagged: generateTaggedPDF, + outline: generateDocumentOutline, } = parsePDFOptions(options); if (omitBackground) { @@ -1127,6 +1149,7 @@ export class CdpPage extends Page { pageRanges, preferCSSPageSize, generateTaggedPDF, + generateDocumentOutline, } ); diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts index df035ae52b..2e30f900c3 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts @@ -40,10 +40,3 @@ export const PredefinedNetworkConditions = Object.freeze({ latency: 150 * 3.75, } as NetworkConditions, }); - -/** - * @deprecated Import {@link PredefinedNetworkConditions}. - * - * @public - */ -export const networkConditions = PredefinedNetworkConditions; diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Target.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Target.ts index b3e9ea83ec..ab8b00475b 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Target.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Target.ts @@ -290,6 +290,8 @@ export class WorkerTarget extends CdpTarget { return new CdpWebWorker( client, this._getTargetInfo().url, + this._targetId, + this.type(), () => {} /* consoleAPICalled */, () => {} /* exceptionThrown */ ); diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/WebWorker.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/WebWorker.ts index 552e8a6cf5..ed2407ba66 100644 --- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/WebWorker.ts +++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/WebWorker.ts @@ -7,8 +7,8 @@ import type {Protocol} from 'devtools-protocol'; import type {CDPSession} from '../api/CDPSession.js'; import type {Realm} from '../api/Realm.js'; +import {TargetType} from '../api/Target.js'; import {WebWorker} from '../api/WebWorker.js'; -import type {ConsoleMessageType} from '../common/ConsoleMessage.js'; import {TimeoutSettings} from '../common/TimeoutSettings.js'; import {debugError} from '../common/util.js'; @@ -20,7 +20,7 @@ import {CdpJSHandle} from './JSHandle.js'; * @internal */ export type ConsoleAPICalledCallback = ( - eventType: ConsoleMessageType, + eventType: string, handles: CdpJSHandle[], trace?: Protocol.Runtime.StackTrace ) => void; @@ -38,15 +38,21 @@ export type ExceptionThrownCallback = ( export class CdpWebWorker extends WebWorker { #world: IsolatedWorld; #client: CDPSession; + readonly #id: string; + readonly #targetType: TargetType; constructor( client: CDPSession, url: string, + targetId: string, + targetType: TargetType, consoleAPICalled: ConsoleAPICalledCallback, exceptionThrown: ExceptionThrownCallback ) { super(url); + this.#id = targetId; this.#client = client; + this.#targetType = targetType; this.#world = new IsolatedWorld(this, new TimeoutSettings()); this.#client.once('Runtime.executionContextCreated', async event => { @@ -80,4 +86,25 @@ export class CdpWebWorker extends WebWorker { get client(): CDPSession { return this.#client; } + + override async close(): Promise<void> { + switch (this.#targetType) { + case TargetType.SERVICE_WORKER: + case TargetType.SHARED_WORKER: { + // For service and shared workers we need to close the target and detach to allow + // the worker to stop. + await this.client.connection()?.send('Target.closeTarget', { + targetId: this.#id, + }); + await this.client.connection()?.send('Target.detachFromTarget', { + sessionId: this.client.id(), + }); + break; + } + default: + await this.evaluate(() => { + self.close(); + }); + } + } } |