/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const TEST_PAGE = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.com" ) + "dummy_page.html"; const CLOSEWATCHER_PAGE = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.com" ) + "page_with_closewatcher.html"; const runTest = (bool, baseURL = TEST_PAGE) => async () => { await SpecialPowers.pushPrefEnv({ set: [["dom.closewatcher.enabled", true]], }); let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, baseURL); await new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve) ); // Assert the hasActiveCloseWatcher property is( gBrowser.selectedBrowser.hasActiveCloseWatcher, bool, `hasActiveCloseWatcher is ${bool}` ); gBrowser.selectedBrowser.processCloseRequest(); // CloseWatcher may not be immediately closed as the request is over IPC, so allow some grace // by checking every 100ms to see if hasActiveCloseWatcher flips to false. { // eslint-disable-next-line mozilla/no-arbitrary-setTimeout const sleep = ms => new Promise(r => setTimeout(r, ms)); const hasActiveCloseWatcherEventuallyFalse = (async () => { while (gBrowser.selectedBrowser.hasActiveCloseWatcher) { await sleep(50); } })(); await Promise.race([hasActiveCloseWatcherEventuallyFalse, sleep(3000)]); } // Assert the hasActiveCloseWatcher property is false after a close request is( gBrowser.selectedBrowser.hasActiveCloseWatcher, false, `hasActiveCloseWatcher is false after processCloseRequest` ); BrowserTestUtils.removeTab(tab); }; add_task(runTest(false, TEST_PAGE)); add_task(runTest(true, CLOSEWATCHER_PAGE)); add_task(async function test_processCloseRequest_unfocused_tab() { await SpecialPowers.pushPrefEnv({ set: [["dom.closewatcher.enabled", true]], }); let cwTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, CLOSEWATCHER_PAGE ); let cwBrowser = cwTab.linkedBrowser; await new Promise(resolve => SessionStore.getSessionHistory(cwTab, resolve)); is( cwBrowser.hasActiveCloseWatcher, true, "CloseWatcher tab reports an active close watcher" ); // Open a second tab, which moves focus away from the CloseWatcher tab. let otherTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, TEST_PAGE ); isnot( gBrowser.selectedTab, cwTab, "CloseWatcher tab is no longer the selected tab" ); // Send processCloseRequest to the now-unfocused CloseWatcher tab. cwBrowser.processCloseRequest(); // SpecialPowers.spawn performs an IPC roundtrip to the content process, // which is ordered after the ProcessCloseRequest message. When it resolves // we know the handler has already run. await SpecialPowers.spawn(cwBrowser, [], () => {}); // The close watcher should still be active since the tab was not focused // when the request was processed. is( cwBrowser.hasActiveCloseWatcher, true, "CloseWatcher is still active because tab was not focused" ); BrowserTestUtils.removeTab(otherTab); BrowserTestUtils.removeTab(cwTab); });