From e0de51624ed7fb249361dfcb282b5c6b66fb57b1 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Fri, 24 Jan 2025 13:15:21 +0100 Subject: [PATCH] only emit one event --- .../playwright-core/src/protocol/validator.ts | 17 - .../dispatchers/mockingProxyDispatcher.ts | 27 +- packages/playwright-core/types/types.d.ts | 346 ------------------ packages/playwright/types/test.d.ts | 3 +- packages/protocol/src/channels.d.ts | 25 -- packages/protocol/src/protocol.yml | 17 - 6 files changed, 3 insertions(+), 432 deletions(-) diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index def91fc000..5cce382272 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -349,23 +349,6 @@ scheme.MockingProxyInitializer = tObject({ scheme.MockingProxyRouteEvent = tObject({ route: tChannel(['Route']), }); -scheme.MockingProxyRequestEvent = tObject({ - request: tChannel(['Request']), -}); -scheme.MockingProxyResponseEvent = tObject({ - request: tChannel(['Request']), - response: tChannel(['Response']), -}); -scheme.MockingProxyRequestFailedEvent = tObject({ - request: tChannel(['Request']), - failureText: tOptional(tString), - responseEndTiming: tNumber, -}); -scheme.MockingProxyRequestFinishedEvent = tObject({ - request: tChannel(['Request']), - response: tOptional(tChannel(['Response'])), - responseEndTiming: tNumber, -}); scheme.MockingProxySetInterceptionPatternsParams = tObject({ patterns: tArray(tObject({ glob: tOptional(tString), diff --git a/packages/playwright-core/src/server/dispatchers/mockingProxyDispatcher.ts b/packages/playwright-core/src/server/dispatchers/mockingProxyDispatcher.ts index 38fbac2f4f..5a77a37de4 100644 --- a/packages/playwright-core/src/server/dispatchers/mockingProxyDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/mockingProxyDispatcher.ts @@ -18,8 +18,8 @@ import { MockingProxy } from '../mockingProxy'; import type { RootDispatcher } from './dispatcher'; import { Dispatcher, existingDispatcher } from './dispatcher'; import type * as channels from '@protocol/channels'; -import { APIRequestContextDispatcher, RequestDispatcher, ResponseDispatcher, RouteDispatcher } from './networkDispatchers'; -import type { Request, Response, Route } from '../network'; +import { APIRequestContextDispatcher, RequestDispatcher, RouteDispatcher } from './networkDispatchers'; +import type { Route } from '../network'; import { urlMatches } from '../../utils/isomorphic/urlMatch'; export class MockingProxyDispatcher extends Dispatcher implements channels.MockingProxyChannel { @@ -40,29 +40,6 @@ export class MockingProxyDispatcher extends Dispatcher { - this._dispatchEvent('request', { request: RequestDispatcher.from(this as any, request) }); - }); - this.addObjectListener(MockingProxy.Events.RequestFailed, (request: Request) => { - this._dispatchEvent('requestFailed', { - request: RequestDispatcher.from(this as any, request), - responseEndTiming: request._responseEndTiming, - failureText: request._failureText ?? undefined - }); - }); - this.addObjectListener(MockingProxy.Events.Response, (response: Response) => { - this._dispatchEvent('response', { - request: RequestDispatcher.from(this as any, response.request()), - response: ResponseDispatcher.from(this as any, response), - }); - }); - this.addObjectListener(MockingProxy.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => { - this._dispatchEvent('requestFinished', { - request: RequestDispatcher.from(this as any, request), - response: ResponseDispatcher.fromNullable(this as any, response), - responseEndTiming: request._responseEndTiming, - }); - }); } async setInterceptionPatterns(params: channels.MockingProxySetInterceptionPatternsParams, metadata?: CallMetadata): Promise { diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 99354d3760..6bd075a633 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -20036,352 +20036,6 @@ export interface Logger { }): void; } -/** - * `MockingProxy` allows you to intercept network traffic from your application server. - * - * ```js - * const { webkit, mockingProxy } = require('playwright'); // Or 'chromium' or 'firefox'. - * - * (async () => { - * const browser = await webkit.launch(); - * const context = await browser.newContext(); - * const server = await mockingProxy.newProxy(8888); // point your application server to MockingProxy all requests through this port - * - * await server.route("https://headless-cms.example.com/posts", (route, request) => { - * await route.fulfill({ - * json: [ - * { id: 1, title: 'Hello, World!' }, - * { id: 2, title: 'Second post' }, - * { id: 2, title: 'Third post' } - * ] - * }); - * }) - * - * const page = await context.newPage(); - * await page.goto('https://localhost:3000/posts'); - * - * console.log(await page.getByRole('list').ariaSnapshot()) - * // - list: - * // - listitem: Hello, World! - * // - listitem: Second post - * // - listitem: Third post - * })(); - * ``` - * - */ -export interface MockingProxy { - /** - * Emitted when a request passes through the MockingProxy. The [request] object is read-only. In order to intercept - * and mutate requests, see - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - */ - on(event: 'request', listener: (request: Request) => any): this; - - /** - * Emitted when a request fails, for example by timing out. - */ - on(event: 'requestfailed', listener: (request: Request) => any): this; - - /** - * Emitted when a request finishes successfully after downloading the response body. For a successful response, the - * sequence of events is `request`, `response` and `requestfinished`. - */ - on(event: 'requestfinished', listener: (request: Request) => any): this; - - /** - * Emitted when [response] status and headers are received for a request. For a successful response, the sequence of - * events is `request`, `response` and `requestfinished`. - */ - on(event: 'response', listener: (response: Response) => any): this; - - /** - * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. - */ - once(event: 'request', listener: (request: Request) => any): this; - - /** - * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. - */ - once(event: 'requestfailed', listener: (request: Request) => any): this; - - /** - * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. - */ - once(event: 'requestfinished', listener: (request: Request) => any): this; - - /** - * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. - */ - once(event: 'response', listener: (response: Response) => any): this; - - /** - * Emitted when a request passes through the MockingProxy. The [request] object is read-only. In order to intercept - * and mutate requests, see - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - */ - addListener(event: 'request', listener: (request: Request) => any): this; - - /** - * Emitted when a request fails, for example by timing out. - */ - addListener(event: 'requestfailed', listener: (request: Request) => any): this; - - /** - * Emitted when a request finishes successfully after downloading the response body. For a successful response, the - * sequence of events is `request`, `response` and `requestfinished`. - */ - addListener(event: 'requestfinished', listener: (request: Request) => any): this; - - /** - * Emitted when [response] status and headers are received for a request. For a successful response, the sequence of - * events is `request`, `response` and `requestfinished`. - */ - addListener(event: 'response', listener: (response: Response) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - removeListener(event: 'request', listener: (request: Request) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - removeListener(event: 'requestfailed', listener: (request: Request) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - removeListener(event: 'requestfinished', listener: (request: Request) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - removeListener(event: 'response', listener: (response: Response) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - off(event: 'request', listener: (request: Request) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - off(event: 'requestfailed', listener: (request: Request) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - off(event: 'requestfinished', listener: (request: Request) => any): this; - - /** - * Removes an event listener added by `on` or `addListener`. - */ - off(event: 'response', listener: (response: Response) => any): this; - - /** - * Emitted when a request passes through the MockingProxy. The [request] object is read-only. In order to intercept - * and mutate requests, see - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - */ - prependListener(event: 'request', listener: (request: Request) => any): this; - - /** - * Emitted when a request fails, for example by timing out. - */ - prependListener(event: 'requestfailed', listener: (request: Request) => any): this; - - /** - * Emitted when a request finishes successfully after downloading the response body. For a successful response, the - * sequence of events is `request`, `response` and `requestfinished`. - */ - prependListener(event: 'requestfinished', listener: (request: Request) => any): this; - - /** - * Emitted when [response] status and headers are received for a request. For a successful response, the sequence of - * events is `request`, `response` and `requestfinished`. - */ - prependListener(event: 'response', listener: (response: Response) => any): this; - - port(): number; - - /** - * Routing provides the capability to modify network requests that are made through the MockingProxy. - * - * Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or - * aborted. - * - * **Usage** - * - * An example of a naive handler that aborts all requests to a specific domain: - * - * ```js - * const page = await browser.newPage(); - * const server = await page.context().newMockingProxy(8888) - * await server.route('https://api.example.com', route => route.abort()); // simulates this API being unreachable - * await page.goto('http://localhost:3000'); - * ``` - * - * It is possible to examine the request to decide the route action. For example, mocking all requests that contain - * some post data, and leaving all other requests as is: - * - * ```js - * await serer.route('https://api.example.com/*', async route => { - * if (route.request().postData().includes('my-string')) - * await route.fulfill({ body: 'mocked-data' }); - * else - * await route.continue(); - * }) - * ``` - * - * To remove a route with its handler you can use - * [mockingProxy.unroute(url[, handler])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-unroute). - * @param url A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a - * [`baseURL`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-base-url) 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. - * @param handler handler function to route the request. - * @param options - */ - route(url: string|RegExp|((url: URL) => boolean), handler: ((route: Route, request: Request) => Promise|any), options?: { - /** - * How often a route should be used. By default it will be used every time. - */ - times?: number; - }): Promise; - - /** - * Removes a route created with - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - * When [`handler`](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-unroute-option-handler) is not - * specified, removes all routes for the - * [`url`](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-unroute-option-url). - * @param url A glob pattern, regex pattern or predicate receiving [URL] used to register a routing with - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - * @param handler Optional handler function used to register a routing with - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - */ - unroute(url: string|RegExp|((url: URL) => boolean), handler?: ((route: Route, request: Request) => Promise|any)): Promise; - - /** - * Removes all routes created with - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - * @param options - */ - unrouteAll(options?: { - /** - * Specifies whether to wait for already running handlers and what to do if they throw errors: - * - `'default'` - do not wait for current handler calls (if any) to finish, if unrouted handler throws, it may - * result in unhandled error - * - `'wait'` - wait for current handler calls (if any) to finish - * - `'ignoreErrors'` - do not wait for current handler calls (if any) to finish, all errors thrown by the handlers - * after unrouting are silently caught - */ - behavior?: "wait"|"ignoreErrors"|"default"; - }): Promise; - - /** - * Emitted when a request passes through the MockingProxy. The [request] object is read-only. In order to intercept - * and mutate requests, see - * [mockingProxy.route(url, handler[, options])](https://playwright.dev/docs/api/class-mockingproxy#mocking-proxy-route). - */ - waitForEvent(event: 'request', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise, timeout?: number } | ((request: Request) => boolean | Promise)): Promise; - - /** - * Emitted when a request fails, for example by timing out. - */ - waitForEvent(event: 'requestfailed', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise, timeout?: number } | ((request: Request) => boolean | Promise)): Promise; - - /** - * Emitted when a request finishes successfully after downloading the response body. For a successful response, the - * sequence of events is `request`, `response` and `requestfinished`. - */ - waitForEvent(event: 'requestfinished', optionsOrPredicate?: { predicate?: (request: Request) => boolean | Promise, timeout?: number } | ((request: Request) => boolean | Promise)): Promise; - - /** - * Emitted when [response] status and headers are received for a request. For a successful response, the sequence of - * events is `request`, `response` and `requestfinished`. - */ - waitForEvent(event: 'response', optionsOrPredicate?: { predicate?: (response: Response) => boolean | Promise, timeout?: number } | ((response: Response) => boolean | Promise)): Promise; - - - /** - * Waits for the matching request and returns it. See [waiting for event](https://playwright.dev/docs/events#waiting-for-event) for more - * details about events. - * - * **Usage** - * - * ```js - * // Start waiting for request before clicking. Note no await. - * const requestPromise = MockingProxy.waitForRequest('https://example.com/resource'); - * await page.getByText('trigger request').click(); - * const request = await requestPromise; - * - * // Alternative way with a predicate. Note no await. - * const requestPromise = MockingProxy.waitForRequest(request => - * request.url() === 'https://example.com' && request.method() === 'GET', - * ); - * await page.getByText('trigger request').click(); - * const request = await requestPromise; - * ``` - * - * @param urlOrPredicate Request URL string, regex or predicate receiving [Request](https://playwright.dev/docs/api/class-request) object. - * @param options - */ - waitForRequest(urlOrPredicate: string|RegExp|((request: Request) => boolean|Promise), options?: { - /** - * Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout. The default value can - * be changed by using the - * [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) method. - */ - timeout?: number; - }): Promise; - - /** - * Returns the matched response. See [waiting for event](https://playwright.dev/docs/events#waiting-for-event) for more details about - * events. - * - * **Usage** - * - * ```js - * // Start waiting for response before clicking. Note no await. - * const responsePromise = MockingProxy.waitForResponse('https://example.com/resource'); - * await page.getByText('trigger response').click(); - * const response = await responsePromise; - * - * // Alternative way with a predicate. Note no await. - * const responsePromise = MockingProxy.waitForResponse(response => - * response.url() === 'https://example.com' && response.status() === 200 - * && response.request().method() === 'GET' - * ); - * await page.getByText('trigger response').click(); - * const response = await responsePromise; - * ``` - * - * @param urlOrPredicate Request URL string, regex or predicate receiving [Response](https://playwright.dev/docs/api/class-response) object. - * @param options - */ - waitForResponse(urlOrPredicate: string|RegExp|((response: Response) => boolean|Promise), options?: { - /** - * Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout. - */ - timeout?: number; - }): Promise; -} - -/** - * This class is used for creating [MockingProxy](https://playwright.dev/docs/api/class-mockingproxy) instances which - * in turn can be used to intercept network traffic from your application server. An instance of this class can be - * obtained via [playwright.mockingProxy](https://playwright.dev/docs/api/class-playwright#playwright-mocking-proxy). - * For more information see [MockingProxy](https://playwright.dev/docs/api/class-mockingproxy). - */ -export interface MockingProxyFactory { - /** - * Creates a new instance of [MockingProxy](https://playwright.dev/docs/api/class-mockingproxy). - * @param port Port to listen on. - */ - newProxy(port?: number): Promise; -} - /** * The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport. * diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 8d04cba78a..a63cd2fe92 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -6914,8 +6914,7 @@ export interface PlaywrightTestArgs { */ request: APIRequestContext; /** - * Instance of [MockingProxy](https://playwright.dev/docs/api/class-mockingproxy) that can be used to intercept - * network requests from your application server. + * Instance of [MockingProxy] that can be used to intercept network requests from your application server. */ server: MockingProxy; } diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index 5c1863b521..9e7d597158 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -586,10 +586,6 @@ export type MockingProxyInitializer = { }; export interface MockingProxyEventTarget { on(event: 'route', callback: (params: MockingProxyRouteEvent) => void): this; - on(event: 'request', callback: (params: MockingProxyRequestEvent) => void): this; - on(event: 'response', callback: (params: MockingProxyResponseEvent) => void): this; - on(event: 'requestFailed', callback: (params: MockingProxyRequestFailedEvent) => void): this; - on(event: 'requestFinished', callback: (params: MockingProxyRequestFinishedEvent) => void): this; } export interface MockingProxyChannel extends MockingProxyEventTarget, EventTargetChannel { _type_MockingProxy: boolean; @@ -598,23 +594,6 @@ export interface MockingProxyChannel extends MockingProxyEventTarget, EventTarge export type MockingProxyRouteEvent = { route: RouteChannel, }; -export type MockingProxyRequestEvent = { - request: RequestChannel, -}; -export type MockingProxyResponseEvent = { - request: RequestChannel, - response: ResponseChannel, -}; -export type MockingProxyRequestFailedEvent = { - request: RequestChannel, - failureText?: string, - responseEndTiming: number, -}; -export type MockingProxyRequestFinishedEvent = { - request: RequestChannel, - response?: ResponseChannel, - responseEndTiming: number, -}; export type MockingProxySetInterceptionPatternsParams = { patterns: { glob?: string, @@ -629,10 +608,6 @@ export type MockingProxySetInterceptionPatternsResult = void; export interface MockingProxyEvents { 'route': MockingProxyRouteEvent; - 'request': MockingProxyRequestEvent; - 'response': MockingProxyResponseEvent; - 'requestFailed': MockingProxyRequestFailedEvent; - 'requestFinished': MockingProxyRequestFinishedEvent; } // ----------- Root ----------- diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 839874d24a..7d24e97df3 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -700,23 +700,6 @@ MockingProxy: route: parameters: route: Route - request: - parameters: - request: Request - response: - parameters: - request: Request - response: Response - requestFailed: - parameters: - request: Request - failureText: string? - responseEndTiming: number - requestFinished: - parameters: - request: Request - response: Response? - responseEndTiming: number Root: type: interface