fix: make sure page.goto navigates away from pages with beforeunload (#8770)

As of today, we can't navigate away from a page with beforeunload unless
we have an explicit `beforeunload` handler.

This patch updates our dialog auto-closing logic so that it auto-accepts
all beforeunload dialogs.

Fixes #8144
This commit is contained in:
Andrey Lushnikov 2021-09-09 23:19:50 +03:00 committed by GitHub
parent 653e25fc01
commit c5ce263de7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 2 deletions

View File

@ -115,8 +115,13 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
this._channel.on('console', ({ message }) => this.emit(Events.Page.Console, ConsoleMessage.from(message))); this._channel.on('console', ({ message }) => this.emit(Events.Page.Console, ConsoleMessage.from(message)));
this._channel.on('crash', () => this._onCrash()); this._channel.on('crash', () => this._onCrash());
this._channel.on('dialog', ({ dialog }) => { this._channel.on('dialog', ({ dialog }) => {
if (!this.emit(Events.Page.Dialog, Dialog.from(dialog))) const dialogObj = Dialog.from(dialog);
dialog.dismiss().catch(() => {}); if (!this.emit(Events.Page.Dialog, dialogObj)) {
if (dialogObj.type() === 'beforeunload')
dialog.accept({}).catch(() => {});
else
dialog.dismiss().catch(() => {});
}
}); });
this._channel.on('domcontentloaded', () => this.emit(Events.Page.DOMContentLoaded, this)); this._channel.on('domcontentloaded', () => this.emit(Events.Page.DOMContentLoaded, this));
this._channel.on('download', ({ url, suggestedFilename, artifact }) => { this._channel.on('download', ({ url, suggestedFilename, artifact }) => {

View File

@ -35,6 +35,14 @@ it('should close browsercontext with beforeunload page', async ({server, page, c
await context.close(); await context.close();
}); });
it('should be able to navigate away from page with beforeunload', async ({server, page, context }) => {
await page.goto(server.PREFIX + '/beforeunload.html');
// We have to interact with a page so that 'beforeunload' handlers
// fire.
await page.click('body');
await page.goto(server.EMPTY_PAGE);
});
it('should close page with beforeunload listener', async ({context, server}) => { it('should close page with beforeunload listener', async ({context, server}) => {
const newPage = await context.newPage(); const newPage = await context.newPage();
await newPage.goto(server.PREFIX + '/beforeunload.html'); await newPage.goto(server.PREFIX + '/beforeunload.html');