/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ var windowState = { windows: [ { tabs: [ { entries: [ { url: "http://example.com#1", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.com#2", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.com#3", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.com#4", triggeringPrincipal_base64 }, ], }, { entries: [ { url: "http://example.com#5", triggeringPrincipal_base64 }, ], hidden: true, }, { entries: [ { url: "http://example.com#6", triggeringPrincipal_base64 }, ], hidden: true, }, { entries: [ { url: "http://example.com#7", triggeringPrincipal_base64 }, ], hidden: true, }, { entries: [ { url: "http://example.com#8", triggeringPrincipal_base64 }, ], hidden: true, }, ], }, ], }; function test() { waitForExplicitFinish(); requestLongerTimeout(2); registerCleanupFunction(function() { Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs"); }); // First stage: restoreHiddenTabs = true // Second stage: restoreHiddenTabs = false test_loadTabs(true, function() { test_loadTabs(false, finish); }); } function test_loadTabs(restoreHiddenTabs, callback) { Services.prefs.setBoolPref( "browser.sessionstore.restore_hidden_tabs", restoreHiddenTabs ); let expectedTabs = restoreHiddenTabs ? 8 : 4; let firstProgress = true; newWindowWithState(windowState, function(win, needsRestore, isRestoring) { if (firstProgress) { firstProgress = false; is(isRestoring, 3, "restoring 3 tabs concurrently"); } else { ok(isRestoring < 4, "restoring max. 3 tabs concurrently"); } // We're explicity checking for (isRestoring == 1) here because the test // progress listener is called before the session store one. So when we're // called with one tab left to restore we know that the last tab has // finished restoring and will soon be handled by the SS listener. let tabsNeedingRestore = win.gBrowser.tabs.length - needsRestore; if (isRestoring == 1 && tabsNeedingRestore == expectedTabs) { is(win.gBrowser.visibleTabs.length, 4, "only 4 visible tabs"); TabsProgressListener.uninit(); executeSoon(callback); } }); } var TabsProgressListener = { init(win) { this.window = win; Services.obs.addObserver(this, "sessionstore-debug-tab-restored"); }, uninit() { Services.obs.removeObserver(this, "sessionstore-debug-tab-restored"); delete this.window; delete this.callback; }, setCallback(callback) { this.callback = callback; }, observe(browser) { TabsProgressListener.onRestored(browser); }, onRestored(browser) { if ( this.callback && ss.getInternalObjectState(browser) == TAB_STATE_RESTORING ) { this.callback.apply(null, [this.window].concat(this.countTabs())); } }, countTabs() { let needsRestore = 0, isRestoring = 0; for (let i = 0; i < this.window.gBrowser.tabs.length; i++) { let state = ss.getInternalObjectState( this.window.gBrowser.tabs[i].linkedBrowser ); if (state == TAB_STATE_RESTORING) { isRestoring++; } else if (state == TAB_STATE_NEEDS_RESTORE) { needsRestore++; } } return [needsRestore, isRestoring]; }, }; // ---------- function newWindowWithState(state, callback) { let opts = "chrome,all,dialog=no,height=800,width=800"; let win = window.openDialog(AppConstants.BROWSER_CHROME_URL, "_blank", opts); registerCleanupFunction(() => BrowserTestUtils.closeWindow(win)); whenWindowLoaded(win, function onWindowLoaded(aWin) { TabsProgressListener.init(aWin); TabsProgressListener.setCallback(callback); ss.setWindowState(aWin, JSON.stringify(state), true); }); }