diff --git a/packages/playwright-core/src/server/chromium/crNetworkManager.ts b/packages/playwright-core/src/server/chromium/crNetworkManager.ts index d13871f789d9d..fbecd213552f2 100644 --- a/packages/playwright-core/src/server/chromium/crNetworkManager.ts +++ b/packages/playwright-core/src/server/chromium/crNetworkManager.ts @@ -520,8 +520,9 @@ export class CRNetworkManager { request.request.setRawRequestHeaders(null); } this._deleteRequest(request); - // Chromium aborts 204 responses, other browsers finish them. - if (response?.status() === 204) { + // Chromium aborts 204 subresource responses, other browsers finish them. + // A 204 navigation never commits, so it must fail to abort the pending navigation. + if (response?.status() === 204 && !request.request.isNavigationRequest()) { (this._page?.frameManager || this._serviceWorker)!.reportRequestFinished(request.request, response); return; } diff --git a/tests/page/page-click.spec.ts b/tests/page/page-click.spec.ts index 34393b94b8b88..160d1868fd060 100644 --- a/tests/page/page-click.spec.ts +++ b/tests/page/page-click.spec.ts @@ -349,6 +349,19 @@ it('should click links which cause navigation', async ({ page, server }) => { await page.click('a'); }); +it('should not wait for navigation after clicking a link answered with 204', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/43279' }, +}, async ({ page, server }) => { + server.setRoute('/204', (req, res) => { + res.statusCode = 204; + res.end(); + }); + await page.goto(server.EMPTY_PAGE); + await page.setContent(`link`); + await page.click('a', { timeout: 5000 }); + expect(page.url()).toBe(server.EMPTY_PAGE); +}); + it('should click the button inside an iframe', async ({ page, server }) => { await page.goto(server.EMPTY_PAGE); await page.setContent('
spacer
'); diff --git a/tests/page/page-event-request.spec.ts b/tests/page/page-event-request.spec.ts index a4f61a4e82130..a47fd560ef8f2 100644 --- a/tests/page/page-event-request.spec.ts +++ b/tests/page/page-event-request.spec.ts @@ -278,6 +278,23 @@ it('should finish 204 request', { expect(await reqPromise).toBe('requestfinished'); }); +it('should fail 204 navigation request', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/43279' }, +}, async ({ page, server }) => { + server.setRoute('/204', (req, res) => { + res.statusCode = 204; + res.end(); + }); + await page.goto(server.EMPTY_PAGE); + const reqPromise = Promise.race([ + page.waitForEvent('requestfailed', r => r.url().endsWith('/204')).then(() => 'requestfailed'), + page.waitForEvent('requestfinished', r => r.url().endsWith('/204')).then(() => 'requestfinished'), + ]); + await page.setContent(`link`); + await page.click('a', { noWaitAfter: true }); + expect(await reqPromise).toBe('requestfailed'); +}); + it(' resource should have type image', async ({ page }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/33148' }); const [request] = await Promise.all([