fix: do not stall waiting for pending navigations after beforeunload dismiss (#33834)

This commit is contained in:
Dmitry Gozman 2024-12-03 23:55:45 +00:00 committed by GitHub
parent abf6916909
commit be78e9e11f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 0 deletions

View File

@ -846,6 +846,9 @@ class FrameSession {
event.type,
event.message,
async (accept: boolean, promptText?: string) => {
// TODO: this should actually be a CDP event that notifies about a cancelled navigation attempt.
if (this._isMainFrame() && event.type === 'beforeunload' && !accept)
this._page._frameManager.frameAbortedNavigation(this._page.mainFrame()._id, 'navigation cancelled by beforeunload dialog');
await this._client.send('Page.handleJavaScriptDialog', { accept, promptText });
},
event.defaultPrompt));

View File

@ -611,6 +611,9 @@ export class WKPage implements PageDelegate {
event.type as dialog.DialogType,
event.message,
async (accept: boolean, promptText?: string) => {
// TODO: this should actually be a RDP event that notifies about a cancelled navigation attempt.
if (event.type === 'beforeunload' && !accept)
this._page._frameManager.frameAbortedNavigation(this._page.mainFrame()._id, 'navigation cancelled by beforeunload dialog');
await this._pageProxySession.send('Dialog.handleJavaScriptDialog', { accept, promptText });
},
event.defaultPrompt));

View File

@ -104,3 +104,25 @@ it('should not stall on evaluate when dismissing beforeunload', async ({ page, s
]);
});
it('should not stall on click when dismissing beforeunload', async ({ page, server }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/33806' });
await page.goto(server.EMPTY_PAGE);
await page.setContent(`<a href="${server.PREFIX}/frames/one-frame.html">click me</a>`);
await page.evaluate(() => {
window.onbeforeunload = () => false;
});
page.on('dialog', async dialog => {
await dialog.dismiss();
});
await page.getByRole('link').click({ noWaitAfter: true });
await page.evaluate(() => {
window.onbeforeunload = null;
});
// This line should not timeout.
await page.getByRole('link').click({ timeout: 5000 });
await expect(page).toHaveURL(server.PREFIX + '/frames/one-frame.html');
});