diff --git a/packages/playwright-core/src/server/chromium/crNetworkManager.ts b/packages/playwright-core/src/server/chromium/crNetworkManager.ts index 6411457a32..93981d717e 100644 --- a/packages/playwright-core/src/server/chromium/crNetworkManager.ts +++ b/packages/playwright-core/src/server/chromium/crNetworkManager.ts @@ -368,6 +368,10 @@ export class CRNetworkManager { _createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response, hasExtraInfo: boolean): network.Response { const getResponseBody = async () => { + const fulfilledBody = request._route?._fulfilledBody; + if (fulfilledBody) + return fulfilledBody; + const contentLengthHeader = Object.entries(responsePayload.headers).find(header => header[0].toLowerCase() === 'content-length'); const expectedLength = contentLengthHeader ? +contentLengthHeader[1] : undefined; @@ -595,6 +599,7 @@ class RouteImpl implements network.RouteDelegate { private readonly _session: CRSession; private _interceptionId: string; _alreadyContinuedParams: Protocol.Fetch.continueRequestParameters | undefined; + _fulfilledBody: Buffer | undefined; constructor(session: CRSession, interceptionId: string) { this._session = session; @@ -616,6 +621,7 @@ class RouteImpl implements network.RouteDelegate { async fulfill(response: types.NormalizedFulfillResponse) { const body = response.isBase64 ? response.body : Buffer.from(response.body).toString('base64'); + this._fulfilledBody = Buffer.from(body, 'base64'); const responseHeaders = splitSetCookieHeader(response.headers); await catchDisallowedErrors(async () => { diff --git a/tests/page/page-request-fulfill.spec.ts b/tests/page/page-request-fulfill.spec.ts index 16f559b467..047ea2b800 100644 --- a/tests/page/page-request-fulfill.spec.ts +++ b/tests/page/page-request-fulfill.spec.ts @@ -457,3 +457,32 @@ it('should fulfill with gzip and readback', { await expect(page.locator('body')).toHaveCSS('background-color', 'rgb(255, 192, 203)'); expect(await response.text()).toContain(`
hello, world!
`); }); + +it('should not go to the network for fulfilled requests body', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30760' }, +}, async ({ page, server, browserName }) => { + await page.route('**/one-style.css', async route => { + return route.fulfill({ + status: 404, + contentType: 'text/plain', + body: 'Not Found! (mocked)', + }); + }); + + let serverHit = false; + server.setRoute('/one-style.css', (req, res) => { + serverHit = true; + res.setHeader('Content-Type', 'text/css'); + res.end('body { background-color: green; }'); + }); + + const responsePromise = page.waitForResponse('**/one-style.css'); + await page.goto(server.PREFIX + '/one-style.html'); + const response = await responsePromise; + const body = await response.text(); + // In webkit the response body is not available. + if (browserName !== 'webkit') + expect(body).toBe('Not Found! (mocked)'); + expect(serverHit).toBe(false); +}); +