chore: allow click close the page w/o errors (#27994)

This commit is contained in:
Pavel Feldman 2023-11-06 15:13:41 -08:00 committed by GitHub
parent ffd2e02aa3
commit 87787dcc7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 25 additions and 11 deletions

View File

@ -107,7 +107,7 @@ export class ArtifactDispatcher extends Dispatcher<Artifact, channels.ArtifactCh
} }
async delete(_: any, metadata: CallMetadata): Promise<void> { async delete(_: any, metadata: CallMetadata): Promise<void> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._object.delete(); await this._object.delete();
this._dispose(); this._dispose();
} }

View File

@ -273,7 +273,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
} }
async close(params: channels.BrowserContextCloseParams, metadata: CallMetadata): Promise<void> { async close(params: channels.BrowserContextCloseParams, metadata: CallMetadata): Promise<void> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._context.close(params); await this._context.close(params);
} }

View File

@ -56,12 +56,12 @@ export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChann
} }
async close(params: channels.BrowserCloseParams, metadata: CallMetadata): Promise<void> { async close(params: channels.BrowserCloseParams, metadata: CallMetadata): Promise<void> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._object.close(params); await this._object.close(params);
} }
async killForTests(_: any, metadata: CallMetadata): Promise<void> { async killForTests(_: any, metadata: CallMetadata): Promise<void> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._object.killForTests(); await this._object.killForTests();
} }

View File

@ -35,7 +35,7 @@ export class CDPSessionDispatcher extends Dispatcher<CDPSession, channels.CDPSes
} }
async detach(_: any, metadata: CallMetadata): Promise<void> { async detach(_: any, metadata: CallMetadata): Promise<void> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._object.detach(); await this._object.detach();
} }
} }

View File

@ -99,7 +99,7 @@ export class Dispatcher<Type extends { guid: string }, ChannelType, ParentScopeT
try { try {
return await this._openScope.race(commandPromise); return await this._openScope.race(commandPromise);
} catch (e) { } catch (e) {
if (callMetadata.closesScope && isTargetClosedError(e)) if (callMetadata.potentiallyClosesScope && isTargetClosedError(e))
return await commandPromise; return await commandPromise;
throw e; throw e;
} }

View File

@ -133,6 +133,7 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Br
} }
async click(params: channels.FrameClickParams, metadata: CallMetadata): Promise<void> { async click(params: channels.FrameClickParams, metadata: CallMetadata): Promise<void> {
metadata.potentiallyClosesScope = true;
return await this._frame.click(metadata, params.selector, params); return await this._frame.click(metadata, params.selector, params);
} }
@ -265,7 +266,7 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Br
} }
async expect(params: channels.FrameExpectParams, metadata: CallMetadata): Promise<channels.FrameExpectResult> { async expect(params: channels.FrameExpectParams, metadata: CallMetadata): Promise<channels.FrameExpectResult> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
const expectedValue = params.expectedValue ? parseArgument(params.expectedValue) : undefined; const expectedValue = params.expectedValue ? parseArgument(params.expectedValue) : undefined;
const result = await this._frame.expect(metadata, params.selector, { ...params, expectedValue }); const result = await this._frame.expect(metadata, params.selector, { ...params, expectedValue });
if (result.received !== undefined) if (result.received !== undefined)

View File

@ -68,7 +68,7 @@ export class JSHandleDispatcher extends Dispatcher<js.JSHandle, channels.JSHandl
} }
async dispose(_: any, metadata: CallMetadata) { async dispose(_: any, metadata: CallMetadata) {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
this._object.dispose(); this._object.dispose();
this._dispose(); this._dispose();
} }

View File

@ -199,7 +199,7 @@ export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, c
} }
async dispose(_: channels.APIRequestContextDisposeParams, metadata: CallMetadata): Promise<void> { async dispose(_: channels.APIRequestContextDisposeParams, metadata: CallMetadata): Promise<void> {
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._object.dispose(); await this._object.dispose();
this._dispose(); this._dispose();
} }

View File

@ -201,7 +201,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
async close(params: channels.PageCloseParams, metadata: CallMetadata): Promise<void> { async close(params: channels.PageCloseParams, metadata: CallMetadata): Promise<void> {
if (!params.runBeforeUnload) if (!params.runBeforeUnload)
metadata.closesScope = true; metadata.potentiallyClosesScope = true;
await this._page.close(metadata, params); await this._page.close(metadata, params);
} }

View File

@ -42,5 +42,5 @@ export type CallMetadata = {
objectId?: string; objectId?: string;
pageId?: string; pageId?: string;
frameId?: string; frameId?: string;
closesScope?: boolean; potentiallyClosesScope?: boolean;
}; };

View File

@ -261,6 +261,19 @@ it('should not throttle rAF in the opener page', async ({ page, server }) => {
]); ]);
}); });
it('should not throw when click closes popup', async ({ browserName, page, server }) => {
it.fixme(browserName === 'firefox');
await page.goto(server.EMPTY_PAGE);
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.evaluate(() => {
const w = window.open('about:blank');
w.document.body.innerHTML = `<button onclick="window.close()">close</button>`;
}),
]);
await popup.getByRole('button').click();
});
async function waitForRafs(page: Page, count: number): Promise<void> { async function waitForRafs(page: Page, count: number): Promise<void> {
await page.evaluate(count => new Promise<void>(resolve => { await page.evaluate(count => new Promise<void>(resolve => {
const onRaf = () => { const onRaf = () => {