From 17bc8f9a15b56bb59adec925ed503d2f109a7be3 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Mon, 5 Feb 2024 16:56:42 -0800 Subject: [PATCH] fix(chromium): best effort 304 status on reload (#29373) Reference https://github.com/microsoft/playwright/issues/28779 --- .../src/server/chromium/crNetworkManager.ts | 10 ++++++++++ packages/playwright-core/src/server/network.ts | 5 +++++ tests/page/page-network-request.spec.ts | 10 +++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/playwright-core/src/server/chromium/crNetworkManager.ts b/packages/playwright-core/src/server/chromium/crNetworkManager.ts index af9cb8fc82dee..7dfa14c2c0587 100644 --- a/packages/playwright-core/src/server/chromium/crNetworkManager.ts +++ b/packages/playwright-core/src/server/chromium/crNetworkManager.ts @@ -760,6 +760,8 @@ class ResponseExtraInfoTracker { if (response && responseExtraInfo) { response.setResponseHeadersSize(responseExtraInfo.headersText?.length || 0); response.setRawResponseHeaders(headersObjectToArray(responseExtraInfo.headers, '\n')); + // This is racy, but proper fix reuquires risky changes, so we doing best effort here. + response.setRawStatus(responseExtraInfo.statusCode, getStatusText(responseExtraInfo.headersText)); info.responseReceivedExtraInfo[index] = undefined; } } @@ -781,3 +783,11 @@ class ResponseExtraInfoTracker { this._requests.delete(requestId); } } + +function getStatusText(headersText?: string): string { + if (!headersText) + return ''; + const statusLine = headersText.split('\n')[0]; + const match = statusLine.match(/\S+\s+\d+\s*(.*)/); + return match?.[1] ?? ''; +} \ No newline at end of file diff --git a/packages/playwright-core/src/server/network.ts b/packages/playwright-core/src/server/network.ts index 83b0093a3886e..e4ebd8489fa83 100644 --- a/packages/playwright-core/src/server/network.ts +++ b/packages/playwright-core/src/server/network.ts @@ -464,6 +464,11 @@ export class Response extends SdkObject { this._transferSizePromise.resolve(size); } + setRawStatus(status: number, statusText: string) { + this._status = status; + this._statusText = statusText; + } + setEncodedBodySize(size: number | null) { this._encodedBodySizePromise.resolve(size); } diff --git a/tests/page/page-network-request.spec.ts b/tests/page/page-network-request.spec.ts index e915ffa3d3212..26668ada90d56 100644 --- a/tests/page/page-network-request.spec.ts +++ b/tests/page/page-network-request.spec.ts @@ -451,7 +451,6 @@ it('should not allow to access frame on popup main request', async ({ page, serv it('page.reload return 304 status code', async ({ page, server, browserName }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/28779' }); - it.fixme(browserName === 'chromium', 'Returns 200 instead of 304'); it.fixme(browserName === 'firefox', 'Does not send second request'); let requestNumber = 0; server.setRoute('/test.html', (req, res) => { @@ -473,6 +472,11 @@ it('page.reload return 304 status code', async ({ page, server, browserName }) = expect(response1.status()).toBe(200); const response2 = await page.reload(); expect(requestNumber).toBe(2); - expect(response2.status()).toBe(304); - expect(response2.statusText()).toBe('Not Modified'); + if (browserName === 'chromium') { + expect([200, 304].includes(response2.status()), 'actual status: ' + response2.status()); + expect(['OK', 'Not Modified'].includes(response2.statusText()), 'actual statusText: ' + response2.statusText()); + } else { + expect(response2.status()).toBe(304); + expect(response2.statusText()).toBe('Not Modified'); + } });