Bug 1364364 - Part 5.2: Remove browser.sessionhistory.cache_subframes and fix test cases relying on it. r=smaug
☠☠ backed out by 38c2e85644f9 ☠ ☠
authorSamael Wang <freesamael@gmail.com>
Tue, 05 Sep 2017 16:02:04 +0800
changeset 428953 0458fccefb5c19786f6ca73461234d20f54a4fb7
parent 428952 d89fe870c4a8be26351ec577c33f98db612e3d59
child 428954 f562d0ea59ef5967b3dc74d1f836c04ed4b97286
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1364364
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 1364364 - Part 5.2: Remove browser.sessionhistory.cache_subframes and fix test cases relying on it. r=smaug browser.sessionhistory.cache_subframes has been disabled for 12yrs. It's not actually maintained and it leaks content viewers. Using this unreliable feature in test cases is a bad practice, so remove the pref completely and fix existing test cases. MozReview-Commit-ID: 3tQLpsqmmaq
docshell/base/nsDocShell.cpp
docshell/test/chrome/bug608669.xul
docshell/test/chrome/test_bug608669.xul
dom/indexedDB/test/bfcache_page1.html
dom/indexedDB/test/bfcache_page2.html
dom/indexedDB/test/test_bfcache.html
dom/media/webspeech/synth/test/file_bfcache_page1.html
dom/media/webspeech/synth/test/file_bfcache_page2.html
dom/media/webspeech/synth/test/test_bfcache.html
dom/workers/test/WorkerDebugger_frozen_window1.html
dom/workers/test/WorkerDebugger_frozen_window2.html
dom/workers/test/blank.html
dom/workers/test/mochitest.ini
dom/workers/test/multi_sharedWorker_frame.html
dom/workers/test/test_WorkerDebugger_frozen.xul
dom/workers/test/test_multi_sharedWorker_lifetimes.html
dom/workers/test/test_onLine.html
dom/workers/test/test_suspend.html
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8309,26 +8309,21 @@ nsDocShell::CanSavePresentation(uint32_t
   }
 
   // Avoid doing the work of saving the presentation state in the case where
   // the content viewer cache is disabled.
   if (nsSHistory::GetMaxTotalViewers() == 0) {
     return false;
   }
 
-  // Don't cache the content viewer if we're in a subframe and the subframe
-  // pref is disabled.
-  bool cacheFrames =
-    Preferences::GetBool("browser.sessionhistory.cache_subframes", false);
-  if (!cacheFrames) {
-    nsCOMPtr<nsIDocShellTreeItem> root;
-    GetSameTypeParent(getter_AddRefs(root));
-    if (root && root != this) {
-      return false;  // this is a subframe load
-    }
+  // Don't cache the content viewer if we're in a subframe.
+  nsCOMPtr<nsIDocShellTreeItem> root;
+  GetSameTypeParent(getter_AddRefs(root));
+  if (root && root != this) {
+    return false;  // this is a subframe load
   }
 
   // If the document does not want its presentation cached, then don't.
   nsCOMPtr<nsIDocument> doc = mScriptGlobal->GetExtantDoc();
   return doc && doc->CanSavePresentation(aNewRequest);
 }
 
 void
--- a/docshell/test/chrome/bug608669.xul
+++ b/docshell/test/chrome/bug608669.xul
@@ -1,6 +1,14 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <window title="Mozilla Bug 608669 - Blank page"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+  onload="notifyOpener();">
   <description flex="1" value="This window is intentionally left blank"/>
+  <script type="application/javascript">
+  function notifyOpener() {
+    if (opener) {
+      opener.postMessage("load", "*");
+    }
+  }
+  </script>
 </window>
--- a/docshell/test/chrome/test_bug608669.xul
+++ b/docshell/test/chrome/test_bug608669.xul
@@ -13,53 +13,28 @@ https://bugzilla.mozilla.org/show_bug.cg
   <body xmlns="http://www.w3.org/1999/xhtml">
   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=608669"
      target="_blank">Mozilla Bug 608669</a>
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
 
-var gOrigMaxTotalViewers = undefined;
-function setCachePref(enabled) {
-  var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
-                             .getService(Components.interfaces.nsIPrefBranch);
-  if (enabled) {
-    is(typeof gOrigMaxTotalViewers, "undefined", "don't double-enable bfcache");
-    prefBranch.setBoolPref("browser.sessionhistory.cache_subframes", true);
-    gOrigMaxTotalViewers = prefBranch.getIntPref("browser.sessionhistory.max_total_viewers");
-    prefBranch.setIntPref("browser.sessionhistory.max_total_viewers", 10);
-  }
-  else {
-    is(typeof gOrigMaxTotalViewers, "number", "don't double-disable bfcache");
-    prefBranch.setIntPref("browser.sessionhistory.max_total_viewers", gOrigMaxTotalViewers);
-    gOrigMaxTotalViewers = undefined;
-    try {
-      prefBranch.clearUserPref("browser.sessionhistory.cache_subframes");
-    } catch (e) { /* Pref didn't exist, meh */ }
-  }
-}
-
-
 /** Test for Bug 608669 **/
 SimpleTest.waitForExplicitFinish();
 
 addLoadEvent(nextTest);
 
 gen = doTest();
 
 function nextTest() {
   gen.next();
 }
 
 function* doTest() {
-  var container = document.getElementById('container');
-
-  setCachePref(true);
-
   var notificationCount = 0;
   var observer = {
     observe: function(aSubject, aTopic, aData) {
       is(aTopic, "chrome-document-global-created",
          "correct topic");
       is(aData, "null",
          "correct data");
       notificationCount++;
@@ -68,49 +43,36 @@ function* doTest() {
 
   var os = Components.classes["@mozilla.org/observer-service;1"].
     getService(Components.interfaces.nsIObserverService);
   os.addObserver(observer, "chrome-document-global-created");
   os.addObserver(observer, "content-document-global-created");
 
   is(notificationCount, 0, "initial count");
 
-  // create a new iframe
-  var iframe = document.createElement("iframe");
-  container.appendChild(iframe);
-  iframe.contentWindow.x = "y";
-  is(notificationCount, 1, "after created iframe");
-  
-  // Try loading in an iframe
-  iframe.setAttribute("src", "bug608669.xul");
-  iframe.onload = nextTest;
+  // create a new window
+  var testWin = window.open("", "bug 608669", "chrome,width=600,height=600");
+  testWin.x = "y";
+  is(notificationCount, 1, "after created window");
+
+  // Try loading in the window
+  testWin.location = "bug608669.xul";
+  window.onmessage = nextTest;
   yield undefined;
   is(notificationCount, 1, "after first load");
-  is(iframe.contentWindow.x, "y", "reused window");
+  is(testWin.x, "y", "reused window");
 
-  // Try loading again in an iframe
-  iframe.setAttribute("src", "bug608669.xul?x");
-  iframe.onload = nextTest;
+  // Try loading again in the window
+  testWin.location = "bug608669.xul?x";
+  window.onmessage = nextTest;
   yield undefined;
   is(notificationCount, 2, "after second load");
-  is("x" in iframe.contentWindow, false, "didn't reuse window");
+  is("x" in testWin, false, "didn't reuse window");
 
-  // Open a new window using window.open
-  popup = window.open("bug608669.xul", "bug 608669",
-                      "chrome,width=600,height=600");
-  popup.onload = nextTest;
-  yield undefined;
-  is(notificationCount, 3, "after window.open load");
-  popup.close();
+  testWin.close();
 
-  setCachePref(false);
   os.removeObserver(observer, "chrome-document-global-created");
   os.removeObserver(observer, "content-document-global-created");
   SimpleTest.finish();
 }
 
-
-
   ]]></script>
-  <vbox id="container" flex="1">
-    <description>Below will an iframe be added</description>
-  </vbox>
 </window>
--- a/dom/indexedDB/test/bfcache_page1.html
+++ b/dom/indexedDB/test/bfcache_page1.html
@@ -1,27 +1,27 @@
 <!DOCTYPE html>
 <html>
 <head>
   <script>
-  var request = indexedDB.open(parent.location, 1);
+  var request = indexedDB.open(opener.location, 1);
   request.onupgradeneeded = function(e) {
     var db = e.target.result;
     // This should never be called
     db.onversionchange = function(e) {
       db.transaction(["mystore"]).objectStore("mystore").put({ hello: "fail" }, 42);
     }
     var trans = e.target.transaction;
     if (db.objectStoreNames.contains("mystore")) {
       db.deleteObjectStore("mystore");
     }
     var store = db.createObjectStore("mystore");
     store.add({ hello: "world" }, 42);
     trans.oncomplete = function() {
-      parent.postMessage("go", "http://mochi.test:8888");
+      opener.postMessage("go", "http://mochi.test:8888");
     }
   };
   </script>
 </head>
 <body>
   This is page one.
 </body>
 </html>
--- a/dom/indexedDB/test/bfcache_page2.html
+++ b/dom/indexedDB/test/bfcache_page2.html
@@ -1,28 +1,28 @@
 <!DOCTYPE html>
 <html>
 <head>
   <script>
   var res = {};
-  var request = indexedDB.open(parent.location, 2);
+  var request = indexedDB.open(opener.location, 2);
   request.onblocked = function() {
     res.blockedFired = true;
   }
   request.onupgradeneeded  = function(e) {
     var db = e.target.result;
     res.version = db.version;
     res.storeCount = db.objectStoreNames.length;
 
     var trans = request.transaction;
     trans.objectStore("mystore").get(42).onsuccess = function(e) {
       res.value = JSON.stringify(e.target.result);
     }
     trans.oncomplete = function() {
-      parent.postMessage(JSON.stringify(res), "http://mochi.test:8888");
+      opener.postMessage(JSON.stringify(res), "http://mochi.test:8888");
     }
   };
 
   </script>
 </head>
 <body>
   This is page two.
 </body>
--- a/dom/indexedDB/test/test_bfcache.html
+++ b/dom/indexedDB/test/test_bfcache.html
@@ -5,63 +5,37 @@
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript">
     /* import-globals-from helpers.js */
-    var gOrigMaxTotalViewers = undefined;
-    function setCachePref(enabled) {
-      if (enabled) {
-        is(typeof gOrigMaxTotalViewers, "undefined",
-           "don't double-enable bfcache");
-        SpecialPowers.setBoolPref("browser.sessionhistory.cache_subframes",
-                                  true);
-        gOrigMaxTotalViewers =
-          SpecialPowers.getIntPref("browser.sessionhistory.max_total_viewers");
-        SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
-                                 10);
-      }
-      else {
-        is(typeof gOrigMaxTotalViewers, "number",
-           "don't double-disable bfcache");
-        SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
-                                 gOrigMaxTotalViewers);
-        gOrigMaxTotalViewers = undefined;
-        try {
-          SpecialPowers.clearUserPref("browser.sessionhistory.cache_subframes");
-        } catch (e) { /* Pref didn't exist, meh */ }
-      }
-    }
 
     function* testSteps()
     {
-      var iframe = $("iframe");
-      setCachePref(true);
       window.onmessage = grabEventAndContinueHandler;
 
-      iframe.src = "bfcache_iframe1.html";
+      let testWin = window.open("bfcache_page1.html", "testWin");
       var event = yield undefined;
       is(event.data, "go", "set up database successfully");
 
-      iframe.src = "bfcache_iframe2.html";
+      testWin.location = "bfcache_page2.html";
       let res = JSON.parse((yield).data);
       is(res.version, 2, "version was set correctly");
       is(res.storeCount, 1, "correct set of stores");
       ok(!("blockedFired" in res), "blocked shouldn't fire");
       is(res.value, JSON.stringify({ hello: "world" }),
          "correct value found in store");
 
-      setCachePref(false);
+      testWin.close();
       finishTest();
     }
   </script>
   <script type="text/javascript" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();">
-  <iframe id="iframe"></iframe>
 </body>
 
 </html>
--- a/dom/media/webspeech/synth/test/file_bfcache_page1.html
+++ b/dom/media/webspeech/synth/test/file_bfcache_page1.html
@@ -2,17 +2,17 @@
 <html>
 <head>
   <meta charset="utf-8">
   <script type="application/javascript">
     addEventListener('pageshow', function onshow(evt) {
       var u = new SpeechSynthesisUtterance('hello');
       u.lang = 'it-IT-noend';
       u.addEventListener('start', function() {
-        location = "file_bfcache_frame2.html";
+        location = "file_bfcache_page2.html";
       });
       speechSynthesis.speak(u);
     });
   </script>
 </head>
 <body>
 </body>
 </html>
--- a/dom/media/webspeech/synth/test/file_bfcache_page2.html
+++ b/dom/media/webspeech/synth/test/file_bfcache_page2.html
@@ -1,14 +1,14 @@
 <html>
 <script>
 var frameUnloaded = function() {
   var u = new SpeechSynthesisUtterance('hi');
   u.addEventListener('end', function () {
-    parent.ok(true, 'Successfully spoke utterance from new frame.');
-    parent.onDone();
+    opener.ok(true, 'Successfully spoke utterance from new frame.');
+    opener.onDone();
   });
   speechSynthesis.speak(u);
 };
 </script>
 
 <body onpageshow="frameUnloaded()"></body></html>
 
--- a/dom/media/webspeech/synth/test/test_bfcache.html
+++ b/dom/media/webspeech/synth/test/test_bfcache.html
@@ -8,38 +8,39 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for Bug 1230533: Test speech is stopped from a window when unloaded</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1230533">Mozilla Bug 1230533</a>
 <p id="display"></p>
-<iframe id="testFrame"></iframe>
 <div id="content" style="display: none">
-  
+
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 525444 **/
 
 SimpleTest.waitForExplicitFinish();
-
-var iframe;
+let testWin;
 
 function onDone() {
+  testWin.close();
   SimpleTest.finish();
 }
 
 SpecialPowers.pushPrefEnv({ set: [
   ['media.webspeech.synth.enabled', true],
-  ['media.webspeech.synth.force_global_queue', true],
-  ['browser.sessionhistory.cache_subframes', true],
-  ['browser.sessionhistory.max_total_viewers', 10]] },
+  ['media.webspeech.synth.force_global_queue', true]] },
   function() {
-    loadSpeechTest("file_bfcache_frame.html");
+    testWin = window.open("about:blank", "testWin");
+    testWin.onload = function(e) {
+      waitForVoices(testWin)
+        .then(() => testWin.location = "file_bfcache_page1.html")
+    };
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/workers/test/WorkerDebugger_frozen_window1.html
+++ b/dom/workers/test/WorkerDebugger_frozen_window1.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="utf-8">
     <script>
       var worker = new Worker("WorkerDebugger_frozen_worker1.js");
       worker.onmessage = function () {
-        parent.postMessage("ready", "*");
+        opener.postMessage("ready", "*");
       };
     </script>
   </head>
   <body>
     This is page 1.
   </body>
 <html>
--- a/dom/workers/test/WorkerDebugger_frozen_window2.html
+++ b/dom/workers/test/WorkerDebugger_frozen_window2.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="utf-8">
     <script>
       var worker = new Worker("WorkerDebugger_frozen_worker2.js");
       worker.onmessage = function () {
-        parent.postMessage("ready", "*");
+        opener.postMessage("ready", "*");
       };
     </script>
   </head>
   <body>
     This is page 2.
   </body>
 <html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/blank.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Blank</title>
+  </head>
+  <body onload="notifyOnload();">
+    <script type="application/javascript">
+    function notifyOnload() {
+      opener.postMessage({event: 'load'}, '*');
+    }
+    </script>
+  </body>
+</html>
+
--- a/dom/workers/test/mochitest.ini
+++ b/dom/workers/test/mochitest.ini
@@ -1,12 +1,13 @@
 [DEFAULT]
 support-files =
   WorkerTest_badworker.js
   atob_worker.js
+  blank.html
   bug978260_worker.js
   bug1014466_data1.txt
   bug1014466_data2.txt
   bug1014466_worker.js
   bug1020226_worker.js
   bug1020226_frame.html
   bug998474_worker.js
   bug1063538_worker.js
--- a/dom/workers/test/multi_sharedWorker_frame.html
+++ b/dom/workers/test/multi_sharedWorker_frame.html
@@ -2,25 +2,41 @@
   Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <!DOCTYPE HTML>
 <html>
   <head>
     <title>Test for SharedWorker</title>
   </head>
-  <body>
+  <body onload="notifyOpenerLoadEvent();">
     <script type="text/javascript">
       "use strict";
 
+      function postMessageToParentOrOpener(message) {
+        if (parent != window) {
+          parent.postMessage(message, "*");
+        }
+        if (opener) {
+          opener.postMessage(message, "*");
+        }
+      }
+
+      // Used by test_multi_sharedWorker_lifetimes.html
+      function notifyOpenerLoadEvent() {
+        if (opener) {
+          opener.postMessage({event: "load"}, "*");
+        }
+      }
+
       function debug(message) {
         if (typeof(message) != "string") {
           throw new Error("debug() only accepts strings!");
         }
-        parent.postMessage(message, "*");
+        postMessageToParentOrOpener(message);
       }
 
       let worker;
 
       window.addEventListener("message", function(event) {
         if (!worker) {
           worker = new SharedWorker("multi_sharedWorker_sharedWorker.js",
                                     "FrameWorker");
@@ -30,22 +46,22 @@
 
             let data = {
               type: "error",
               message: event.message,
               filename: event.filename,
               lineno: event.lineno,
               isErrorEvent: event instanceof ErrorEvent
             };
-            parent.postMessage(data, "*");
+            postMessageToParentOrOpener(data);
           };
 
           worker.port.onmessage = function(event) {
             debug("Worker message: " + JSON.stringify(event.data));
-            parent.postMessage(event.data, "*");
+            postMessageToParentOrOpener(event.data);
           };
         }
 
         debug("Posting message: " + JSON.stringify(event.data));
         worker.port.postMessage(event.data);
       });
     </script>
   </body>
--- a/dom/workers/test/test_WorkerDebugger_frozen.xul
+++ b/dom/workers/test/test_WorkerDebugger_frozen.xul
@@ -11,80 +11,69 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
   <script type="application/javascript" src="dom_worker_helper.js"/>
 
   <script type="application/javascript">
   <![CDATA[
 
-    const CACHE_SUBFRAMES = "browser.sessionhistory.cache_subframes";
-    const MAX_TOTAL_VIEWERS = "browser.sessionhistory.max_total_viewers";
-
-    const IFRAME1_URL = "WorkerDebugger_frozen_iframe1.html";
-    const IFRAME2_URL = "WorkerDebugger_frozen_iframe2.html";
+    const WINDOW1_URL = "WorkerDebugger_frozen_window1.html";
+    const WINDOW2_URL = "WorkerDebugger_frozen_window2.html";
 
     const WORKER1_URL = "WorkerDebugger_frozen_worker1.js";
     const WORKER2_URL = "WorkerDebugger_frozen_worker2.js";
 
     function test() {
       (async function() {
         SimpleTest.waitForExplicitFinish();
 
-        var oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
-
-        SpecialPowers.setBoolPref(CACHE_SUBFRAMES, true);
-        SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, 10);
-
-        let iframe = $("iframe");
+        SpecialPowers.pushPrefEnv({set:
+          [["browser.sessionhistory.max_total_viewers", 10]]});
 
         let promise = waitForMultiple([
           waitForRegister(WORKER1_URL),
           waitForWindowMessage(window, "ready"),
         ]);
-        iframe.src = IFRAME1_URL;
+        let testWin = window.open(WINDOW1_URL, "testWin");;
         let [dbg1] = await promise;
         is(dbg1.isClosed, false,
            "debugger for worker on page 1 should not be closed");
 
         promise = waitForMultiple([
           waitForUnregister(WORKER1_URL),
           waitForDebuggerClose(dbg1),
           waitForRegister(WORKER2_URL),
           waitForWindowMessage(window, "ready"),
         ]);
-        iframe.src = IFRAME2_URL;
+        testWin.location = WINDOW2_URL;
         let [,, dbg2] = await promise;
         is(dbg1.isClosed, true,
            "debugger for worker on page 1 should be closed");
         is(dbg2.isClosed, false,
            "debugger for worker on page 2 should not be closed");
 
         promise = Promise.all([
           waitForUnregister(WORKER2_URL),
           waitForDebuggerClose(dbg2),
           waitForRegister(WORKER1_URL)
         ]);
-        iframe.contentWindow.history.back();
+        testWin.history.back();
         [,, dbg1] = await promise;
         is(dbg1.isClosed, false,
            "debugger for worker on page 1 should not be closed");
         is(dbg2.isClosed, true,
            "debugger for worker on page 2 should be closed");
 
-        SpecialPowers.clearUserPref(CACHE_SUBFRAMES);
-        SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, oldMaxTotalViewers);
-
         SimpleTest.finish();
       })();
     }
 
   ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display"></p>
     <div id="content" style="display:none;"></div>
     <pre id="test"></pre>
-    <iframe id="iframe"></iframe>
   </body>
   <label id="test-result"/>
 </window>
--- a/dom/workers/test/test_multi_sharedWorker_lifetimes.html
+++ b/dom/workers/test/test_multi_sharedWorker_lifetimes.html
@@ -7,149 +7,132 @@
   <head>
     <title>Test for SharedWorker</title>
     <script src="/tests/SimpleTest/SimpleTest.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
       <script class="testbody" type="text/javascript">
         "use strict";
 
         const scrollbarPref = "layout.testing.overlay-scrollbars.always-visible";
-        const bfCacheEnabledPref = "browser.sessionhistory.cache_subframes";
-        const bfCacheDepthPref = "browser.sessionhistory.max_total_viewers";
-        const bfCacheDepth = 10;
 
-        const frameRelativeURL = "multi_sharedWorker_frame.html";
+        const windowRelativeURL = "multi_sharedWorker_frame.html";
         const storedData = "0123456789abcdefghijklmnopqrstuvwxyz";
 
         let testGenerator = (function*() {
           SimpleTest.waitForExplicitFinish();
 
-	  // Force scrollbar to always be shown.  The scrollbar setting is
-	  // necessary to avoid the fade-in/fade-out from evicting our document
-	  // from the BF cache below.  If bug 1049277 is fixed, then we can
-	  // stop setting the scrollbar pref here.
+          // Force scrollbar to always be shown.  The scrollbar setting is
+          // necessary to avoid the fade-in/fade-out from evicting our document
+          // from the BF cache below.  If bug 1049277 is fixed, then we can
+          // stop setting the scrollbar pref here.
           SpecialPowers.pushPrefEnv({ set: [[scrollbarPref, true]] },
                                     sendToGenerator);
           yield undefined;
 
           window.addEventListener("message", function(event) {
             if (typeof(event.data) == "string") {
               info(event.data);
             } else {
               sendToGenerator(event);
             }
           });
 
-          let frame = document.getElementById("frame");
-          frame.src = frameRelativeURL;
-          frame.onload = sendToGenerator;
-
+          let testWin = window.open(windowRelativeURL, "testWin");
           yield undefined;
 
-          frame = frame.contentWindow;
-          frame.postMessage({ command: "retrieve" }, "*");
+          testWin.postMessage({ command: "retrieve" }, "*");
 
           let event = yield undefined;
           ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
+          is(event.source, testWin, "Correct window got the event");
           is(event.data.type, "result", "Got a result message");
           is(event.data.data, undefined, "No data stored yet");
 
-          frame.postMessage({ command: "store", data: storedData }, "*");
-          frame.postMessage({ command: "retrieve" }, "*");
+          testWin.postMessage({ command: "store", data: storedData }, "*");
+          testWin.postMessage({ command: "retrieve" }, "*");
 
           event = yield undefined;
           ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
+          is(event.source, testWin, "Correct window got the event");
           is(event.data.type, "result", "Got a result message");
           is(event.data.data, storedData, "Got stored data");
 
           // Navigate when the bfcache is disabled.
-          info("Navigating to about:blank");
-          frame = document.getElementById("frame");
-          frame.onload = sendToGenerator;
-          frame.src = "about:blank";
-          frame.contentWindow.document.body.offsetTop;
+          info("Navigating to a blank page");
+          testWin.onunload = function(){};;
+          testWin.location = "blank.html";
+          testWin.document.body.offsetTop;
 
           yield undefined;
 
-          info("Navigating to " + frameRelativeURL);
-          frame.src = frameRelativeURL;
-          frame.contentWindow.document.body.offsetTop;
+          info("Navigating to " + windowRelativeURL);
+          testWin.onunload = function(){};
+          testWin.location = windowRelativeURL;
+          testWin.document.body.offsetTop;
 
           yield undefined;
 
-          frame = frame.contentWindow;
-          frame.postMessage({ command: "retrieve" }, "*");
+          testWin.postMessage({ command: "retrieve" }, "*");
 
           event = yield undefined;
           ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
+          is(event.source, testWin, "Correct window got the event");
           is(event.data.type, "result", "Got a result message");
           is(event.data.data, undefined, "No data stored");
 
-          frame.postMessage({ command: "store", data: storedData }, "*");
-          frame.postMessage({ command: "retrieve" }, "*");
+          testWin.postMessage({ command: "store", data: storedData }, "*");
+          testWin.postMessage({ command: "retrieve" }, "*");
 
           event = yield undefined;
           ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
+          is(event.source, testWin, "Correct window got the event");
           is(event.data.type, "result", "Got a result message");
           is(event.data.data, storedData, "Got stored data");
 
-          info("Enabling '" + bfCacheEnabledPref + "' pref");
-          SpecialPowers.pushPrefEnv({ set: [[bfCacheEnabledPref, true],
-                                            [bfCacheDepthPref, bfCacheDepth]] },
-                                    sendToGenerator);
-          yield undefined;
-
           // Navigate when the bfcache is enabled.
-          frame = document.getElementById("frame");
-          frame.onload = sendToGenerator;
-
-          info("Navigating to about:blank");
-          frame.src = "about:blank";
-          frame.contentWindow.document.body.offsetTop;
+          info("Navigating to a blank page");
+          testWin.location = "blank.html";
+          testWin.document.body.offsetTop;
 
           yield undefined;
 
           for (let i = 0; i < 3; i++) {
             info("Running GC");
             SpecialPowers.exactGC(sendToGenerator);
             yield undefined;
 
+            // It seems using SpecialPowers.executeSoon() would make the
+            // entryGlobal being the TabChildGlobal (and that would make the
+            // baseURI in the location assignment below being incorrect);
+            // setTimeout on the otherhand ensures the entryGlobal is this
+            // window.
             info("Waiting the event queue to clear");
-            SpecialPowers.executeSoon(sendToGenerator);
+            setTimeout(sendToGenerator, 0);
             yield undefined;
           }
 
-          info("Navigating to " + frameRelativeURL);
-          frame.src = frameRelativeURL;
-          frame.contentWindow.document.body.offsetTop;
+          info("Navigating to " + windowRelativeURL);
+          testWin.location = windowRelativeURL;
+          testWin.document.body.offsetTop;
 
           yield undefined;
 
-          frame = frame.contentWindow;
-          frame.postMessage({ command: "retrieve" }, "*");
+          testWin.postMessage({ command: "retrieve" }, "*");
 
           event = yield undefined;
           ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
+          is(event.source, testWin, "Correct window got the event");
           is(event.data.type, "result", "Got a result message");
           is(event.data.data, storedData, "Still have data stored");
 
-          info("Resetting '" + bfCacheEnabledPref + "' pref");
-          SpecialPowers.popPrefEnv(sendToGenerator);
-          yield undefined;
-
           window.removeEventListener("message", sendToGenerator);
 
+          testWin.close();
           SimpleTest.finish();
         })();
 
         let sendToGenerator = testGenerator.next.bind(testGenerator);
 
       </script>
   </head>
   <body onload="testGenerator.next();">
-    <iframe id="frame"></iframe>
   </body>
 </html>
--- a/dom/workers/test/test_onLine.html
+++ b/dom/workers/test/test_onLine.html
@@ -21,17 +21,26 @@ http://creativecommons.org/licenses/publ
 
 <script class="testbody" type="text/javascript">
 
 addLoadEvent(function() {
   var w = new Worker("onLine_worker.js");
 
   w.onmessage = function(e) {
     if (e.data.type === 'ready') {
-      doTest();
+      // XXX Important trick here.
+      //
+      // Setting iosvc.offline would trigger a sync notifyObservers call, and if
+      // there exists a preloaded about:newtab (see tabbrowser._handleNewTab),
+      // that tab will be notified.
+      //
+      // This implies a sync call across different tabGroups, and will hit the
+      // assertion in SchedulerGroup::ValidateAccess(). So use executeSoon to
+      // re-dispatch an unlabeled runnable to the event queue.
+      SpecialPowers.executeSoon(doTest);
     } else if (e.data.type === 'ok') {
       ok(e.data.test, e.data.message);
     } else if (e.data.type === 'finished') {
       SimpleTest.finish();
     }
   }
 
   function doTest() {
--- a/dom/workers/test/test_suspend.html
+++ b/dom/workers/test/test_suspend.html
@@ -9,130 +9,126 @@
   <title>Test for DOM Worker Threads</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content" style="display: none"></div>
 <pre id="test">
-<iframe id="workerFrame" src="suspend_iframe.html" onload="subframeLoaded();">
-</iframe>
 <script class="testbody" type="text/javascript">
 
   SimpleTest.waitForExplicitFinish();
 
-  var iframe;
+  const BLANK_URI = location.href.replace("test_suspend.html", "blank.html");
+
   var lastCount;
 
   var suspended = false;
   var resumed = false;
   var finished = false;
 
   var interval;
   var oldMessageCount;
   var waitCount = 0;
 
+  var testWin = window.open("suspend_window.html", "testWin");
+  testWin.onload = testWinLoaded;
+
+  window.addEventListener("message", msg => {
+    if (suspended) {
+      badOnloadCallback();
+    } else {
+      suspendCallback();
+    }
+  })
+
   function finishTest() {
     if (finished) {
       return;
     }
     finished = true;
-    SpecialPowers.flushPrefEnv(function () {
-      iframe.terminateWorker();
-      SimpleTest.finish();
-    });
+    testWin.terminateWorker();
+    testWin.close();
+    SimpleTest.finish();
   }
 
   function waitInterval() {
     if (finished) {
       return;
     }
-    is(String(iframe.location), "about:blank", "Wrong url!");
+    is(testWin.location.href, BLANK_URI, "Wrong url!");
     is(suspended, true, "Not suspended?");
     is(resumed, false, "Already resumed?!");
     is(lastCount, oldMessageCount, "Received a message while suspended!");
     if (++waitCount == 5) {
       clearInterval(interval);
       resumed = true;
-      iframe.history.back();
+      testWin.history.back();
     }
   }
 
   function badOnloadCallback() {
     if (finished) {
       return;
     }
-    ok(false, "We don't want suspend_iframe.html to fire a new load event, we want it to come out of the bfcache!");
+    ok(false, "We don't want suspend_window.html to fire a new load event, we want it to come out of the bfcache!");
     finishTest();
   }
 
   function suspendCallback() {
     if (finished) {
       return;
     }
-    is(String(iframe.location), "about:blank", "Wrong url!");
+    is(testWin.location.href, BLANK_URI, "Wrong url!");
     is(suspended, false, "Already suspended?");
     is(resumed, false, "Already resumed?");
-    SpecialPowers.popPrefEnv(function () {
-      suspended = true;
-      var iframeElement = document.getElementById("workerFrame");
-      iframeElement.onload = badOnloadCallback;
-      oldMessageCount = lastCount;
-      interval = setInterval(waitInterval, 1000);
-    });
+    suspended = true;
+    oldMessageCount = lastCount;
+    interval = setInterval(waitInterval, 1000);
   }
 
   function messageCallback(data) {
     if (finished) {
       return;
     }
 
     if (!suspended) {
       ok(lastCount === undefined || lastCount == data - 1,
          "Got good data, lastCount = " + lastCount + ", data = " + data);
       lastCount = data;
       if (lastCount == 25) {
-        SpecialPowers.pushPrefEnv({"set": [["browser.sessionhistory.cache_subframes", true]]}, function () {
-          iframe.location = "about:blank";
-          // We want suspend_iframe.html to go into bfcache, so we need to flush
-          // out all pending notifications. Otherwise, if they're flushed too
-          // late, they could kick us out of the bfcache again.
-          iframe.document.body.offsetTop;
-        });
+        testWin.location = "blank.html";
+        // We want suspend_window.html to go into bfcache, so we need to flush
+        // out all pending notifications. Otherwise, if they're flushed too
+        // late, they could kick us out of the bfcache again.
+        testWin.document.body.offsetTop;
       }
       return;
     }
 
-    var newLocation =
-      window.location.toString().replace("test_suspend.html",
-                                         "suspend_iframe.html");
-    is(newLocation.indexOf(iframe.location.toString()), 0, "Wrong url!");
+    var newLocation = location.href.replace("test_suspend.html",
+                                            "suspend_window.html");
+    is(testWin.location.href, newLocation, "Wrong url!");
     is(resumed, true, "Got message before resumed!");
     is(lastCount, data - 1, "Missed a message, suspend failed!");
     finishTest();
   }
 
   function errorCallback(data) {
     if (finished) {
       return;
     }
-    ok(false, "Iframe had an error: '" + data + "'");
+    ok(false, "testWin had an error: '" + data + "'");
     finishTest();
   }
 
-  function subframeLoaded() {
+  function testWinLoaded() {
     if (finished) {
       return;
     }
-    var iframeElement = document.getElementById("workerFrame");
-    iframeElement.onload = suspendCallback;
-
-    iframe = iframeElement.contentWindow;
-    ok(iframe, "No iframe?!");
-
-    iframe.startWorker(messageCallback, errorCallback);
+    testWin.startWorker(messageCallback, errorCallback);
   }
 
 </script>
 </pre>
 </body>
 </html>