Skip to content

Commit

Permalink
fix: interrupt request.allHeaders()/response() on page.close() (#27695)
Browse files Browse the repository at this point in the history
Reference #27227
  • Loading branch information
yury-s authored Oct 23, 2023
1 parent 5752a28 commit 5e51a73
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
10 changes: 7 additions & 3 deletions packages/playwright-core/src/server/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type * as frames from './frames';
import type * as types from './types';
import type * as channels from '@protocol/channels';
import { assert } from '../utils';
import { ManualPromise } from '../utils/manualPromise';
import { LongStandingScope, ManualPromise } from '../utils/manualPromise';
import { SdkObject } from './instrumentation';
import type { HeadersArray, NameValue } from '../common/types';
import { APIRequestContext } from './fetch';
Expand Down Expand Up @@ -129,6 +129,10 @@ export class Request extends SdkObject {
this._isFavicon = url.endsWith('/favicon.ico') || !!redirectedFrom?._isFavicon;
}

private _targetClosedScope(): LongStandingScope {
return this._serviceWorker?.openScope || this._frame?._page.openScope || new LongStandingScope();
}

_setFailureText(failureText: string) {
this._failureText = failureText;
this._waitForResponsePromise.resolve(null);
Expand Down Expand Up @@ -179,11 +183,11 @@ export class Request extends SdkObject {
}

async rawRequestHeaders(): Promise<HeadersArray> {
return this._overrides?.headers || this._rawRequestHeadersPromise;
return this._overrides?.headers || this._targetClosedScope().race(this._rawRequestHeadersPromise);
}

response(): PromiseLike<Response | null> {
return this._waitForResponsePromise;
return this._targetClosedScope().race(this._waitForResponsePromise);
}

_existingResponse(): Response | null {
Expand Down
21 changes: 21 additions & 0 deletions tests/page/page-event-network.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import type { ServerResponse } from 'http';
import { test as it, expect } from './pageTest';
import { kTargetClosedErrorMessage } from '../config/errors';

it('Page.Events.Request @smoke', async ({ page, server }) => {
const requests = [];
Expand Down Expand Up @@ -137,3 +138,23 @@ it('should resolve responses after a navigation', async ({ page, server, browser
// the response should resolve to null, because the page navigated.
expect(await responsePromise).toBe(null);
});

it('interrupt request.response() and request.allHeaders() on page.close', async ({ page, server, browserName }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/27227' });
server.setRoute('/one-style.css', (req, res) => {
res.setHeader('Content-Type', 'text/css');
});
const reqPromise = page.waitForRequest('**/one-style.css');
await page.goto(server.PREFIX + '/one-style.html', { waitUntil: 'domcontentloaded' });
const req = await reqPromise;
const respPromise = req.response().catch(e => e);
const headersPromise = req.allHeaders().catch(e => e);
await page.close();
expect((await respPromise).message).toContain(kTargetClosedErrorMessage);
// All headers are the same as "provisional" headers in Firefox.
if (browserName === 'firefox')
expect((await headersPromise)['user-agent']).toBeTruthy();
else
expect((await headersPromise).message).toContain(kTargetClosedErrorMessage);

});

0 comments on commit 5e51a73

Please sign in to comment.