diff --git a/packages/playwright-core/src/server/network.ts b/packages/playwright-core/src/server/network.ts index ff041fa9bb..5c6ca29abe 100644 --- a/packages/playwright-core/src/server/network.ts +++ b/packages/playwright-core/src/server/network.ts @@ -238,14 +238,12 @@ export class Route extends SdkObject { } async abort(errorCode: string = 'failed') { - assert(!this._handled, 'Route is already handled!'); - this._handled = true; + this._startHandling(); await this._delegate.abort(errorCode); } async fulfill(overrides: { status?: number, headers?: types.HeadersArray, body?: string, isBase64?: boolean, useInterceptedResponseBody?: boolean, fetchResponseUid?: string }) { - assert(!this._handled, 'Route is already handled!'); - this._handled = true; + this._startHandling(); let body = overrides.body; let isBase64 = overrides.isBase64 || false; if (body === undefined) { @@ -269,7 +267,7 @@ export class Route extends SdkObject { } async continue(overrides: types.NormalizedContinueOverrides = {}) { - assert(!this._handled, 'Route is already handled!'); + this._startHandling(); if (overrides.url) { const newUrl = new URL(overrides.url); const oldUrl = new URL(this._request.url()); @@ -278,6 +276,11 @@ export class Route extends SdkObject { } await this._delegate.continue(this._request, overrides); } + + private _startHandling() { + assert(!this._handled, 'Route is already handled!'); + this._handled = true; + } } export type RouteHandler = (route: Route, request: Request) => void; diff --git a/tests/page/page-request-continue.spec.ts b/tests/page/page-request-continue.spec.ts index 1ef212cf0e..49291148d4 100644 --- a/tests/page/page-request-continue.spec.ts +++ b/tests/page/page-request-continue.spec.ts @@ -63,16 +63,18 @@ it('should override request url', async ({ page, server }) => { }); it('should not allow changing protocol when overriding url', async ({ page, server }) => { - let error: Error | undefined; + let resolve; + const errorPromise = new Promise(f => resolve = f); await page.route('**/*', async route => { try { await route.continue({ url: 'file:///tmp/foo' }); + resolve(null); } catch (e) { - error = e; - await route.continue(); + resolve(e); } }); - await page.goto(server.EMPTY_PAGE); + page.goto(server.EMPTY_PAGE).catch(() => {}); + const error = await errorPromise; expect(error).toBeTruthy(); expect(error.message).toContain('New URL must have same protocol as overridden URL'); }); diff --git a/tests/page/page-route.spec.ts b/tests/page/page-route.spec.ts index e538e3ace4..4da1bb5b8c 100644 --- a/tests/page/page-route.spec.ts +++ b/tests/page/page-route.spec.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import { Route } from 'playwright-core'; import { test as it, expect } from './pageTest'; it('should intercept #smoke', async ({ page, server }) => { @@ -710,3 +711,16 @@ it('should contain raw response header after fulfill', async ({ page, server }) const headers = await response.allHeaders(); expect(headers['content-type']).toBeTruthy(); }); + +for (const method of ['fulfill', 'continue', 'abort'] as const) { + it(`route.${method} should throw if called twice`, async ({ page, server }) => { + const routePromise = new Promise(async resove => { + await page.route('**/*', resove); + }); + page.goto(server.PREFIX + '/empty.html').catch(() => {}); + const route = await routePromise; + await route[method](); + const e = await route[method]().catch(e => e); + expect(e.message).toContain('Route is already handled!'); + }); +}