/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * Tests that tabs which aren't displayed yet (i.e. need to be reloaded) are * still displayed in the address bar results. */ const RESTRICT_TOKEN_OPENPAGE = "%"; const { PlacesTestUtils } = ChromeUtils.importESModule( "resource://testing-common/PlacesTestUtils.sys.mjs" ); const { UrlbarProviderOpenTabs } = ChromeUtils.importESModule( "resource:///modules/UrlbarProviderOpenTabs.sys.mjs" ); const { UrlbarTestUtils } = ChromeUtils.importESModule( "resource://testing-common/UrlbarTestUtils.sys.mjs" ); var stateBackup = ss.getBrowserState(); add_setup(async function () { await SpecialPowers.pushPrefEnv({ set: [ // Set the pref to true so we know exactly how many tabs should be restoring at // any given time. This guarantees that a finishing load won't start another. ["browser.sessionstore.restore_on_demand", true], // Don't restore tabs lazily. ["browser.sessionstore.restore_tabs_lazily", false], ], }); registerCleanupFunction(() => { ss.setBrowserState(stateBackup); }); info("Waiting for the Places DB to be initialized"); await PlacesUtils.promiseLargeCacheDBConnection(); await UrlbarProviderOpenTabs.promiseDBPopulated; }); add_task(async function test_unrestored_tabs_listed() { const state = { windows: [ { tabs: [ { entries: [ { url: "http://example.org/#1", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.org/#2", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.org/#3", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.org/#4", triggeringPrincipal_base64 }, ], }, ], selected: 1, }, ], }; const tabsForEnsure = new Set(); state.windows[0].tabs.forEach(function (tab) { tabsForEnsure.add(tab.entries[0].url); }); let tabsRestoring = 0; let tabsRestored = 0; await new Promise(resolve => { function handleEvent(aEvent) { if (aEvent.type == "SSTabRestoring") { tabsRestoring++; } else { tabsRestored++; } if (tabsRestoring < state.windows[0].tabs.length || tabsRestored < 1) { return; } gBrowser.tabContainer.removeEventListener( "SSTabRestoring", handleEvent, true ); gBrowser.tabContainer.removeEventListener( "SSTabRestored", handleEvent, true ); executeSoon(resolve); } // currentURI is set before SSTabRestoring is fired, so we can sucessfully check // after that has fired for all tabs. Since 1 tab will be restored though, we // also need to wait for 1 SSTabRestored since currentURI will be set, unset, then set. gBrowser.tabContainer.addEventListener("SSTabRestoring", handleEvent, true); gBrowser.tabContainer.addEventListener("SSTabRestored", handleEvent, true); ss.setBrowserState(JSON.stringify(state)); }); // Ensure any database statements started by UrlbarProviderOpenTabs are // complete before continuing. await PlacesTestUtils.promiseAsyncUpdates(); // Remove the current tab from tabsForEnsure, because switch to tab doesn't // suggest it. tabsForEnsure.delete(gBrowser.currentURI.spec); info("Searching open pages."); await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, waitForFocus, value: RESTRICT_TOKEN_OPENPAGE, }); const total = UrlbarTestUtils.getResultCount(window); info(`Found ${total} matches`); // Check to see the expected uris and titles match up (in any order) for (let i = 0; i < total; i++) { const result = await UrlbarTestUtils.getDetailsOfResultAt(window, i); if (result.heuristic) { info("Skip heuristic match"); continue; } const url = result.url; Assert.ok( tabsForEnsure.has(url), `Should have the found result '${url}' in the expected list of entries` ); // Remove the found entry from expected results. tabsForEnsure.delete(url); } // Make sure there is no reported open page that is not open. Assert.equal(tabsForEnsure.size, 0, "Should have found all the tabs"); });