From 08f761486e2bf8d509aba7ad4493f66ae127b4c6 Mon Sep 17 00:00:00 2001 From: jrandolf <101637635+jrandolf@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:52:11 +0100 Subject: [PATCH] refactor: use generic implementation for `waitForRequest` (#11753) --- docs/api/puppeteer.page.waitforrequest.md | 16 ++++----- packages/puppeteer-core/src/api/Page.ts | 32 +++++++++++++---- packages/puppeteer-core/src/bidi/Page.ts | 17 --------- packages/puppeteer-core/src/cdp/Page.ts | 15 -------- packages/puppeteer-core/src/common/util.ts | 40 +--------------------- 5 files changed, 34 insertions(+), 86 deletions(-) diff --git a/docs/api/puppeteer.page.waitforrequest.md b/docs/api/puppeteer.page.waitforrequest.md index 175d8fb32e2..de0b8016253 100644 --- a/docs/api/puppeteer.page.waitforrequest.md +++ b/docs/api/puppeteer.page.waitforrequest.md @@ -8,21 +8,19 @@ sidebar_label: Page.waitForRequest ```typescript class Page { - abstract waitForRequest( - urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise), - options?: { - timeout?: number; - } + waitForRequest( + urlOrPredicate: string | AwaitablePredicate, + options?: WaitTimeoutOptions ): Promise; } ``` ## Parameters -| Parameter | Type | Description | -| -------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| urlOrPredicate | string \| ((req: [HTTPRequest](./puppeteer.httprequest.md)) => boolean \| Promise<boolean>) | A URL or predicate to wait for | -| options | { timeout?: number; } | _(Optional)_ Optional waiting parameters | +| Parameter | Type | Description | +| -------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | +| urlOrPredicate | string \| [AwaitablePredicate](./puppeteer.awaitablepredicate.md)<[HTTPRequest](./puppeteer.httprequest.md)> | A URL or predicate to wait for | +| options | [WaitTimeoutOptions](./puppeteer.waittimeoutoptions.md) | _(Optional)_ Optional waiting parameters | **Returns:** diff --git a/packages/puppeteer-core/src/api/Page.ts b/packages/puppeteer-core/src/api/Page.ts index 7b7d6fc4b7e..f9e3b4c5983 100644 --- a/packages/puppeteer-core/src/api/Page.ts +++ b/packages/puppeteer-core/src/api/Page.ts @@ -1621,10 +1621,30 @@ export abstract class Page extends EventEmitter { * `0` to disable the timeout. The default value can be changed by using the * {@link Page.setDefaultTimeout} method. */ - abstract waitForRequest( - urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise), - options?: {timeout?: number} - ): Promise; + waitForRequest( + urlOrPredicate: string | AwaitablePredicate, + options: WaitTimeoutOptions = {} + ): Promise { + const {timeout: ms = this._timeoutSettings.timeout()} = options; + if (typeof urlOrPredicate === 'string') { + const url = urlOrPredicate; + urlOrPredicate = (request: HTTPRequest) => { + return request.url() === url; + }; + } + const observable$ = fromEmitterEvent(this, PageEvent.Request).pipe( + filterAsync(urlOrPredicate), + raceWith( + timeout(ms), + fromEmitterEvent(this, PageEvent.Close).pipe( + map(() => { + throw new TargetCloseError('Page closed!'); + }) + ) + ) + ); + return firstValueFrom(observable$); + } /** * @param urlOrPredicate - A URL or predicate to wait for. @@ -1660,8 +1680,8 @@ export abstract class Page extends EventEmitter { const {timeout: ms = this._timeoutSettings.timeout()} = options; if (typeof urlOrPredicate === 'string') { const url = urlOrPredicate; - urlOrPredicate = (request: HTTPResponse) => { - return request.url() === url; + urlOrPredicate = (response: HTTPResponse) => { + return response.url() === url; }; } const observable$ = fromEmitterEvent(this, PageEvent.Response).pipe( diff --git a/packages/puppeteer-core/src/bidi/Page.ts b/packages/puppeteer-core/src/bidi/Page.ts index f240c5341c0..567e2944f4c 100644 --- a/packages/puppeteer-core/src/bidi/Page.ts +++ b/packages/puppeteer-core/src/bidi/Page.ts @@ -51,7 +51,6 @@ import { parsePDFOptions, timeout, validateDialogType, - waitForHTTP, } from '../common/util.js'; import type {Viewport} from '../common/Viewport.js'; import {assert} from '../util/assert.js'; @@ -702,22 +701,6 @@ export class BidiPage extends Page { return data; } - override async waitForRequest( - urlOrPredicate: - | string - | ((req: BidiHTTPRequest) => boolean | Promise), - options: {timeout?: number} = {} - ): Promise { - const {timeout = this._timeoutSettings.timeout()} = options; - return await waitForHTTP( - this.#networkManager, - NetworkManagerEvent.Request, - urlOrPredicate, - timeout, - this.#closedDeferred - ); - } - override async waitForNetworkIdle( options: {idleTime?: number; timeout?: number} = {} ): Promise { diff --git a/packages/puppeteer-core/src/cdp/Page.ts b/packages/puppeteer-core/src/cdp/Page.ts index b5d1dbf0408..db6b456bf33 100644 --- a/packages/puppeteer-core/src/cdp/Page.ts +++ b/packages/puppeteer-core/src/cdp/Page.ts @@ -46,7 +46,6 @@ import { parsePDFOptions, timeout, validateDialogType, - waitForHTTP, } from '../common/util.js'; import type {Viewport} from '../common/Viewport.js'; import {assert} from '../util/assert.js'; @@ -910,20 +909,6 @@ export class CdpPage extends Page { return await this.target().createCDPSession(); } - override async waitForRequest( - urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise), - options: {timeout?: number} = {} - ): Promise { - const {timeout = this._timeoutSettings.timeout()} = options; - return await waitForHTTP( - this.#frameManager.networkManager, - NetworkManagerEvent.Request, - urlOrPredicate, - timeout, - this.#sessionCloseDeferred - ); - } - override async waitForNetworkIdle( options: {idleTime?: number; timeout?: number} = {} ): Promise { diff --git a/packages/puppeteer-core/src/common/util.ts b/packages/puppeteer-core/src/common/util.ts index 3abe6c77758..2c8f76f664b 100644 --- a/packages/puppeteer-core/src/common/util.ts +++ b/packages/puppeteer-core/src/common/util.ts @@ -7,26 +7,15 @@ import type FS from 'fs/promises'; import type {Readable} from 'stream'; -import { - filterAsync, - firstValueFrom, - from, - map, - NEVER, - Observable, - raceWith, - timer, -} from '../../third_party/rxjs/rxjs.js'; +import {map, NEVER, Observable, timer} from '../../third_party/rxjs/rxjs.js'; import type {CDPSession} from '../api/CDPSession.js'; import {isNode} from '../environment.js'; import {assert} from '../util/assert.js'; -import type {Deferred} from '../util/Deferred.js'; import {isErrorLike} from '../util/ErrorLike.js'; import {debug} from './Debug.js'; import {TimeoutError} from './Errors.js'; import type {EventEmitter, EventType} from './EventEmitter.js'; -import type {NetworkManagerEvents} from './NetworkManagerEvents.js'; import type { LowerCasePaperFormat, ParsedPDFOptions, @@ -338,33 +327,6 @@ export function getSourceUrlComment(url: string): string { return `//# sourceURL=${url}`; } -/** - * @internal - */ -export async function waitForHTTP( - networkManager: EventEmitter, - eventName: EventType, - urlOrPredicate: string | ((res: T) => boolean | Promise), - /** Time after the function will timeout */ - ms: number, - cancelation: Deferred -): Promise { - return await firstValueFrom( - (fromEmitterEvent(networkManager, eventName) as Observable).pipe( - filterAsync(async http => { - if (isString(urlOrPredicate)) { - return urlOrPredicate === http.url(); - } - if (typeof urlOrPredicate === 'function') { - return !!(await urlOrPredicate(http)); - } - return false; - }), - raceWith(timeout(ms), from(cancelation.valueOrThrow())) - ) - ); -} - /** * @internal */