feat(routes): add support for the times option (#8399)

This commit is contained in:
Max Schmitt 2021-08-24 20:45:50 +02:00 committed by GitHub
parent 59422a00f5
commit 8e20f13079
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 130 additions and 55 deletions

View file

@ -1021,6 +1021,11 @@ handler function to route the request.
handler function to route the request. handler function to route the request.
### option: BrowserContext.route.times
- `times` <[int]>
How often a route should be used. By default it will be used every time.
## method: BrowserContext.serviceWorkers ## method: BrowserContext.serviceWorkers
* langs: js, python * langs: js, python
- returns: <[Array]<[Worker]>> - returns: <[Array]<[Worker]>>

View file

@ -2561,6 +2561,11 @@ handler function to route the request.
handler function to route the request. handler function to route the request.
### option: Page.route.times
- `times` <[int]>
How often a route should be used. By default it will be used every time.
## async method: Page.screenshot ## async method: Page.screenshot
- returns: <[Buffer]> - returns: <[Buffer]>

View file

@ -21,7 +21,7 @@ import * as network from './network';
import * as channels from '../protocol/channels'; import * as channels from '../protocol/channels';
import fs from 'fs'; import fs from 'fs';
import { ChannelOwner } from './channelOwner'; import { ChannelOwner } from './channelOwner';
import { deprecate, evaluationScript, urlMatches } from './clientHelper'; import { deprecate, evaluationScript } from './clientHelper';
import { Browser } from './browser'; import { Browser } from './browser';
import { Worker } from './worker'; import { Worker } from './worker';
import { Events } from './events'; import { Events } from './events';
@ -38,7 +38,7 @@ import type { BrowserType } from './browserType';
export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel, channels.BrowserContextInitializer> implements api.BrowserContext { export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel, channels.BrowserContextInitializer> implements api.BrowserContext {
_pages = new Set<Page>(); _pages = new Set<Page>();
private _routes: { url: URLMatch, handler: network.RouteHandler }[] = []; private _routes: network.RouteHandler[] = [];
readonly _browser: Browser | null = null; readonly _browser: Browser | null = null;
private _browserType: BrowserType | undefined; private _browserType: BrowserType | undefined;
readonly _bindings = new Map<string, (source: structs.BindingSource, ...args: any[]) => any>(); readonly _bindings = new Map<string, (source: structs.BindingSource, ...args: any[]) => any>();
@ -132,9 +132,9 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
} }
_onRoute(route: network.Route, request: network.Request) { _onRoute(route: network.Route, request: network.Request) {
for (const {url, handler} of this._routes) { for (const routeHandler of this._routes) {
if (urlMatches(this._options.baseURL, request.url(), url)) { if (routeHandler.matches(request.url())) {
handler(route, request); routeHandler.handle(route, request);
return; return;
} }
} }
@ -258,15 +258,15 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
}); });
} }
async route(url: URLMatch, handler: network.RouteHandler): Promise<void> { async route(url: URLMatch, handler: network.RouteHandlerCallback, options: { times?: number } = {}): Promise<void> {
return this._wrapApiCall(async (channel: channels.BrowserContextChannel) => { return this._wrapApiCall(async (channel: channels.BrowserContextChannel) => {
this._routes.unshift({ url, handler }); this._routes.unshift(new network.RouteHandler(this._options.baseURL, url, handler, options.times));
if (this._routes.length === 1) if (this._routes.length === 1)
await channel.setNetworkInterceptionEnabled({ enabled: true }); await channel.setNetworkInterceptionEnabled({ enabled: true });
}); });
} }
async unroute(url: URLMatch, handler?: network.RouteHandler): Promise<void> { async unroute(url: URLMatch, handler?: network.RouteHandlerCallback): Promise<void> {
return this._wrapApiCall(async (channel: channels.BrowserContextChannel) => { return this._wrapApiCall(async (channel: channels.BrowserContextChannel) => {
this._routes = this._routes.filter(route => route.url !== url || (handler && route.handler !== handler)); this._routes = this._routes.filter(route => route.url !== url || (handler && route.handler !== handler));
if (this._routes.length === 0) if (this._routes.length === 0)

View file

@ -26,6 +26,8 @@ import { Events } from './events';
import { Page } from './page'; import { Page } from './page';
import { Waiter } from './waiter'; import { Waiter } from './waiter';
import * as api from '../../types/types'; import * as api from '../../types/types';
import { URLMatch } from '../common/types';
import { urlMatches } from './clientHelper';
export type NetworkCookie = { export type NetworkCookie = {
name: string, name: string,
@ -352,7 +354,7 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
} }
} }
export type RouteHandler = (route: Route, request: Request) => void; export type RouteHandlerCallback = (route: Route, request: Request) => void;
export type ResourceTiming = { export type ResourceTiming = {
startTime: number; startTime: number;
@ -516,3 +518,29 @@ export function validateHeaders(headers: Headers) {
throw new Error(`Expected value of header "${key}" to be String, but "${typeof value}" is found.`); throw new Error(`Expected value of header "${key}" to be String, but "${typeof value}" is found.`);
} }
} }
export class RouteHandler {
private handledCount = 0;
private readonly _baseURL: string | undefined;
private readonly _times: number | undefined;
readonly url: URLMatch;
readonly handler: RouteHandlerCallback;
constructor(baseURL: string | undefined, url: URLMatch, handler: RouteHandlerCallback, times?: number) {
this._baseURL = baseURL;
this._times = times;
this.url = url;
this.handler = handler;
}
public matches(requestURL: string): boolean {
if (this._times && this.handledCount >= this._times)
return false;
return urlMatches(this._baseURL, requestURL, this.url);
}
public handle(route: Route, request: Request) {
this.handler(route, request);
this.handledCount++;
}
}

View file

@ -32,7 +32,7 @@ import { Worker } from './worker';
import { Frame, verifyLoadState, WaitForNavigationOptions } from './frame'; import { Frame, verifyLoadState, WaitForNavigationOptions } from './frame';
import { Keyboard, Mouse, Touchscreen } from './input'; import { Keyboard, Mouse, Touchscreen } from './input';
import { assertMaxArguments, serializeArgument, parseResult, JSHandle } from './jsHandle'; import { assertMaxArguments, serializeArgument, parseResult, JSHandle } from './jsHandle';
import { Request, Response, Route, RouteHandler, WebSocket, validateHeaders } from './network'; import { Request, Response, Route, RouteHandlerCallback, WebSocket, validateHeaders, RouteHandler } from './network';
import { FileChooser } from './fileChooser'; import { FileChooser } from './fileChooser';
import { Buffer } from 'buffer'; import { Buffer } from 'buffer';
import { Coverage } from './coverage'; import { Coverage } from './coverage';
@ -71,7 +71,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
private _closed = false; private _closed = false;
_closedOrCrashedPromise: Promise<void>; _closedOrCrashedPromise: Promise<void>;
private _viewportSize: Size | null; private _viewportSize: Size | null;
private _routes: { url: URLMatch, handler: RouteHandler }[] = []; private _routes: RouteHandler[] = [];
readonly accessibility: Accessibility; readonly accessibility: Accessibility;
readonly coverage: Coverage; readonly coverage: Coverage;
@ -161,9 +161,9 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
} }
private _onRoute(route: Route, request: Request) { private _onRoute(route: Route, request: Request) {
for (const {url, handler} of this._routes) { for (const routeHandler of this._routes) {
if (urlMatches(this._browserContext._options.baseURL, request.url(), url)) { if (routeHandler.matches(request.url())) {
handler(route, request); routeHandler.handle(route, request);
return; return;
} }
} }
@ -443,15 +443,15 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}); });
} }
async route(url: URLMatch, handler: RouteHandler): Promise<void> { async route(url: URLMatch, handler: RouteHandlerCallback, options: { times?: number } = {}): Promise<void> {
return this._wrapApiCall(async (channel: channels.PageChannel) => { return this._wrapApiCall(async (channel: channels.PageChannel) => {
this._routes.unshift({ url, handler }); this._routes.unshift(new RouteHandler(this._browserContext._options.baseURL, url, handler, options.times));
if (this._routes.length === 1) if (this._routes.length === 1)
await channel.setNetworkInterceptionEnabled({ enabled: true }); await channel.setNetworkInterceptionEnabled({ enabled: true });
}); });
} }
async unroute(url: URLMatch, handler?: RouteHandler): Promise<void> { async unroute(url: URLMatch, handler?: RouteHandlerCallback): Promise<void> {
return this._wrapApiCall(async (channel: channels.PageChannel) => { return this._wrapApiCall(async (channel: channels.PageChannel) => {
this._routes = this._routes.filter(route => route.url !== url || (handler && route.handler !== handler)); this._routes = this._routes.filter(route => route.url !== url || (handler && route.handler !== handler));
if (this._routes.length === 0) if (this._routes.length === 0)

View file

@ -198,3 +198,15 @@ it('should work with ignoreHTTPSErrors', async ({browser, httpsServer}) => {
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
await context.close(); await context.close();
}); });
it('should support the times parameter with route matching', async ({context, page, server}) => {
const intercepted = [];
await context.route('**/empty.html', route => {
intercepted.push(1);
route.continue();
}, { times: 1});
await page.goto(server.EMPTY_PAGE);
await page.goto(server.EMPTY_PAGE);
await page.goto(server.EMPTY_PAGE);
expect(intercepted).toHaveLength(1);
});

View file

@ -652,3 +652,15 @@ it('should support cors for different methods', async ({page, server}) => {
expect(resp).toEqual(['DELETE', 'electric', 'gas']); expect(resp).toEqual(['DELETE', 'electric', 'gas']);
} }
}); });
it('should support the times parameter with route matching', async ({page, server}) => {
const intercepted = [];
await page.route('**/empty.html', route => {
intercepted.push(1);
route.continue();
}, { times: 1});
await page.goto(server.EMPTY_PAGE);
await page.goto(server.EMPTY_PAGE);
await page.goto(server.EMPTY_PAGE);
expect(intercepted).toHaveLength(1);
});

2
types/test.d.ts vendored
View file

@ -2508,7 +2508,7 @@ export interface PlaywrightTestOptions {
viewport: ViewportSize | null | undefined; viewport: ViewportSize | null | undefined;
/** /**
* When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto), * When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto),
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route), * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route),
* [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url), * [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url),
* [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or * [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or
* [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it * [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it

87
types/types.d.ts vendored
View file

@ -507,8 +507,8 @@ export interface Page {
/** /**
* Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see * Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route) or * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route) or
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route). * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route).
*/ */
on(event: 'request', listener: (request: Request) => void): this; on(event: 'request', listener: (request: Request) => void): this;
@ -778,8 +778,8 @@ export interface Page {
/** /**
* Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see * Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route) or * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route) or
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route). * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route).
*/ */
addListener(event: 'request', listener: (request: Request) => void): this; addListener(event: 'request', listener: (request: Request) => void): this;
@ -2339,9 +2339,9 @@ export interface Page {
* Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted. * Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
* *
* > NOTE: The handler will only be called for the first url if the response is a redirect. * > NOTE: The handler will only be called for the first url if the response is a redirect.
* > NOTE: [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route) will not intercept requests * > NOTE: [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route) will not intercept
* intercepted by Service Worker. See [this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend * requests intercepted by Service Worker. See [this](https://github.com/microsoft/playwright/issues/1090) issue. We
* disabling Service Workers when using request interception. Via `await context.addInitScript(() => delete * recommend disabling Service Workers when using request interception. Via `await context.addInitScript(() => delete
* window.navigator.serviceWorker);` * window.navigator.serviceWorker);`
* *
* An example of a naive handler that aborts all image requests: * An example of a naive handler that aborts all image requests:
@ -2375,8 +2375,8 @@ export interface Page {
* ``` * ```
* *
* Page routes take precedence over browser context routes (set up with * Page routes take precedence over browser context routes (set up with
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route)) when * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route))
* request matches both handlers. * when request matches both handlers.
* *
* To remove a route with its handler you can use * To remove a route with its handler you can use
* [page.unroute(url[, handler])](https://playwright.dev/docs/api/class-page#page-unroute). * [page.unroute(url[, handler])](https://playwright.dev/docs/api/class-page#page-unroute).
@ -2385,8 +2385,14 @@ export interface Page {
* @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a `baseURL` via the context options was provided and the passed URL is a path, it gets merged via the * @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a `baseURL` via the context options was provided and the passed URL is a path, it gets merged via the
* [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. * [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor.
* @param handler handler function to route the request. * @param handler handler function to route the request.
* @param options
*/ */
route(url: string|RegExp|((url: URL) => boolean), handler: ((route: Route, request: Request) => void)): Promise<void>; route(url: string|RegExp|((url: URL) => boolean), handler: ((route: Route, request: Request) => void), options?: {
/**
* How often a route should be used. By default it will be used every time.
*/
times?: number;
}): Promise<void>;
/** /**
* Returns the buffer with the captured screenshot. * Returns the buffer with the captured screenshot.
@ -2853,8 +2859,9 @@ export interface Page {
}): Promise<void>; }): Promise<void>;
/** /**
* Removes a route created with [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route). When * Removes a route created with
* `handler` is not specified, removes all routes for the `url`. * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route). When `handler` is not
* specified, removes all routes for the `url`.
* @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing. * @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing.
* @param handler Optional handler function to route the request. * @param handler Optional handler function to route the request.
*/ */
@ -3019,8 +3026,8 @@ export interface Page {
/** /**
* Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see * Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route) or * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route) or
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route). * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route).
*/ */
waitForEvent(event: 'request', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise<boolean>, timeout?: number } | ((request: Request) => boolean | Promise<boolean>)): Promise<Request>; waitForEvent(event: 'request', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise<boolean>, timeout?: number } | ((request: Request) => boolean | Promise<boolean>)): Promise<Request>;
@ -5029,8 +5036,8 @@ export interface BrowserContext {
* [page.on('request')](https://playwright.dev/docs/api/class-page#page-event-request). * [page.on('request')](https://playwright.dev/docs/api/class-page#page-event-request).
* *
* In order to intercept and mutate requests, see * In order to intercept and mutate requests, see
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) or * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route)
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route). * or [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route).
*/ */
on(event: 'request', listener: (request: Request) => void): this; on(event: 'request', listener: (request: Request) => void): this;
@ -5156,8 +5163,8 @@ export interface BrowserContext {
* [page.on('request')](https://playwright.dev/docs/api/class-page#page-event-request). * [page.on('request')](https://playwright.dev/docs/api/class-page#page-event-request).
* *
* In order to intercept and mutate requests, see * In order to intercept and mutate requests, see
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) or * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route)
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route). * or [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route).
*/ */
addListener(event: 'request', listener: (request: Request) => void): this; addListener(event: 'request', listener: (request: Request) => void): this;
@ -5500,9 +5507,9 @@ export interface BrowserContext {
* Routing provides the capability to modify network requests that are made by any page in the browser context. Once route * Routing provides the capability to modify network requests that are made by any page in the browser context. Once route
* is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted. * is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
* *
* > NOTE: [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route) will not intercept requests * > NOTE: [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route) will not intercept
* intercepted by Service Worker. See [this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend * requests intercepted by Service Worker. See [this](https://github.com/microsoft/playwright/issues/1090) issue. We
* disabling Service Workers when using request interception. Via `await context.addInitScript(() => delete * recommend disabling Service Workers when using request interception. Via `await context.addInitScript(() => delete
* window.navigator.serviceWorker);` * window.navigator.serviceWorker);`
* *
* An example of a naive handler that aborts all image requests: * An example of a naive handler that aborts all image requests:
@ -5537,8 +5544,8 @@ export interface BrowserContext {
* }); * });
* ``` * ```
* *
* Page routes (set up with [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route)) take * Page routes (set up with [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route))
* precedence over browser context routes when request matches both handlers. * take precedence over browser context routes when request matches both handlers.
* *
* To remove a route with its handler you can use * To remove a route with its handler you can use
* [browserContext.unroute(url[, handler])](https://playwright.dev/docs/api/class-browsercontext#browser-context-unroute). * [browserContext.unroute(url[, handler])](https://playwright.dev/docs/api/class-browsercontext#browser-context-unroute).
@ -5547,8 +5554,14 @@ export interface BrowserContext {
* @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a `baseURL` via the context options was provided and the passed URL is a path, it gets merged via the * @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a `baseURL` via the context options was provided and the passed URL is a path, it gets merged via the
* [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. * [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor.
* @param handler handler function to route the request. * @param handler handler function to route the request.
* @param options
*/ */
route(url: string|RegExp|((url: URL) => boolean), handler: ((route: Route, request: Request) => void)): Promise<void>; route(url: string|RegExp|((url: URL) => boolean), handler: ((route: Route, request: Request) => void), options?: {
/**
* How often a route should be used. By default it will be used every time.
*/
times?: number;
}): Promise<void>;
/** /**
* > NOTE: Service workers are only supported on Chromium-based browsers. * > NOTE: Service workers are only supported on Chromium-based browsers.
@ -5693,10 +5706,10 @@ export interface BrowserContext {
/** /**
* Removes a route created with * Removes a route created with
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route). When * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route).
* `handler` is not specified, removes all routes for the `url`. * When `handler` is not specified, removes all routes for the `url`.
* @param url A glob pattern, regex pattern or predicate receiving [URL] used to register a routing with [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route). * @param url A glob pattern, regex pattern or predicate receiving [URL] used to register a routing with [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route).
* @param handler Optional handler function used to register a routing with [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route). * @param handler Optional handler function used to register a routing with [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route).
*/ */
unroute(url: string|RegExp|((url: URL) => boolean), handler?: ((route: Route, request: Request) => void)): Promise<void>; unroute(url: string|RegExp|((url: URL) => boolean), handler?: ((route: Route, request: Request) => void)): Promise<void>;
@ -5749,8 +5762,8 @@ export interface BrowserContext {
* [page.on('request')](https://playwright.dev/docs/api/class-page#page-event-request). * [page.on('request')](https://playwright.dev/docs/api/class-page#page-event-request).
* *
* In order to intercept and mutate requests, see * In order to intercept and mutate requests, see
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) or * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route)
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route). * or [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route).
*/ */
waitForEvent(event: 'request', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise<boolean>, timeout?: number } | ((request: Request) => boolean | Promise<boolean>)): Promise<Request>; waitForEvent(event: 'request', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise<boolean>, timeout?: number } | ((request: Request) => boolean | Promise<boolean>)): Promise<Request>;
@ -8250,7 +8263,7 @@ export interface BrowserType<Unused = {}> {
/** /**
* When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto), * When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto),
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route), * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route),
* [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url), * [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url),
* [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or * [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or
* [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it * [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it
@ -9430,7 +9443,7 @@ export interface AndroidDevice {
/** /**
* When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto), * When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto),
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route), * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route),
* [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url), * [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url),
* [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or * [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or
* [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it * [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it
@ -10202,7 +10215,7 @@ export interface Browser extends EventEmitter {
/** /**
* When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto), * When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto),
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route), * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route),
* [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url), * [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url),
* [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or * [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or
* [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it * [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it
@ -11838,9 +11851,9 @@ export interface Response {
/** /**
* Whenever a network route is set up with * Whenever a network route is set up with
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route) or * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route) or
* [browserContext.route(url, handler)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route), the * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route),
* `Route` object allows to handle the route. * the `Route` object allows to handle the route.
*/ */
export interface Route { export interface Route {
/** /**
@ -12357,7 +12370,7 @@ export interface BrowserContextOptions {
/** /**
* When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto), * When using [page.goto(url[, options])](https://playwright.dev/docs/api/class-page#page-goto),
* [page.route(url, handler)](https://playwright.dev/docs/api/class-page#page-route), * [page.route(url, handler[, options])](https://playwright.dev/docs/api/class-page#page-route),
* [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url), * [page.waitForURL(url[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-url),
* [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or * [page.waitForRequest(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-request), or
* [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it * [page.waitForResponse(urlOrPredicate[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-response) it