refactor: use generic implementation for waitForRequest (#11753)

This commit is contained in:
jrandolf 2024-01-25 14:52:11 +01:00 committed by GitHub
parent 3698fa8aec
commit 08f761486e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 34 additions and 86 deletions

View File

@ -8,21 +8,19 @@ sidebar_label: Page.waitForRequest
```typescript
class Page {
abstract waitForRequest(
urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise<boolean>),
options?: {
timeout?: number;
}
waitForRequest(
urlOrPredicate: string | AwaitablePredicate<HTTPRequest>,
options?: WaitTimeoutOptions
): Promise<HTTPRequest>;
}
```
## Parameters
| Parameter | Type | Description |
| -------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| urlOrPredicate | string \| ((req: [HTTPRequest](./puppeteer.httprequest.md)) =&gt; boolean \| Promise&lt;boolean&gt;) | A URL or predicate to wait for |
| options | &#123; timeout?: number; &#125; | _(Optional)_ Optional waiting parameters |
| Parameter | Type | Description |
| -------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| urlOrPredicate | string \| [AwaitablePredicate](./puppeteer.awaitablepredicate.md)&lt;[HTTPRequest](./puppeteer.httprequest.md)&gt; | A URL or predicate to wait for |
| options | [WaitTimeoutOptions](./puppeteer.waittimeoutoptions.md) | _(Optional)_ Optional waiting parameters |
**Returns:**

View File

@ -1621,10 +1621,30 @@ export abstract class Page extends EventEmitter<PageEvents> {
* `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<boolean>),
options?: {timeout?: number}
): Promise<HTTPRequest>;
waitForRequest(
urlOrPredicate: string | AwaitablePredicate<HTTPRequest>,
options: WaitTimeoutOptions = {}
): Promise<HTTPRequest> {
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<PageEvents> {
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(

View File

@ -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<boolean>),
options: {timeout?: number} = {}
): Promise<BidiHTTPRequest> {
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<void> {

View File

@ -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<boolean>),
options: {timeout?: number} = {}
): Promise<HTTPRequest> {
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<void> {

View File

@ -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<T extends {url(): string}>(
networkManager: EventEmitter<NetworkManagerEvents>,
eventName: EventType,
urlOrPredicate: string | ((res: T) => boolean | Promise<boolean>),
/** Time after the function will timeout */
ms: number,
cancelation: Deferred<never>
): Promise<T> {
return await firstValueFrom(
(fromEmitterEvent(networkManager, eventName) as Observable<T>).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
*/