Bug 1153407 - browser_toolbox_options_enable_serviceworkers_testing.js breaks other tests, needs to be e10s. r=ochameau
authorJose Antonio Olivera Ortega <jaoo@jaoo.es>
Wed, 03 Jun 2015 08:07:26 +0200
changeset 269626 51a031e1159572b52f36c868a2da4e358a71f521
parent 269625 d597146748b9a448298854a4249858a030970707
child 269627 4017f25a873397e2a8b4835eda4c7d93b8694004
push id2540
push userwcosta@mozilla.com
push dateWed, 03 Jun 2015 20:55:41 +0000
reviewersochameau
bugs1153407
milestone41.0a1
Bug 1153407 - browser_toolbox_options_enable_serviceworkers_testing.js breaks other tests, needs to be e10s. r=ochameau
browser/devtools/framework/test/browser.ini
browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing.html
browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing.js
browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing_frame_script.js
browser/devtools/framework/test/head.js
--- a/browser/devtools/framework/test/browser.ini
+++ b/browser/devtools/framework/test/browser.ini
@@ -7,16 +7,17 @@ support-files =
   browser_toolbox_options_disable_cache.sjs
   browser_toolbox_sidebar_tool.xul
   code_math.js
   head.js
   shared-head.js
   helper_disable_cache.js
   doc_theme.css
   doc_viewsource.html
+  browser_toolbox_options_enable_serviceworkers_testing_frame_script.js
   browser_toolbox_options_enable_serviceworkers_testing.html
   serviceworker.js
 
 [browser_devtools_api.js]
 [browser_devtools_api_destroy.js]
 [browser_dynamic_tool_enabling.js]
 [browser_ignore_toolbox_network_requests.js]
 [browser_keybindings_01.js]
@@ -61,14 +62,13 @@ skip-if = e10s # Bug 1069044 - destroyIn
 [browser_toolbox_window_reload_target.js]
 [browser_toolbox_window_shortcuts.js]
 skip-if = os == "mac" && os_version == "10.8" || os == "win" && os_version == "5.1" # Bug 851129 - Re-enable browser_toolbox_window_shortcuts.js test after leaks are fixed
 [browser_toolbox_window_title_changes.js]
 [browser_toolbox_zoom.js]
 [browser_toolbox_custom_host.js]
 [browser_toolbox_theme_registration.js]
 [browser_toolbox_options_enable_serviceworkers_testing.js]
-skip-if = true # Bug 1153407 - this test breaks subsequent tests and is not e10s compatible
 [browser_toolbox_selected_tool_unavailable.js]
 
 # We want this test to run for mochitest-dt as well, so we include it here:
 [../../../base/content/test/general/browser_parsable_css.js]
 
--- a/browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing.html
+++ b/browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing.html
@@ -1,58 +1,10 @@
 <!DOCTYPE html>
 <html>
   <head>
     <title>browser_toolbox_options_enable_serviceworkers_testing.html</title>
     <meta charset="UTF-8">
-    <style>
-      div {
-        width: 260px;
-        height: 24px;
-        border: 1px solid #000;
-        margin-top: 10px;
-      }
-
-      h1 {
-        font-size: 20px
-      }
-    </style>
-    <script type="application/javascript;version=1.8">
-      function log(msg) {
-        var output = document.getElementById("output");
-
-        output.innerHTML = msg;
-      }
-
-      navigator.serviceWorker.register("serviceworker.js").then(
-        swr => {
-          var msg = "";
-          var button = document.getElementById("button");
-          if (swr.installing) {
-            msg += "Installing worker/";
-          }
-          if (swr.waiting) {
-            msg += "Waiting worker/";
-          }
-          if (swr.active) {
-            msg += "Active worker/";
-          }
-          log(msg);
-          button.click();
-        },
-        error => {
-          var button = document.getElementById("button");
-          if (error.name === "SecurityError") {
-            log("SecurityError");
-          }
-          button.click();
-      });
-    </script>
   </head>
   <body>
-    <h1>Test in page</h1>
-    <input id="button"
-           type="button"
-           value="Worker clicks here"/>
-    <br>
-    <div id="output">No output</div>
+    <h1>SW-test</h1>
   </body>
 </html>
--- a/browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing.js
+++ b/browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing.js
@@ -1,143 +1,122 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that enabling Service Workers testing option enables the
 // mServiceWorkersTestingEnabled attribute added to nsPIDOMWindow.
 
+const COMMON_FRAME_SCRIPT_URL =
+  "chrome://browser/content/devtools/frame-script-utils.js";
+const ROOT_TEST_DIR =
+  getRootDirectory(gTestPath);
+const FRAME_SCRIPT_URL =
+  ROOT_TEST_DIR +
+  "browser_toolbox_options_enable_serviceworkers_testing_frame_script.js";
 const TEST_URI = URL_ROOT +
                  "browser_toolbox_options_enable_serviceworkers_testing.html";
 
 const ELEMENT_ID = "devtools-enable-serviceWorkersTesting";
 
 let toolbox;
-let doc;
 
 function test() {
   // Note: Pref dom.serviceWorkers.testing.enabled is false since we are testing
   // the same capabilities are enabled with the devtool pref.
   SpecialPowers.pushPrefEnv({"set": [
     ["dom.serviceWorkers.exemptFromPerDomainMax", true],
     ["dom.serviceWorkers.enabled", true],
     ["dom.serviceWorkers.testing.enabled", false]
-  ]}, start);
+  ]}, init);
 }
 
-function start() {
-  gBrowser.selectedTab = gBrowser.addTab();
+function init() {
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
   let target = TargetFactory.forTab(gBrowser.selectedTab);
+  let linkedBrowser = tab.linkedBrowser;
+
+  linkedBrowser.messageManager.loadFrameScript(COMMON_FRAME_SCRIPT_URL, false);
+  linkedBrowser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
 
   gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
     gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
-    doc = content.document;
     gDevTools.showToolbox(target).then(testSelectTool);
   }, true);
 
   content.location = TEST_URI;
 }
 
 function testSelectTool(aToolbox) {
   toolbox = aToolbox;
-  toolbox.once("options-selected", () => {
-    testRegisterFails().then(testRegisterInstallingWorker);
-  });
+  toolbox.once("options-selected", start);
   toolbox.selectTool("options");
 }
 
-function testRegisterFails() {
-  let deferred = promise.defer();
-
-  let output = doc.getElementById("output");
-  let button = doc.getElementById("button");
-
-  function doTheCheck() {
-    info("Testing it doesn't registers correctly until enable testing");
-    is(output.textContent,
-       "SecurityError",
-       "SecurityError expected");
-    deferred.resolve();
-  }
-
-  if (output.textContent !== "No output") {
-    doTheCheck();
-  }
-
-  button.addEventListener('click', function onClick() {
-    button.removeEventListener('click', onClick);
-    doTheCheck();
-  });
-
-  return deferred.promise;
+function register() {
+  return executeInContent("devtools:sw-test:register");
 }
 
-function testRegisterInstallingWorker() {
-  toggleServiceWorkersTestingCheckbox().then(() => {
-    let output = doc.getElementById("output");
-    let button = doc.getElementById("button");
-
-    function doTheCheck() {
-      info("Testing it registers correctly and there is an installing worker");
-      is(output.textContent,
-         "Installing worker/",
-         "Installing worker expected");
-      testRegisterFailsWhenToolboxCloses();
-    }
-
-    if (output.textContent !== "No output") {
-      doTheCheck();
-    }
-
-    button.addEventListener('click', function onClick() {
-      button.removeEventListener('click', onClick);
-      doTheCheck();
-    });
-  });
+function unregister(swr) {
+  return executeInContent("devtools:sw-test:unregister");
 }
 
-// Workers should be turned back off when we closes the toolbox
-function testRegisterFailsWhenToolboxCloses() {
-  info("Testing it disable worker when closing the toolbox");
-  toolbox.destroy()
-         .then(reload)
-         .then(testRegisterFails)
-         .then(finishUp);
-}
-
-function reload() {
-  let deferred = promise.defer();
-
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
-    doc = content.document;
-    deferred.resolve();
-  }, true);
-
-  let mm = getFrameScript();
-  mm.sendAsyncMessage("devtools:test:reload");
-
-  return deferred.promise;
+function testRegisterFails(data) {
+  is(data.success, false, "Register should fail with security error");
+  return promise.resolve();
 }
 
 function toggleServiceWorkersTestingCheckbox() {
-  let deferred = promise.defer();
-
   let panel = toolbox.getCurrentPanel();
   let cbx = panel.panelDoc.getElementById(ELEMENT_ID);
 
   cbx.scrollIntoView();
 
   if (cbx.checked) {
     info("Clearing checkbox to disable service workers testing");
   } else {
     info("Checking checkbox to enable service workers testing");
   }
 
   cbx.click();
 
-  return reload();
+  return promise.resolve();
+}
+
+function reload() {
+  let deferred = promise.defer();
+
+  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
+    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+    deferred.resolve();
+  }, true);
+
+  executeInContent("devtools:test:reload", {}, {}, false);
+  return deferred.promise;
+}
+
+function testRegisterSuccesses(data) {
+  is(data.success, true, "Register should success");
+  return promise.resolve();
+}
+
+function start() {
+  register()
+    .then(testRegisterFails)
+    .then(toggleServiceWorkersTestingCheckbox)
+    .then(reload)
+    .then(register)
+    .then(testRegisterSuccesses)
+    .then(unregister)
+    // Workers should be turned back off when we closes the toolbox
+    .then(toolbox.destroy.bind(toolbox))
+    .then(reload)
+    .then(register)
+    .then(testRegisterFails)
+    .catch(function(e) {
+      ok(false, "Some test failed with error " + e);
+    }).then(finishUp);
 }
 
 function finishUp() {
   gBrowser.removeCurrentTab();
-  toolbox = doc = null;
+  toolbox = null;
   finish();
 }
new file mode 100644
--- /dev/null
+++ b/browser/devtools/framework/test/browser_toolbox_options_enable_serviceworkers_testing_frame_script.js
@@ -0,0 +1,24 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// A helper frame-script for browser/devtools/framework service worker tests.
+
+"use strict";
+
+addMessageListener("devtools:sw-test:register", function(msg) {
+  content.navigator.serviceWorker.register("serviceworker.js")
+    .then(swr => {
+      sendAsyncMessage("devtools:sw-test:register", {success: true});
+    }, error => {
+      sendAsyncMessage("devtools:sw-test:register", {success: false});
+    });
+});
+
+addMessageListener("devtools:sw-test:unregister", function(msg) {
+  content.navigator.serviceWorker.getRegistration().then(swr => {
+    swr.unregister().then(result => {
+      sendAsyncMessage("devtools:sw-test:unregister",
+                       {success: result ? true : false});
+    });
+  });
+});
--- a/browser/devtools/framework/test/head.js
+++ b/browser/devtools/framework/test/head.js
@@ -60,8 +60,52 @@ function *openScratchpadWindow () {
   win.Scratchpad.addObserver({
     onReady: function () {
       win.Scratchpad.removeObserver(this);
       resolve(win);
     }
   });
   return p;
 }
+
+/**
+ * Wait for a content -> chrome message on the message manager (the window
+ * messagemanager is used).
+ * @param {String} name The message name
+ * @return {Promise} A promise that resolves to the response data when the
+ * message has been received
+ */
+function waitForContentMessage(name) {
+  info("Expecting message " + name + " from content");
+
+  let mm = gBrowser.selectedBrowser.messageManager;
+
+  let def = promise.defer();
+  mm.addMessageListener(name, function onMessage(msg) {
+    mm.removeMessageListener(name, onMessage);
+    def.resolve(msg.data);
+  });
+  return def.promise;
+}
+
+/**
+ * Send an async message to the frame script (chrome -> content) and wait for a
+ * response message with the same name (content -> chrome).
+ * @param {String} name The message name. Should be one of the messages defined
+ * in doc_frame_script.js
+ * @param {Object} data Optional data to send along
+ * @param {Object} objects Optional CPOW objects to send along
+ * @param {Boolean} expectResponse If set to false, don't wait for a response
+ * with the same name from the content script. Defaults to true.
+ * @return {Promise} Resolves to the response data if a response is expected,
+ * immediately resolves otherwise
+ */
+function executeInContent(name, data={}, objects={}, expectResponse=true) {
+  info("Sending message " + name + " to content");
+  let mm = gBrowser.selectedBrowser.messageManager;
+
+  mm.sendAsyncMessage(name, data, objects);
+  if (expectResponse) {
+    return waitForContentMessage(name);
+  } else {
+    return promise.resolve();
+  }
+}