From 5d5b0d8cc1627eaabb640e22c4ce724d8e690375 Mon Sep 17 00:00:00 2001 From: winst0niuss Date: Mon, 24 Nov 2025 23:14:41 +0400 Subject: [PATCH] Fix beforeunload handler crash during browser closure When closing the browser, if a page has a beforeunload event handler, Taiko would crash with 'There is no handler registered for beforeunload popup'. This fix adds a flag to automatically accept beforeunload dialogs during browser closure, preventing the crash while still allowing explicit beforeunload handling during normal operation. Fixes #2752 Signed-off-by: winst0niuss --- lib/connection.js | 3 ++- lib/handlers/pageHandler.js | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/connection.js b/lib/connection.js index 0ef8306a4..e63b6ec97 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -139,7 +139,7 @@ const connect_to_cri = async (target, options = {}) => { const closeConnection = async (promisesToBeResolvedBeforeCloseBrowser) => { if (_client) { - // remove listeners other than JS dialog for beforeUnload on client first to stop executing them when closing + pageHandler.setClosingBrowserFlag(true); await _client.removeAllListeners(); pageHandler.addJavascriptDialogOpeningListener(); if (!defaultConfig.firefox) { @@ -161,6 +161,7 @@ const closeConnection = async (promisesToBeResolvedBeforeCloseBrowser) => { : await closeBrowser(); await _client.close(); _client = null; + pageHandler.setClosingBrowserFlag(false); }; async function reconnect() { diff --git a/lib/handlers/pageHandler.js b/lib/handlers/pageHandler.js index a7ae37529..937cf3ecf 100644 --- a/lib/handlers/pageHandler.js +++ b/lib/handlers/pageHandler.js @@ -8,6 +8,7 @@ const { isSameUrl } = require("../util"); let page; let framePromises; let frameNavigationPromise; +let isClosingBrowser = false; const createdSessionListener = async (client) => { let resolve; @@ -71,6 +72,12 @@ const addJavascriptDialogOpeningListener = () => { if (eventName) { eventHandler.emit(eventName, data); eventRegexMap.delete(eventName); + } else if (data.type === "beforeunload" && isClosingBrowser) { + page + .handleJavaScriptDialog({ + accept: true, + }) + .catch(() => {}); } else { throw new Error( `There is no handler registered for ${data.type} popup displayed on the page ${data.url}. @@ -258,6 +265,10 @@ const navigateToHistoryEntry = async (entryId) => { await page.navigateToHistoryEntry({ entryId }); }; +const setClosingBrowserFlag = (value) => { + isClosingBrowser = value; +}; + module.exports = { handleNavigation, resetPromises, @@ -268,4 +279,5 @@ module.exports = { navigateToHistoryEntry, handleJavaScriptDialog, getNavigationHistory, + setClosingBrowserFlag, };