Bug 1034036 - Part 3: Tests that use set state should wait until window is restored to continue. r=mikedeboer
authorBeekill95 <nnn_bikiu0707@yahoo.com>
Tue, 15 Aug 2017 14:45:08 +0700
changeset 379720 39a94e16a3694c443a985081ac1c6cd761363da2
parent 379719 b9fdf5d1b40222f6a6dcf41334d643a43d6b40ed
child 379721 0181bf16af4f45ddab48bf2e7d3b0410a17c0d08
push id32461
push userkwierso@gmail.com
push dateFri, 08 Sep 2017 20:15:32 +0000
treeherdermozilla-central@dd3736e98e4e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1034036
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1034036 - Part 3: Tests that use set state should wait until window is restored to continue. r=mikedeboer MozReview-Commit-ID: 5SZ9ePGMKF1
browser/components/extensions/test/browser/browser_ext_tabs_lazy.js
browser/components/extensions/test/browser/head.js
browser/components/sessionstore/test/browser_423132.js
browser/components/sessionstore/test/browser_461634.js
browser/components/sessionstore/test/browser_464199.js
browser/components/sessionstore/test/browser_465223.js
browser/components/sessionstore/test/browser_477657.js
browser/components/sessionstore/test/browser_490040.js
browser/components/sessionstore/test/browser_491577.js
browser/components/sessionstore/test/browser_495495.js
browser/components/sessionstore/test/browser_514751.js
browser/components/sessionstore/test/browser_607016.js
browser/components/sessionstore/test/browser_637020.js
browser/components/sessionstore/test/browser_687710.js
browser/components/sessionstore/test/browser_694378.js
browser/components/sessionstore/test/browser_frame_history.js
browser/components/sessionstore/test/browser_merge_closed_tabs.js
browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js
browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js
browser/components/sessionstore/test/browser_windowStateContainer.js
browser/components/sessionstore/test/head.js
--- a/browser/components/extensions/test/browser/browser_ext_tabs_lazy.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_lazy.js
@@ -6,16 +6,17 @@ const SESSION = {
       {entries: [{url: "about:blank"}]},
       {entries: [{url: "https://example.com/"}]},
     ],
   }],
 };
 
 add_task(async function() {
   SessionStore.setBrowserState(JSON.stringify(SESSION));
+  await promiseWindowRestored(window);
   const tab = gBrowser.tabs[1];
 
   is(tab.getAttribute("pending"), "true", "The tab is pending restore");
   is(tab.linkedBrowser.isConnected, false, "The tab is lazy");
 
   async function background() {
     const [tab] = await browser.tabs.query({url: "https://example.com/"});
     browser.test.assertRejects(
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -15,16 +15,17 @@
  *          openTabContextMenu closeTabContextMenu
  *          openToolsMenu closeToolsMenu
  *          imageBuffer imageBufferFromDataURI
  *          getListStyleImage getPanelForNode
  *          awaitExtensionPanel awaitPopupResize
  *          promiseContentDimensions alterContent
  *          promisePrefChangeObserved openContextMenuInFrame
  *          promiseAnimationFrame getCustomizableUIPanelID
+ *          promiseWindowRestored
  */
 
 // There are shutdown issues for which multiple rejections are left uncaught.
 // This bug should be fixed, but for the moment this directory is whitelisted.
 //
 // NOTE: Entire directory whitelisting should be kept to a minimum. Normally you
 //       should use "expectUncaughtRejection" to flag individual failures.
 const {PromiseTestUtils} = Cu.import("resource://testing-common/PromiseTestUtils.jsm", {});
@@ -443,8 +444,12 @@ function closePageAction(extension, win 
 
 function promisePrefChangeObserved(pref) {
   return new Promise((resolve, reject) =>
     Preferences.observe(pref, function prefObserver() {
       Preferences.ignore(pref, prefObserver);
       resolve();
     }));
 }
+
+function promiseWindowRestored(window) {
+  return new Promise(resolve => window.addEventListener("SSWindowRestored", resolve, {once: true}));
+}
--- a/browser/components/sessionstore/test/browser_423132.js
+++ b/browser/components/sessionstore/test/browser_423132.js
@@ -32,16 +32,17 @@ add_task(async function() {
   }
   Assert.equal(i, 1, "expected one cookie");
 
   // remove the cookie
   Services.cookies.removeAll();
 
   // restore the window state
   ss.setBrowserState(state);
+  await promiseWindowRestored(window);
 
   // at this point, the cookie should be restored...
   enumerator = Services.cookies.enumerator;
   let cookie2;
   while (enumerator.hasMoreElements()) {
     cookie2 = enumerator.getNext().QueryInterface(Ci.nsICookie);
     if (cookie.name == cookie2.name)
       break;
--- a/browser/components/sessionstore/test/browser_461634.js
+++ b/browser/components/sessionstore/test/browser_461634.js
@@ -33,52 +33,54 @@ function test() {
 
   // Open a window and add the above closed tab list.
   let newWin = openDialog(location, "", "chrome,all,dialog=no");
   promiseWindowLoaded(newWin).then(() => {
     gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
                             test_state.windows[0]._closedTabs.length);
     ss.setWindowState(newWin, JSON.stringify(test_state), true);
 
-    let closedTabs = SessionStore.getClosedTabData(newWin, false);
+    promiseWindowRestored(newWin).then(() => {
+      let closedTabs = SessionStore.getClosedTabData(newWin, false);
 
-    // Verify that non JSON serialized data is the same as JSON serialized data.
-    is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
-       "Non-serialized data is the same as serialized data")
+      // Verify that non JSON serialized data is the same as JSON serialized data.
+      is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
+        "Non-serialized data is the same as serialized data")
 
-    is(closedTabs.length, test_state.windows[0]._closedTabs.length,
-       "Closed tab list has the expected length");
-    is(countByTitle(closedTabs, FORGET),
-       test_state.windows[0]._closedTabs.length - remember_count,
-       "The correct amout of tabs are to be forgotten");
-    is(countByTitle(closedTabs, REMEMBER), remember_count,
-       "Everything is set up");
+      is(closedTabs.length, test_state.windows[0]._closedTabs.length,
+        "Closed tab list has the expected length");
+      is(countByTitle(closedTabs, FORGET),
+        test_state.windows[0]._closedTabs.length - remember_count,
+        "The correct amout of tabs are to be forgotten");
+      is(countByTitle(closedTabs, REMEMBER), remember_count,
+        "Everything is set up");
 
-    // All of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE.
-    ok(testForError(() => ss.forgetClosedTab({}, 0)),
-       "Invalid window for forgetClosedTab throws");
-    ok(testForError(() => ss.forgetClosedTab(newWin, -1)),
-       "Invalid tab for forgetClosedTab throws");
-    ok(testForError(() => ss.forgetClosedTab(newWin, test_state.windows[0]._closedTabs.length + 1)),
-       "Invalid tab for forgetClosedTab throws");
+      // All of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE.
+      ok(testForError(() => ss.forgetClosedTab({}, 0)),
+        "Invalid window for forgetClosedTab throws");
+      ok(testForError(() => ss.forgetClosedTab(newWin, -1)),
+        "Invalid tab for forgetClosedTab throws");
+      ok(testForError(() => ss.forgetClosedTab(newWin, test_state.windows[0]._closedTabs.length + 1)),
+        "Invalid tab for forgetClosedTab throws");
 
-    // Remove third tab, then first tab.
-    ss.forgetClosedTab(newWin, 2);
-    ss.forgetClosedTab(newWin, null);
+      // Remove third tab, then first tab.
+      ss.forgetClosedTab(newWin, 2);
+      ss.forgetClosedTab(newWin, null);
 
-    closedTabs = SessionStore.getClosedTabData(newWin, false);
+      closedTabs = SessionStore.getClosedTabData(newWin, false);
 
-    // Verify that non JSON serialized data is the same as JSON serialized data.
-    is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
-       "Non-serialized data is the same as serialized data")
+      // Verify that non JSON serialized data is the same as JSON serialized data.
+      is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
+        "Non-serialized data is the same as serialized data")
 
-    is(closedTabs.length, remember_count,
-       "The correct amout of tabs was removed");
-    is(countByTitle(closedTabs, FORGET), 0,
-       "All tabs specifically forgotten were indeed removed");
-    is(countByTitle(closedTabs, REMEMBER), remember_count,
-       "... and tabs not specifically forgetten weren't");
+      is(closedTabs.length, remember_count,
+        "The correct amout of tabs was removed");
+      is(countByTitle(closedTabs, FORGET), 0,
+        "All tabs specifically forgotten were indeed removed");
+      is(countByTitle(closedTabs, REMEMBER), remember_count,
+        "... and tabs not specifically forgetten weren't");
 
-    // Clean up.
-    gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
-    BrowserTestUtils.closeWindow(newWin).then(finish);
+      // Clean up.
+      gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
+      BrowserTestUtils.closeWindow(newWin).then(finish);
+    });
   });
 }
--- a/browser/components/sessionstore/test/browser_464199.js
+++ b/browser/components/sessionstore/test/browser_464199.js
@@ -52,16 +52,17 @@ add_task(async function() {
   }
 
   // open a window and add the above closed tab list
   let newWin = openDialog(location, "", "chrome,all,dialog=no");
   await promiseWindowLoaded(newWin);
   gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
                           test_state.windows[0]._closedTabs.length);
   ss.setWindowState(newWin, JSON.stringify(test_state), true);
+  await promiseWindowRestored(newWin);
 
   let closedTabs = JSON.parse(ss.getClosedTabData(newWin));
   is(closedTabs.length, test_state.windows[0]._closedTabs.length,
      "Closed tab list has the expected length");
   is(countByTitle(closedTabs, FORGET),
      test_state.windows[0]._closedTabs.length - remember_count,
      "The correct amout of tabs are to be forgotten");
   is(countByTitle(closedTabs, REMEMBER), remember_count,
--- a/browser/components/sessionstore/test/browser_465223.js
+++ b/browser/components/sessionstore/test/browser_465223.js
@@ -17,29 +17,35 @@ function test() {
   let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
   promiseWindowLoaded(newWin).then(() => {
     ss.setWindowValue(newWin, uniqueKey1, uniqueValue1);
 
     let newState = { windows: [{ tabs: [{ entries: [] }], extData: {} }] };
     newState.windows[0].extData[uniqueKey2] = uniqueValue2;
     ss.setWindowState(newWin, JSON.stringify(newState), false);
 
-    is(newWin.gBrowser.tabs.length, 2,
-       "original tab wasn't overwritten");
-    is(ss.getWindowValue(newWin, uniqueKey1), uniqueValue1,
-       "window value wasn't overwritten when the tabs weren't");
-    is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue2,
-       "new window value was correctly added");
+    promiseWindowRestored(newWin).then(() => {
+      is(newWin.gBrowser.tabs.length, 2,
+        "original tab wasn't overwritten");
+      is(ss.getWindowValue(newWin, uniqueKey1), uniqueValue1,
+        "window value wasn't overwritten when the tabs weren't");
+      is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue2,
+        "new window value was correctly added");
 
-    newState.windows[0].extData[uniqueKey2] = uniqueValue1;
-    ss.setWindowState(newWin, JSON.stringify(newState), true);
+      newState.windows[0].extData[uniqueKey2] = uniqueValue1;
+      ss.setWindowState(newWin, JSON.stringify(newState), true);
 
-    is(newWin.gBrowser.tabs.length, 1,
-       "original tabs were overwritten");
-    is(ss.getWindowValue(newWin, uniqueKey1), "",
-       "window value was cleared");
-    is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue1,
-       "window value was correctly overwritten");
+      promiseWindowRestored(newWin).then(() => {
+        is(newWin.gBrowser.tabs.length, 1,
+          "original tabs were overwritten");
+        is(ss.getWindowValue(newWin, uniqueKey1), "",
+          "window value was cleared");
+        is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue1,
+          "window value was correctly overwritten");
 
-    // clean up
-    BrowserTestUtils.closeWindow(newWin).then(finish);
+        // clean up
+        BrowserTestUtils.closeWindow(newWin).then(finish);
+
+      });
+    });
   });
 }
+
--- a/browser/components/sessionstore/test/browser_477657.js
+++ b/browser/components/sessionstore/test/browser_477657.js
@@ -20,41 +20,48 @@ function test() {
     let uniqueKey = "bug 477657";
     let uniqueValue = "unik" + Date.now();
 
     ss.setWindowValue(newWin, uniqueKey, uniqueValue);
     is(ss.getWindowValue(newWin, uniqueKey), uniqueValue,
        "window value was set before the window was overwritten");
     ss.setWindowState(newWin, JSON.stringify(newState), true);
 
-    // use newWin.setTimeout(..., 0) to mirror sss_restoreWindowFeatures
-    newWin.setTimeout(function() {
-      is(ss.getWindowValue(newWin, uniqueKey), "",
-         "window value was implicitly cleared");
-
-      is(newWin.windowState, newWin.STATE_MAXIMIZED,
-         "the window was maximized");
-
-      is(JSON.parse(ss.getClosedTabData(newWin)).length, 1,
-         "the closed tab was added before the window was overwritten");
-      delete newState.windows[0]._closedTabs;
-      delete newState.windows[0].sizemode;
-      ss.setWindowState(newWin, JSON.stringify(newState), true);
-
+    promiseWindowRestored(newWin).then(() => {
+      // use newWin.setTimeout(..., 0) to mirror sss_restoreWindowFeatures
       newWin.setTimeout(function() {
-        is(JSON.parse(ss.getClosedTabData(newWin)).length, 0,
-           "closed tabs were implicitly cleared");
+        is(ss.getWindowValue(newWin, uniqueKey), "",
+          "window value was implicitly cleared");
 
         is(newWin.windowState, newWin.STATE_MAXIMIZED,
-           "the window remains maximized");
-        newState.windows[0].sizemode = "normal";
+          "the window was maximized");
+
+        is(JSON.parse(ss.getClosedTabData(newWin)).length, 1,
+          "the closed tab was added before the window was overwritten");
+        delete newState.windows[0]._closedTabs;
+        delete newState.windows[0].sizemode;
         ss.setWindowState(newWin, JSON.stringify(newState), true);
 
-        newWin.setTimeout(function() {
-          isnot(newWin.windowState, newWin.STATE_MAXIMIZED,
-                "the window was explicitly unmaximized");
+        promiseWindowRestored(newWin).then(() => {
+          newWin.setTimeout(function() {
+            is(JSON.parse(ss.getClosedTabData(newWin)).length, 0,
+              "closed tabs were implicitly cleared");
+
+            is(newWin.windowState, newWin.STATE_MAXIMIZED,
+              "the window remains maximized");
+            newState.windows[0].sizemode = "normal";
+            ss.setWindowState(newWin, JSON.stringify(newState), true);
 
-          BrowserTestUtils.closeWindow(newWin).then(finish);
-        }, 0);
+            promiseWindowRestored(newWin).then(() => {
+              newWin.setTimeout(function() {
+                isnot(newWin.windowState, newWin.STATE_MAXIMIZED,
+                  "the window was explicitly unmaximized");
+
+                BrowserTestUtils.closeWindow(newWin).then(finish);
+              }, 0);
+            });
+          }, 0);
+        });
       }, 0);
-    }, 0);
+    });
   });
 }
+
--- a/browser/components/sessionstore/test/browser_490040.js
+++ b/browser/components/sessionstore/test/browser_490040.js
@@ -46,16 +46,17 @@ add_task(async function test_bug_490040(
     let startingClosedWindowCount = ss.getClosedWindowCount();
     await pushPrefs(["browser.sessionstore.max_windows_undo",
                      startingClosedWindowCount + 1]);
 
     let curClosedWindowCount = ss.getClosedWindowCount();
     let win = await BrowserTestUtils.openNewBrowserWindow();
 
     ss.setWindowState(win, JSON.stringify(state.windowState), true);
+    await promiseWindowRestored(win);
     if (state.windowState.windows[0].tabs.length) {
       await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
     }
 
     await BrowserTestUtils.closeWindow(win);
 
     is(ss.getClosedWindowCount(),
        curClosedWindowCount + (state.shouldBeAdded ? 1 : 0),
--- a/browser/components/sessionstore/test/browser_491577.js
+++ b/browser/components/sessionstore/test/browser_491577.js
@@ -80,40 +80,43 @@ function test() {
 
   // open a window and add the above closed window list
   let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
   promiseWindowLoaded(newWin).then(() => {
     gPrefService.setIntPref("browser.sessionstore.max_windows_undo",
                             test_state._closedWindows.length);
     ss.setWindowState(newWin, JSON.stringify(test_state), true);
 
-    let closedWindows = JSON.parse(ss.getClosedWindowData());
-    is(closedWindows.length, test_state._closedWindows.length,
-       "Closed window list has the expected length");
-    is(countByTitle(closedWindows, FORGET),
-       test_state._closedWindows.length - remember_count,
-       "The correct amount of windows are to be forgotten");
-    is(countByTitle(closedWindows, REMEMBER), remember_count,
-       "Everything is set up.");
+    promiseWindowRestored(newWin).then(() => {
+      let closedWindows = JSON.parse(ss.getClosedWindowData());
+      is(closedWindows.length, test_state._closedWindows.length,
+        "Closed window list has the expected length");
+      is(countByTitle(closedWindows, FORGET),
+        test_state._closedWindows.length - remember_count,
+        "The correct amount of windows are to be forgotten");
+      is(countByTitle(closedWindows, REMEMBER), remember_count,
+        "Everything is set up.");
 
-    // all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
-    ok(testForError(() => ss.forgetClosedWindow(-1)),
-       "Invalid window for forgetClosedWindow throws");
-    ok(testForError(() => ss.forgetClosedWindow(test_state._closedWindows.length + 1)),
-       "Invalid window for forgetClosedWindow throws");
+      // all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
+      ok(testForError(() => ss.forgetClosedWindow(-1)),
+        "Invalid window for forgetClosedWindow throws");
+      ok(testForError(() => ss.forgetClosedWindow(test_state._closedWindows.length + 1)),
+        "Invalid window for forgetClosedWindow throws");
 
-    // Remove third window, then first window
-    ss.forgetClosedWindow(2);
-    ss.forgetClosedWindow(null);
+      // Remove third window, then first window
+      ss.forgetClosedWindow(2);
+      ss.forgetClosedWindow(null);
 
-    closedWindows = JSON.parse(ss.getClosedWindowData());
-    is(closedWindows.length, remember_count,
-       "The correct amount of windows were removed");
-    is(countByTitle(closedWindows, FORGET), 0,
-       "All windows specifically forgotten were indeed removed");
-    is(countByTitle(closedWindows, REMEMBER), remember_count,
-       "... and windows not specifically forgetten weren't.");
+      closedWindows = JSON.parse(ss.getClosedWindowData());
+      is(closedWindows.length, remember_count,
+        "The correct amount of windows were removed");
+      is(countByTitle(closedWindows, FORGET), 0,
+        "All windows specifically forgotten were indeed removed");
+      is(countByTitle(closedWindows, REMEMBER), remember_count,
+        "... and windows not specifically forgetten weren't.");
 
-    // clean up
-    gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
-    BrowserTestUtils.closeWindow(newWin).then(finish);
+      // clean up
+      gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
+      BrowserTestUtils.closeWindow(newWin).then(finish);
+    });
   });
 }
+
--- a/browser/components/sessionstore/test/browser_495495.js
+++ b/browser/components/sessionstore/test/browser_495495.js
@@ -17,26 +17,28 @@ function test() {
       promiseWindowLoaded(newWin).then(() => {
         let state2 = ss.getWindowState(newWin);
 
         function testState(state, expected, callback) {
           let win = openDialog(location, "_blank", "chrome,all,dialog=no");
           promiseWindowLoaded(win).then(() => {
 
             is(win.gURLBar.readOnly, false,
-               "URL bar should not be read-only before setting the state");
+              "URL bar should not be read-only before setting the state");
             is(win.gURLBar.getAttribute("enablehistory"), "true",
-               "URL bar autocomplete should be enabled before setting the state");
+              "URL bar autocomplete should be enabled before setting the state");
             ss.setWindowState(win, state, true);
-            is(win.gURLBar.readOnly, expected.readOnly,
-               "URL bar read-only state should be restored correctly");
-            is(win.gURLBar.getAttribute("enablehistory"), expected.enablehistory,
-               "URL bar autocomplete state should be restored correctly");
+            promiseWindowRestored(win).then(() => {
+              is(win.gURLBar.readOnly, expected.readOnly,
+                "URL bar read-only state should be restored correctly");
+              is(win.gURLBar.getAttribute("enablehistory"), expected.enablehistory,
+                "URL bar autocomplete state should be restored correctly");
 
-            BrowserTestUtils.closeWindow(win).then(callback);
+              BrowserTestUtils.closeWindow(win).then(callback);
+            });
           });
         }
 
         BrowserTestUtils.closeWindow(newWin).then(() => {
           testState(state1, {readOnly: false, enablehistory: "true"}, function() {
             testState(state2, {readOnly: true, enablehistory: "false"}, finish);
           });
         });
--- a/browser/components/sessionstore/test/browser_514751.js
+++ b/browser/components/sessionstore/test/browser_514751.js
@@ -23,14 +23,16 @@ function test() {
     executeSoon(function() {
       var gotError = false;
       try {
         ss.setWindowState(theWin, JSON.stringify(state), true);
       } catch (e) {
         if (/NS_ERROR_MALFORMED_URI/.test(e))
           gotError = true;
       }
-      ok(!gotError, "Didn't get a malformed URI error.");
-      BrowserTestUtils.closeWindow(theWin).then(finish);
+      promiseWindowRestored(theWin).then(() => {
+        ok(!gotError, "Didn't get a malformed URI error.");
+        BrowserTestUtils.closeWindow(theWin).then(finish);
+      });
     });
   }, {once: true});
 }
 
--- a/browser/components/sessionstore/test/browser_607016.js
+++ b/browser/components/sessionstore/test/browser_607016.js
@@ -78,16 +78,17 @@ add_task(async function() {
 
     while (gBrowser.tabs.length > 1) {
       await promiseRemoveTab(gBrowser.tabs[1]);
     }
   }
 
   // Set the test state.
   ss.setBrowserState(JSON.stringify(state));
+  await promiseWindowRestored(window);
 
   // Wait until the selected tab is restored and all others are pending.
   await Promise.all(Array.map(gBrowser.tabs, tab => {
     return (tab == gBrowser.selectedTab) ?
       promiseTabRestored(tab) : promiseTabRestoring(tab)
   }));
 
   // Kick off the actual tests.
--- a/browser/components/sessionstore/test/browser_637020.js
+++ b/browser/components/sessionstore/test/browser_637020.js
@@ -37,16 +37,17 @@ add_task(async function test() {
     }, "domwindowopened");
   });
 
   // Set the new browser state that will
   // restore a window with two slowly loading tabs.
   let backupState = SessionStore.getBrowserState();
   SessionStore.setBrowserState(JSON.stringify(TEST_STATE));
   let win = await promiseWindow;
+  await promiseWindowRestored(win);
 
   // The window has now been opened. Check the state that is returned,
   // this should come from the cache while the window isn't restored, yet.
   info("the window has been opened");
   checkWindows();
 
   // The history has now been restored and the tabs are loading. The data must
   // now come from the window, if it's correctly been marked as dirty before.
--- a/browser/components/sessionstore/test/browser_687710.js
+++ b/browser/components/sessionstore/test/browser_687710.js
@@ -32,17 +32,18 @@ var state = {windows: [{tabs: [{entries:
         docIdentifier: 1,
         url: "http://example.com",
         triggeringPrincipal_base64,
       }
     ]
   }
 ]}]}]}
 
-function test() {
+add_task(async function test() {
   registerCleanupFunction(function() {
     ss.setBrowserState(stateBackup);
   });
 
   /* This test fails by hanging. */
   ss.setBrowserState(JSON.stringify(state));
+  await promiseWindowRestored(window);
   ok(true, "Didn't hang!");
-}
+});
--- a/browser/components/sessionstore/test/browser_694378.js
+++ b/browser/components/sessionstore/test/browser_694378.js
@@ -19,14 +19,17 @@ function test() {
   let gotError = false;
   try {
     ss.setWindowState(window, brokenStateString, true);
   } catch (ex) {
     gotError = true;
     info(ex);
   }
 
-  ok(!gotError, "ss.setWindowState did not throw an error");
+  promiseWindowRestored(window).then(() => {
+    ok(!gotError, "ss.setWindowState did not throw an error");
 
-  // Make sure that we reset the state. Use a full state just in case things get crazy.
-  let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }]}]};
-  waitForBrowserState(blankState, finish);
+    // Make sure that we reset the state. Use a full state just in case things get crazy.
+    let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }]}]};
+    waitForBrowserState(blankState, finish);
+  });
 }
+
--- a/browser/components/sessionstore/test/browser_frame_history.js
+++ b/browser/components/sessionstore/test/browser_frame_history.js
@@ -96,29 +96,32 @@ add_task(async function() {
        "frame " + i + " has the right url");
   }
   gBrowser.removeTab(newTab);
 });
 
 // Now, test that we don't record history if the iframe is added dynamically
 add_task(async function() {
   // Start with an empty history
-    let blankState = JSON.stringify({
-      windows: [{
-        tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }],
-        _closedTabs: []
-      }],
-      _closedWindows: []
-    });
-    ss.setBrowserState(blankState);
+  let blankState = JSON.stringify({
+    windows: [{
+      tabs: [{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }],
+      _closedTabs: []
+    }],
+    _closedWindows: []
+  });
+  ss.setBrowserState(blankState);
+  await promiseWindowRestored(window);
 
   let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index_blank.html";
   let tab = BrowserTestUtils.addTab(gBrowser, testURL);
   gBrowser.selectedTab = tab;
+  dump("Wait here\n");
   await waitForLoadsInBrowser(tab.linkedBrowser, 1);
+  dump("Finished Wait here\n");
 
   info("dynamic: Opening a page with an iframe containing three frames, 4 dynamic loads should take place");
   let doc = tab.linkedBrowser.contentDocument;
   let iframe = doc.createElement("iframe");
   iframe.id = "iframe";
   iframe.src = "browser_frame_history_index.html";
   doc.body.appendChild(iframe);
   await waitForLoadsInBrowser(tab.linkedBrowser, 4);
--- a/browser/components/sessionstore/test/browser_merge_closed_tabs.js
+++ b/browser/components/sessionstore/test/browser_merge_closed_tabs.js
@@ -32,21 +32,23 @@ add_task(async function() {
   }
 
   const maxTabsUndo = 4;
   gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", maxTabsUndo);
 
   // Open a new window and restore it to an initial state.
   let win = await promiseNewWindowLoaded({private: false});
   SessionStore.setWindowState(win, JSON.stringify(initialState), true);
+  await promiseWindowRestored(win);
   is(SessionStore.getClosedTabCount(win), 2, "2 closed tabs after restoring initial state");
 
   // Restore the new state but do not overwrite existing tabs (this should
   // cause the closed tabs to be merged).
   SessionStore.setWindowState(win, JSON.stringify(restoreState), false);
+  await promiseWindowRestored(win);
 
   // Verify the windows closed tab data is correct.
   let iClosed = initialState.windows[0]._closedTabs;
   let rClosed = restoreState.windows[0]._closedTabs;
   let cData = JSON.parse(SessionStore.getClosedTabData(win));
 
   is(cData.length, Math.min(iClosed.length + rClosed.length, maxTabsUndo),
      "Number of closed tabs is correct");
--- a/browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js
+++ b/browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js
@@ -130,16 +130,17 @@ async function runScenarios(scenarios) {
       await BrowserTestUtils.switchTab(tabbrowser, tabToSelect);
     }
 
     // Okay, time to test!
     let state = prepareState(scenario.stateToRestore,
                              scenario.selectedTab);
 
     SessionStore.setWindowState(win, state, true);
+    await promiseWindowRestored(win);
 
     for (let i = 0; i < scenario.expectedRemoteness.length; ++i) {
       let expectedRemoteness = scenario.expectedRemoteness[i];
       let tab = tabbrowser.tabs[i];
 
       Assert.equal(tab.linkedBrowser.isRemoteBrowser, expectedRemoteness,
                    "Should have gotten the expected remoteness " +
                    `for the tab at index ${i}`);
--- a/browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js
+++ b/browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js
@@ -130,16 +130,17 @@ add_task(async function run_test() {
   // Clear cookies.
   Services.cookies.removeAll();
 
   // Open a new window.
   let win = await promiseNewWindowLoaded();
 
   // Restore window with session cookies that have no originAttributes.
   ss.setWindowState(win, SESSION_DATA, true);
+  await promiseWindowRestored(win);
 
   let enumerator = Services.cookies.getCookiesFromHost(TEST_HOST, {});
   let cookie;
   let cookieCount = 0;
   while (enumerator.hasMoreElements()) {
     cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
     cookieCount++;
   }
@@ -150,16 +151,17 @@ add_task(async function run_test() {
   is(cookie.value, COOKIE.value, "cookie value successfully restored");
   is(cookie.path, COOKIE.path, "cookie path successfully restored");
 
   // Clear cookies.
   Services.cookies.removeAll();
 
   // Restore window with session cookies that have originAttributes within.
   ss.setWindowState(win, SESSION_DATA_OA, true);
+  await promiseWindowRestored(win);
 
   enumerator = Services.cookies.getCookiesFromHost(TEST_HOST, {});
   cookieCount = 0;
   while (enumerator.hasMoreElements()) {
     cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
     cookieCount++;
   }
 
--- a/browser/components/sessionstore/test/browser_windowStateContainer.js
+++ b/browser/components/sessionstore/test/browser_windowStateContainer.js
@@ -37,16 +37,17 @@ add_task(async function() {
   // fewer tabs and with different order with win.
   for (let userContextId = 3; userContextId > 0; userContextId--) {
     let tab = win2.gBrowser.addTab("http://example.com/", {userContextId});
     await promiseBrowserLoaded(tab.linkedBrowser);
     await TabStateFlusher.flush(tab.linkedBrowser);
   }
 
   ss.setWindowState(win2, JSON.stringify(winState), true);
+  await promiseWindowRestored(win2);
 
   for (let i = 0; i < 4; i++) {
     let browser = win2.gBrowser.tabs[i].linkedBrowser;
     await ContentTask.spawn(browser, { expectedId: i + 1 }, async function(args) {
       Assert.equal(docShell.getOriginAttributes().userContextId,
                    args.expectedId,
                    "The docShell has the correct userContextId");
 
@@ -97,16 +98,17 @@ add_task(async function() {
   await TabStateFlusher.flush(tab2.linkedBrowser);
 
   // Move the first normal tab to end, so the first tab of win2 will be a
   // container tab.
   win2.gBrowser.moveTabTo(win2.gBrowser.tabs[0], win2.gBrowser.tabs.length - 1);
   await TabStateFlusher.flush(win2.gBrowser.tabs[0].linkedBrowser);
 
   ss.setWindowState(win2, JSON.stringify(winState), true);
+  await promiseWindowRestored(win2);
 
   for (let i = 0; i < 2; i++) {
     let browser = win2.gBrowser.tabs[i].linkedBrowser;
     await ContentTask.spawn(browser, { expectedId: i }, async function(args) {
       Assert.equal(docShell.getOriginAttributes().userContextId,
                    args.expectedId,
                    "The docShell has the correct userContextId");
 
--- a/browser/components/sessionstore/test/head.js
+++ b/browser/components/sessionstore/test/head.js
@@ -181,16 +181,20 @@ function promiseTabState(tab, state) {
     state = JSON.stringify(state);
   }
 
   let promise = promiseTabRestored(tab);
   ss.setTabState(tab, state);
   return promise;
 }
 
+function promiseWindowRestored(win) {
+  return new Promise(resolve => win.addEventListener("SSWindowRestored", resolve, {once: true}));
+}
+
 /**
  * Wait for a content -> chrome message.
  */
 function promiseContentMessage(browser, name) {
   let mm = browser.messageManager;
 
   return new Promise(resolve => {
     function removeListener() {