Bug 1034036 - Part 3: Tests that use set state should wait until window is restored to continue. r?mikedeboer draft
authorBeekill95 <nnn_bikiu0707@yahoo.com>
Tue, 15 Aug 2017 14:45:08 +0700
changeset 661464 56f9eda830f5eca9ecf0a5c5a8d6b6175acf8635
parent 661463 eee267e2733cac80bba6d34ad1c0fe3944e07f16
child 730573 58f567269ce382eaf821e15e3c4d16e454c421cf
push id78760
push userbmo:nnn_bikiu0707@yahoo.com
push dateFri, 08 Sep 2017 13:24:18 +0000
reviewersmikedeboer
bugs1034036
milestone57.0a1
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() {