Bug 1034036 - Part 2: Test that we stored window z-indices correctly and in order of creation. Ensure that we restore windows in reverse z-index order. r?dao
MozReview-Commit-ID: 9cfpL2cAb6Y
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -264,9 +264,9 @@ skip-if = debug
[browser_duplicate_history.js]
[browser_tabicon_after_bg_tab_crash.js]
skip-if = !crashreporter || !e10s # Tabs can't crash without e10s
[browser_cookies.js]
[browser_cookies_legacy.js]
[browser_cookies_privacy.js]
[browser_speculative_connect.js]
-
+[browser_restore_reversed_z_order.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_restore_reversed_z_order.js
@@ -0,0 +1,146 @@
+let gTestURLsMap = new Map([
+ ["about:about", null],
+ ["about:license", null],
+ ["about:profiles", null],
+ ["about:mozilla", null]
+]);
+
+const Paths = SessionFile.Paths;
+const BROKEN_WM_Z_ORDER = AppConstants.platform != "macosx" && AppConstants.platform != "win";
+
+let gRawState;
+
+add_task(async function initState() {
+ // Make sure that we start with only primary window.
+ await promiseAllButPrimaryWindowClosed();
+ // Capture the global window object.
+ let primaryWindow = window;
+
+ let windows = [];
+ let count = 0;
+ for (let url of gTestURLsMap.keys()) {
+ ++count;
+ let window = count == 1 ? primaryWindow : await BrowserTestUtils.openNewBrowserWindow();
+ let browserLoadedPromise = BrowserTestUtils.browserLoaded(window.gBrowser.selectedBrowser);
+ await BrowserTestUtils.loadURI(window.gBrowser.selectedBrowser, url);
+ await browserLoadedPromise;
+ // Capture the title.
+ gTestURLsMap.set(url, window.gBrowser.selectedTab.label);
+ // Minimize the before-last window, to have a different window feature added
+ // to the test.
+ if (count == gTestURLsMap.size - 1) {
+ window.minimize();
+ }
+ windows.push(window);
+ }
+
+ // Wait until we get the lastest history from all windows.
+ await Promise.all(windows.map(window => TabStateFlusher.flushWindow(window)));
+
+ gRawState = ss.getBrowserState();
+
+ await promiseAllButPrimaryWindowClosed();
+});
+
+add_task(async function test_z_indices_are_saved_correctly() {
+ let state = JSON.parse(gRawState);
+ Assert.equal(state.windows.length, gTestURLsMap.size, "Correct number of windows saved");
+
+ // Check if we saved state in correct order of creation.
+ let idx = 0;
+ for (let url of gTestURLsMap.keys()) {
+ Assert.equal(state.windows[idx].tabs[0].entries[0].url, url,
+ `Window #${idx} is stored in correct creation order`);
+ ++idx;
+ }
+
+ // Check if we saved a valid zIndex (no null, no undefined or no 0).
+ for (let window of state.windows) {
+ Assert.ok(window.zIndex, "A valid zIndex is stored");
+ }
+
+ if (BROKEN_WM_Z_ORDER) {
+ // Last window should have zIndex of 2.
+ Assert.equal(state.windows[3].zIndex, 2, "Currently using window has correct z-index");
+
+ // Other windows should have zIndex of 1.
+ Assert.equal(state.windows[0].zIndex, 1, "Window #1 has correct z-index");
+ Assert.equal(state.windows[1].zIndex, 1, "Window #2 has correct z-index");
+
+ // Minimized window should have zIndex of -1.
+ Assert.equal(state.windows[2].zIndex, -1, "Minimized window has correct z-index");
+ } else {
+ Assert.equal(state.windows[2].zIndex, -1, "Minimized window has correct z-index");
+ Assert.ok(state.windows[0].zIndex != -1, "Window #1 shouldn't have a z-index -1");
+ Assert.ok(state.windows[1].zIndex > state.windows[0].zIndex, "Window #2 has correct z-index");
+ Assert.ok(state.windows[3].zIndex > state.windows[1].zIndex, "Currently using window has correct z-index");
+ }
+});
+
+add_task(async function test_windows_are_restored_in_reversed_z_index() {
+ let windowsOpened = 1;
+ let windows = [window];
+ let windowsRestored = 0;
+ let tabsRestoredLabels = [];
+
+ // A defer promise that will be resolved once we restored all tabs.
+ let defer = {};
+ defer.promise = new Promise((resolve, reject) => {
+ defer.resolve = resolve;
+ defer.reject = reject;
+ });
+
+ function allTabsRestored() {
+ let indexedTabLabels = [...gTestURLsMap.values()];
+ Assert.equal(tabsRestoredLabels[0], indexedTabLabels[3], "First restored tab should be previous used tab");
+ // We don't care about restoration order of windows in between the first and last window
+ // when the OS has broken wm z-order.
+ if (!BROKEN_WM_Z_ORDER) {
+ Assert.equal(tabsRestoredLabels[1], indexedTabLabels[1], "Second restored tab is correct");
+ Assert.equal(tabsRestoredLabels[2], indexedTabLabels[0], "Third restored tab is correct");
+ }
+ Assert.equal(tabsRestoredLabels[3], indexedTabLabels[2], "Last restored tab should be in minimized window");
+
+ // Finish the test.
+ defer.resolve();
+ }
+
+ function onSSWindowRestored(aEvent) {
+ if (++windowsRestored == gTestURLsMap.size) {
+ executeSoon(allTabsRestored);
+ }
+ tabsRestoredLabels.push(aEvent.target.gBrowser.tabs[0].label);
+ }
+
+ // Used to add our listener to further windows so we can catch SSWindowRestored
+ // coming from them when creating a multi-window state.
+ function windowObserver(aSubject, aTopic, aData) {
+ if (aTopic == "domwindowopened") {
+ let window = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ window.addEventListener("load", function() {
+ if (++windowsOpened == gTestURLsMap.size - 1) {
+ Services.ww.unregisterNotification(windowObserver);
+ }
+
+ // Track this window so we can remove the progress listener later.
+ windows.push(window);
+ // Add the progress listener.
+ window.addEventListener("SSWindowRestored", onSSWindowRestored, true);
+ }, { once: true });
+ }
+ }
+
+ Services.ww.registerNotification(windowObserver);
+ window.addEventListener("SSWindowRestored", onSSWindowRestored, true);
+
+ // Restore states.
+ ss.setBrowserState(gRawState);
+
+ await defer.promise;
+
+ for (let window of windows) {
+ window.removeEventListener("SSWindowRestored", onSSWindowRestored, true);
+ }
+ await promiseAllButPrimaryWindowClosed();
+});
+