Bug 1300822 - Fix tab load event wait in devtools test helpers. r=tromey, a=test-only
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 06 Sep 2016 07:05:32 -0700
changeset 348216 0437e13b60c39116f82158dfc77c3f72436100f2
parent 348215 7d67edce5ec0e4b137bee04c5931605f1eb70027
child 348217 93266904a199ad4d2cb4ee36d0fb15b00fdc61d8
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstromey, test-only
bugs1300822
milestone50.0a2
Bug 1300822 - Fix tab load event wait in devtools test helpers. r=tromey, a=test-only MozReview-Commit-ID: 8vSSaDloJND
devtools/client/aboutdebugging/test/head.js
devtools/client/canvasdebugger/test/head.js
devtools/client/debugger/test/mochitest/head.js
devtools/client/framework/test/browser_keybindings_01.js
devtools/client/framework/test/browser_toolbox_custom_host.js
devtools/client/framework/test/browser_toolbox_dynamic_registration.js
devtools/client/framework/test/browser_toolbox_options_disable_buttons.js
devtools/client/framework/test/browser_toolbox_options_disable_js.js
devtools/client/framework/test/browser_toolbox_options_enable_serviceworkers_testing.js
devtools/client/framework/test/browser_toolbox_raise.js
devtools/client/framework/test/browser_toolbox_ready.js
devtools/client/framework/test/browser_two_tabs.js
devtools/client/framework/test/helper_disable_cache.js
devtools/client/framework/test/shared-head.js
devtools/client/inspector/markup/test/browser_markup_links_05.js
devtools/client/inspector/markup/test/browser_markup_links_07.js
devtools/client/inspector/test/head.js
devtools/client/projecteditor/test/head.js
devtools/client/responsivedesign/test/head.js
devtools/client/shadereditor/test/head.js
devtools/client/sourceeditor/test/browser_codemirror.js
devtools/client/sourceeditor/test/browser_css_autocompletion.js
devtools/client/sourceeditor/test/browser_vimemacs.js
devtools/client/sourceeditor/test/head.js
devtools/client/styleeditor/test/head.js
devtools/client/webaudioeditor/test/head.js
devtools/client/webide/test/head.js
devtools/server/tests/browser/browser_canvasframe_helper_04.js
devtools/server/tests/browser/head.js
--- a/devtools/client/aboutdebugging/test/head.js
+++ b/devtools/client/aboutdebugging/test/head.js
@@ -78,21 +78,21 @@ function addTab(url, win, backgroundTab 
 
     targetWindow.focus();
     let tab = targetBrowser.addTab(url);
     if (!backgroundTab) {
       targetBrowser.selectedTab = tab;
     }
     let linkedBrowser = tab.linkedBrowser;
 
-    linkedBrowser.addEventListener("load", function onLoad() {
-      linkedBrowser.removeEventListener("load", onLoad, true);
-      info("Tab added and finished loading: " + url);
-      done(tab);
-    }, true);
+    BrowserTestUtils.browserLoaded(linkedBrowser)
+      .then(function () {
+        info("Tab added and finished loading: " + url);
+        done(tab);
+      });
   });
 }
 
 function removeTab(tab, win) {
   info("Removing tab.");
 
   return new Promise(done => {
     let targetWindow = win || window;
--- a/devtools/client/canvasdebugger/test/head.js
+++ b/devtools/client/canvasdebugger/test/head.js
@@ -75,21 +75,21 @@ function addTab(aUrl, aWindow) {
   let deferred = promise.defer();
   let targetWindow = aWindow || window;
   let targetBrowser = targetWindow.gBrowser;
 
   targetWindow.focus();
   let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
   let linkedBrowser = tab.linkedBrowser;
 
-  linkedBrowser.addEventListener("load", function onLoad() {
-    linkedBrowser.removeEventListener("load", onLoad, true);
-    info("Tab added and finished loading: " + aUrl);
-    deferred.resolve(tab);
-  }, true);
+  BrowserTestUtils.browserLoaded(linkedBrowser)
+    .then(function () {
+      info("Tab added and finished loading: " + aUrl);
+      deferred.resolve(tab);
+    });
 
   return deferred.promise;
 }
 
 function removeTab(aTab, aWindow) {
   info("Removing tab.");
 
   let deferred = promise.defer();
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -82,21 +82,21 @@ this.addTab = function addTab(aUrl, aWin
 
   targetWindow.focus();
   let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
   let linkedBrowser = tab.linkedBrowser;
 
   info("Loading frame script with url " + FRAME_SCRIPT_URL + ".");
   linkedBrowser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
 
-  linkedBrowser.addEventListener("load", function onLoad() {
-    linkedBrowser.removeEventListener("load", onLoad, true);
-    info("Tab added and finished loading: " + aUrl);
-    deferred.resolve(tab);
-  }, true);
+  BrowserTestUtils.browserLoaded(linkedBrowser)
+    .then(function () {
+      info("Tab added and finished loading: " + aUrl);
+      deferred.resolve(tab);
+    });
 
   return deferred.promise;
 };
 
 this.removeTab = function removeTab(aTab, aWindow) {
   info("Removing tab.");
 
   let deferred = promise.defer();
--- a/devtools/client/framework/test/browser_keybindings_01.js
+++ b/devtools/client/framework/test/browser_keybindings_01.js
@@ -1,36 +1,32 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the keybindings for opening and closing the inspector work as expected
 // Can probably make this a shared test that tests all of the tools global keybindings
-
+const TEST_URL = "data:text/html,<html><head><title>Test for the " +
+                 "highlighter keybindings</title></head><body>" +
+                 "<h1>Keybindings!</h1></body></html>"
 function test()
 {
   waitForExplicitFinish();
 
   let doc;
   let node;
   let inspector;
   let keysetMap = { };
 
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
+  addTab(TEST_URL).then(function () {
     doc = content.document;
     node = doc.querySelector("h1");
     waitForFocus(setupKeyBindingsTest);
-  }, true);
-
-  content.location = "data:text/html,<html><head><title>Test for the " +
-                     "highlighter keybindings</title></head><body>" +
-                     "<h1>Keybindings!</h1></body></html>";
+  });
 
   function buildDevtoolsKeysetMap(keyset) {
     [].forEach.call(keyset.querySelectorAll("key"), function (key) {
 
       if (!key.getAttribute("key")) {
         return;
       }
 
--- a/devtools/client/framework/test/browser_toolbox_custom_host.js
+++ b/devtools/client/framework/test/browser_toolbox_custom_host.js
@@ -1,35 +1,32 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const TEST_URL = "data:text/html,test custom host";
+
 function test() {
   let {Toolbox} = require("devtools/client/framework/toolbox");
 
-  let toolbox, iframe, target, tab;
-
-  gBrowser.selectedTab = gBrowser.addTab();
-  target = TargetFactory.forTab(gBrowser.selectedTab);
+  let toolbox, iframe, target;
 
   window.addEventListener("message", onMessage);
 
   iframe = document.createElement("iframe");
   document.documentElement.appendChild(iframe);
 
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+  addTab(TEST_URL).then(function (tab) {
+    target = TargetFactory.forTab(tab);
     let options = {customIframe: iframe};
     gDevTools.showToolbox(target, null, Toolbox.HostType.CUSTOM, options)
              .then(testCustomHost, console.error)
              .then(null, console.error);
-  }, true);
-
-  content.location = "data:text/html,test custom host";
+  });
 
   function onMessage(event) {
     info("onMessage: " + event.data);
     let json = JSON.parse(event.data);
     if (json.name == "toolbox-close") {
       ok("Got the `toolbox-close` message");
       window.removeEventListener("message", onMessage);
       cleanup();
@@ -45,13 +42,13 @@ function test() {
 
   function cleanup() {
     iframe.remove();
 
     // Even if we received "toolbox-close", the toolbox may still be destroying
     // toolbox.destroy() returns a singleton promise that ensures
     // everything is cleaned up before proceeding.
     toolbox.destroy().then(() => {
-      toolbox = iframe = target = tab = null;
+      toolbox = iframe = target = null;
       finish();
     });
   }
 }
--- a/devtools/client/framework/test/browser_toolbox_dynamic_registration.js
+++ b/devtools/client/framework/test/browser_toolbox_dynamic_registration.js
@@ -1,26 +1,23 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const TEST_URL = "data:text/html,test for dynamically registering and unregistering tools";
+
 var toolbox;
 
 function test()
 {
-  gBrowser.selectedTab = gBrowser.addTab();
-  let target = TargetFactory.forTab(gBrowser.selectedTab);
-
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+  addTab(TEST_URL).then(tab => {
+    let target = TargetFactory.forTab(tab);
     gDevTools.showToolbox(target).then(testRegister);
-  }, true);
-
-  content.location = "data:text/html,test for dynamically registering and unregistering tools";
+  });
 }
 
 function testRegister(aToolbox)
 {
   toolbox = aToolbox;
   gDevTools.once("tool-registered", toolRegistered);
 
   gDevTools.registerTool({
--- a/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js
@@ -1,33 +1,29 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /* import-globals-from shared-head.js */
 "use strict";
 
+const TEST_URL = "data:text/html;charset=utf8,test for dynamically " +
+                 "registering and unregistering tools";
 var doc = null, toolbox = null, panelWin = null, modifiedPrefs = [];
 
 function test() {
-  gBrowser.selectedTab = gBrowser.addTab();
-  let target = TargetFactory.forTab(gBrowser.selectedTab);
-
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+  addTab(TEST_URL).then(tab => {
+    let target = TargetFactory.forTab(tab);
     gDevTools.showToolbox(target)
       .then(testSelectTool)
       .then(testToggleToolboxButtons)
       .then(testPrefsAreRespectedWhenReopeningToolbox)
       .then(cleanup, errorHandler);
-  }, true);
-
-  content.location = "data:text/html;charset=utf8,test for dynamically " +
-                     "registering and unregistering tools";
+  });
 }
 
 function testPrefsAreRespectedWhenReopeningToolbox() {
   let deferred = defer();
   let target = TargetFactory.forTab(gBrowser.selectedTab);
 
   info("Closing toolbox to test after reopening");
   gDevTools.closeToolbox(target).then(() => {
--- a/devtools/client/framework/test/browser_toolbox_options_disable_js.js
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_js.js
@@ -3,25 +3,20 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that disabling JavaScript for a tab works as it should.
 
 const TEST_URI = URL_ROOT + "browser_toolbox_options_disable_js.html";
 
 function test() {
-  gBrowser.selectedTab = gBrowser.addTab();
-  let target = TargetFactory.forTab(gBrowser.selectedTab);
-
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+  addTab(TEST_URI).then(tab => {
+    let target = TargetFactory.forTab(tab);
     gDevTools.showToolbox(target).then(testSelectTool);
-  }, true);
-
-  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
+  });
 }
 
 function testSelectTool(toolbox) {
   toolbox.once("options-selected", () => testToggleJS(toolbox));
   toolbox.selectTool("options");
 }
 
 let testToggleJS = Task.async(function* (toolbox) {
--- a/devtools/client/framework/test/browser_toolbox_options_enable_serviceworkers_testing.js
+++ b/devtools/client/framework/test/browser_toolbox_options_enable_serviceworkers_testing.js
@@ -26,29 +26,25 @@ function test() {
   SpecialPowers.pushPrefEnv({"set": [
     ["dom.serviceWorkers.exemptFromPerDomainMax", true],
     ["dom.serviceWorkers.enabled", true],
     ["dom.serviceWorkers.testing.enabled", false]
   ]}, init);
 }
 
 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);
+  addTab(TEST_URI).then(tab => {
+    let target = TargetFactory.forTab(tab);
+    let linkedBrowser = tab.linkedBrowser;
 
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+    linkedBrowser.messageManager.loadFrameScript(COMMON_FRAME_SCRIPT_URL, false);
+    linkedBrowser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
+
     gDevTools.showToolbox(target).then(testSelectTool);
-  }, true);
-
-  content.location = TEST_URI;
+  });
 }
 
 function testSelectTool(aToolbox) {
   toolbox = aToolbox;
   toolbox.once("options-selected", start);
   toolbox.selectTool("options");
 }
 
--- a/devtools/client/framework/test/browser_toolbox_raise.js
+++ b/devtools/client/framework/test/browser_toolbox_raise.js
@@ -1,30 +1,27 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const TEST_URL = "data:text/html,test for opening toolbox in different hosts";
+
 var {Toolbox} = require("devtools/client/framework/toolbox");
 
-var toolbox, target, tab1, tab2;
+var toolbox, tab1, tab2;
 
 function test() {
-  gBrowser.selectedTab = tab1 = gBrowser.addTab();
-  tab2 = gBrowser.addTab();
-  target = TargetFactory.forTab(gBrowser.selectedTab);
-
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
-    gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
+  addTab(TEST_URL).then(tab => {
+    tab2 = gBrowser.addTab();
+    let target = TargetFactory.forTab(tab);
     gDevTools.showToolbox(target)
              .then(testBottomHost, console.error)
              .then(null, console.error);
-  }, true);
-
-  content.location = "data:text/html,test for opening toolbox in different hosts";
+  });
 }
 
 function testBottomHost(aToolbox) {
   toolbox = aToolbox;
 
   // switch to another tab and test toolbox.raise()
   gBrowser.selectedTab = tab2;
   executeSoon(function () {
@@ -68,14 +65,14 @@ function onFocus() {
   // Now raise toolbox.
   toolbox.raise();
 }
 
 function cleanup() {
   Services.prefs.setCharPref("devtools.toolbox.host", Toolbox.HostType.BOTTOM);
 
   toolbox.destroy().then(function () {
-    toolbox = target = null;
+    toolbox = null;
     gBrowser.removeCurrentTab();
     gBrowser.removeCurrentTab();
     finish();
   });
 }
--- a/devtools/client/framework/test/browser_toolbox_ready.js
+++ b/devtools/client/framework/test/browser_toolbox_ready.js
@@ -1,27 +1,21 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-function test() {
-  gBrowser.selectedTab = gBrowser.addTab();
-  let target = TargetFactory.forTab(gBrowser.selectedTab);
+const TEST_URL = "data:text/html,test for toolbox being ready";
 
-  const onLoad = Task.async(function* (evt) {
-    gBrowser.selectedBrowser.removeEventListener("load", onLoad);
-
-    const toolbox = yield gDevTools.showToolbox(target, "webconsole");
-    ok(toolbox.isReady, "toolbox isReady is set");
-    ok(toolbox.threadClient, "toolbox has a thread client");
+add_task(function* () {
+  let tab = yield addTab(TEST_URL);
+  let target = TargetFactory.forTab(tab);
 
-    const toolbox2 = yield gDevTools.showToolbox(toolbox.target, toolbox.toolId);
-    is(toolbox2, toolbox, "same toolbox");
+  const toolbox = yield gDevTools.showToolbox(target, "webconsole");
+  ok(toolbox.isReady, "toolbox isReady is set");
+  ok(toolbox.threadClient, "toolbox has a thread client");
 
-    yield toolbox.destroy();
-    gBrowser.removeCurrentTab();
-    finish();
-  });
+  const toolbox2 = yield gDevTools.showToolbox(toolbox.target, toolbox.toolId);
+  is(toolbox2, toolbox, "same toolbox");
 
-  gBrowser.selectedBrowser.addEventListener("load", onLoad, true);
-  content.location = "data:text/html,test for toolbox being ready";
-}
+  yield toolbox.destroy();
+  gBrowser.removeCurrentTab();
+});
--- a/devtools/client/framework/test/browser_two_tabs.js
+++ b/devtools/client/framework/test/browser_two_tabs.js
@@ -25,27 +25,24 @@ function test() {
     DebuggerServer.addBrowserActors();
   }
 
   openTabs();
 }
 
 function openTabs() {
   // Open two tabs, select the second
-  gTab1 = gBrowser.addTab(TAB_URL_1);
-  gTab1.linkedBrowser.addEventListener("load", function onLoad1(evt) {
-    gTab1.linkedBrowser.removeEventListener("load", onLoad1);
-
-    gTab2 = gBrowser.selectedTab = gBrowser.addTab(TAB_URL_2);
-    gTab2.linkedBrowser.addEventListener("load", function onLoad2(evt) {
-      gTab2.linkedBrowser.removeEventListener("load", onLoad2);
+  addTab(TAB_URL_1).then(tab1 => {
+    gTab1 = tab1;
+    addTab(TAB_URL_2).then(tab2 => {
+      gTab2 = tab2;
 
       connect();
-    }, true);
-  }, true);
+    });
+  });
 }
 
 function connect() {
   // Connect to debugger server to fetch the two tab actors
   gClient = new DebuggerClient(DebuggerServer.connectPipe());
   gClient.connect()
     .then(() => gClient.listTabs())
     .then(response => {
--- a/devtools/client/framework/test/helper_disable_cache.js
+++ b/devtools/client/framework/test/helper_disable_cache.js
@@ -86,22 +86,20 @@ function* setDisableCacheCheckboxChecked
     yield waitForTick();
   }
 }
 
 function reloadTab(tabX) {
   let def = defer();
   let browser = gBrowser.selectedBrowser;
 
-  // once() doesn't work here so we use a standard handler instead.
-  browser.addEventListener("load", function onLoad() {
-    browser.removeEventListener("load", onLoad, true);
+  BrowserTestUtils.browserLoaded(browser).then(function () {
     info("Reloaded tab " + tabX.title);
     def.resolve();
-  }, true);
+  });
 
   info("Reloading tab " + tabX.title);
   let mm = getFrameScript();
   mm.sendAsyncMessage("devtools:test:reload");
 
   return def.promise;
 }
 
--- a/devtools/client/framework/test/shared-head.js
+++ b/devtools/client/framework/test/shared-head.js
@@ -107,17 +107,17 @@ registerCleanupFunction(function* cleanu
  * Add a new test tab in the browser and load the given url.
  * @param {String} url The url to be loaded in the new tab
  * @return a promise that resolves to the tab object when the url is loaded
  */
 var addTab = Task.async(function* (url) {
   info("Adding a new tab with URL: " + url);
 
   let tab = gBrowser.selectedTab = gBrowser.addTab(url);
-  yield once(gBrowser.selectedBrowser, "load", true);
+  yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   info("Tab added and finished loading");
 
   return tab;
 });
 
 /**
  * Remove the given tab.
@@ -136,17 +136,17 @@ var removeTab = Task.async(function* (ta
 
 /**
  * Refresh the given tab.
  * @param {Object} tab The tab to be refreshed.
  * @return Promise<undefined> resolved when the tab is successfully refreshed.
  */
 var refreshTab = Task.async(function*(tab) {
   info("Refreshing tab.");
-  const finished = once(gBrowser.selectedBrowser, "load", true);
+  const finished = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   gBrowser.reloadTab(gBrowser.selectedTab);
   yield finished;
   info("Tab finished refreshing.");
 });
 
 /**
  * Simulate a key event from a <key> element.
  * @param {DOMNode} key
--- a/devtools/client/inspector/markup/test/browser_markup_links_05.js
+++ b/devtools/client/inspector/markup/test/browser_markup_links_05.js
@@ -20,17 +20,17 @@ add_task(function* () {
   openContextMenuAndGetAllItems(inspector, {
     target: editor.attrElements.get("poster").querySelector(".link"),
   });
 
   info("Follow the link and wait for the new tab to open");
   let onTabOpened = once(gBrowser.tabContainer, "TabOpen");
   inspector.onFollowLink();
   let {target: tab} = yield onTabOpened;
-  yield waitForTabLoad(tab);
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   ok(true, "A new tab opened");
   is(tab.linkedBrowser.currentURI.spec, URL_ROOT + "doc_markup_tooltip.png",
     "The URL for the new tab is correct");
   gBrowser.removeTab(tab);
 
   info("Select a node with a IDREF attribute");
   yield selectNode("label", inspector);
@@ -62,21 +62,8 @@ add_task(function* () {
   let onFailed = inspector.once("idref-attribute-link-failed");
   inspector.onFollowLink();
   yield onFailed;
 
   ok(true, "The node selection failed");
   is(inspector.selection.nodeFront.tagName.toLowerCase(), "output",
     "The <output> node is still selected");
 });
-
-function waitForTabLoad(tab) {
-  let def = defer();
-  tab.addEventListener("load", function onLoad(e) {
-    // Skip load event for about:blank
-    if (tab.linkedBrowser.currentURI.spec === "about:blank") {
-      return;
-    }
-    tab.removeEventListener("load", onLoad);
-    def.resolve();
-  });
-  return def.promise;
-}
--- a/devtools/client/inspector/markup/test/browser_markup_links_07.js
+++ b/devtools/client/inspector/markup/test/browser_markup_links_07.js
@@ -53,29 +53,16 @@ add_task(function* () {
 
   info("Try to follow link wiith middle-click, check no new node selected");
   yield followLinkNoNewNode(linkEl, false, inspector);
 
   info("Try to follow link wiith meta/ctrl-click, check no new node selected");
   yield followLinkNoNewNode(linkEl, true, inspector);
 });
 
-function waitForTabLoad(tab) {
-  let def = defer();
-  tab.addEventListener("load", function onLoad() {
-    // Skip load event for about:blank
-    if (tab.linkedBrowser.currentURI.spec === "about:blank") {
-      return;
-    }
-    tab.removeEventListener("load", onLoad);
-    def.resolve();
-  });
-  return def.promise;
-}
-
 function performMouseDown(linkEl, metactrl) {
   let evt = linkEl.ownerDocument.createEvent("MouseEvents");
 
   let button = -1;
 
   if (metactrl) {
     info("Performing Meta/Ctrl+Left Click");
     button = 0;
@@ -90,17 +77,17 @@ function performMouseDown(linkEl, metact
 
   linkEl.dispatchEvent(evt);
 }
 
 function* followLinkWaitForTab(linkEl, isMetaClick, expectedTabURI) {
   let onTabOpened = once(gBrowser.tabContainer, "TabOpen");
   performMouseDown(linkEl, isMetaClick);
   let {target} = yield onTabOpened;
-  yield waitForTabLoad(target);
+  yield BrowserTestUtils.browserLoaded(target.linkedBrowser);
   ok(true, "A new tab opened");
   is(target.linkedBrowser.currentURI.spec, expectedTabURI,
      "The URL for the new tab is correct");
   gBrowser.removeTab(target);
 }
 
 function* followLinkWaitForNewNode(linkEl, isMetaClick, inspector) {
   let onSelection = inspector.selection.once("new-node-front");
--- a/devtools/client/inspector/test/head.js
+++ b/devtools/client/inspector/test/head.js
@@ -655,18 +655,17 @@ function containsFocus(doc, container) {
  * does and completes the load event.
  *
  * @return a promise that resolves to the tab object
  */
 var waitForTab = Task.async(function* () {
   info("Waiting for a tab to open");
   yield once(gBrowser.tabContainer, "TabOpen");
   let tab = gBrowser.selectedTab;
-  let browser = tab.linkedBrowser;
-  yield once(browser, "load", true);
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   info("The tab load completed");
   return tab;
 });
 
 /**
  * Simulate the key input for the given input in the window.
  *
  * @param {String} input
--- a/devtools/client/projecteditor/test/head.js
+++ b/devtools/client/projecteditor/test/head.js
@@ -51,25 +51,23 @@ registerCleanupFunction(() => {
  * Add a new test tab in the browser and load the given url.
  * @param {String} url The url to be loaded in the new tab
  * @return a promise that resolves to the tab object when the url is loaded
  */
 function addTab(url) {
   info("Adding a new tab with URL: '" + url + "'");
   let def = promise.defer();
 
-  let tab = gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
+  let tab = gBrowser.selectedTab = gBrowser.addTab(url);
+  BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(function () {
     info("URL '" + url + "' loading complete");
     waitForFocus(() => {
       def.resolve(tab);
     }, content);
-  }, true);
-  content.location = url;
+  });
 
   return def.promise;
 }
 
 /**
  * Some tests may need to import one or more of the test helper scripts.
  * A test helper script is simply a js file that contains common test code that
  * is either not common-enough to be in head.js, or that is located in a separate
--- a/devtools/client/responsivedesign/test/head.js
+++ b/devtools/client/responsivedesign/test/head.js
@@ -190,17 +190,17 @@ function openRuleView() {
 var addTab = Task.async(function* (url) {
   info("Adding a new tab with URL: '" + url + "'");
 
   window.focus();
 
   let tab = gBrowser.selectedTab = gBrowser.addTab(url);
   let browser = tab.linkedBrowser;
 
-  yield once(browser, "load", true);
+  yield BrowserTestUtils.browserLoaded(browser);
   info("URL '" + url + "' loading complete");
 
   return tab;
 });
 
 /**
  * Waits for the next load to complete in the current browser.
  *
--- a/devtools/client/shadereditor/test/head.js
+++ b/devtools/client/shadereditor/test/head.js
@@ -70,21 +70,20 @@ function addTab(aUrl, aWindow) {
   let deferred = promise.defer();
   let targetWindow = aWindow || window;
   let targetBrowser = targetWindow.gBrowser;
 
   targetWindow.focus();
   let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
   let linkedBrowser = tab.linkedBrowser;
 
-  linkedBrowser.addEventListener("load", function onLoad() {
-    linkedBrowser.removeEventListener("load", onLoad, true);
+  BrowserTestUtils.browserLoaded(linkedBrowser).then(function () {
     info("Tab added and finished loading: " + aUrl);
     deferred.resolve(tab);
-  }, true);
+  });
 
   return deferred.promise;
 }
 
 function removeTab(aTab, aWindow) {
   info("Removing tab.");
 
   let deferred = promise.defer();
--- a/devtools/client/sourceeditor/test/browser_codemirror.js
+++ b/devtools/client/sourceeditor/test/browser_codemirror.js
@@ -7,19 +7,12 @@
 const URI = "chrome://mochitests/content/browser/devtools/client/" +
             "sourceeditor/test/codemirror/codemirror.html";
 loadHelperScript("helper_codemirror_runner.js");
 
 function test() {
   requestLongerTimeout(3);
   waitForExplicitFinish();
 
-  let tab = gBrowser.addTab();
-  gBrowser.selectedTab = tab;
-
-  let browser = gBrowser.getBrowserForTab(tab);
-  browser.addEventListener("load", function onLoad() {
-    browser.removeEventListener("load", onLoad, true);
-    runCodeMirrorTest(browser);
-  }, true);
-
-  browser.loadURI(URI);
+  addTab(URI).then(function (tab) {
+    runCodeMirrorTest(tab.linkedBrowser);
+  });
 }
--- a/devtools/client/sourceeditor/test/browser_css_autocompletion.js
+++ b/devtools/client/sourceeditor/test/browser_css_autocompletion.js
@@ -74,23 +74,20 @@ let doc = null;
 let index = 0;
 let completer = null;
 let progress;
 let progressDiv;
 let inspector;
 
 function test() {
   waitForExplicitFinish();
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
+  addTab(TEST_URI).then(function () {
     doc = content.document;
     runTests();
-  }, true);
-  content.location = TEST_URI;
+  });
 }
 
 function runTests() {
   progress = doc.getElementById("progress");
   progressDiv = doc.querySelector("#progress > div");
   let target = TargetFactory.forTab(gBrowser.selectedTab);
   target.makeRemote().then(() => {
     inspector = InspectorFront(target.client, target.form);
--- a/devtools/client/sourceeditor/test/browser_vimemacs.js
+++ b/devtools/client/sourceeditor/test/browser_vimemacs.js
@@ -6,19 +6,12 @@
 const URI = "chrome://mochitests/content/browser/devtools/client" +
             "/sourceeditor/test/codemirror/vimemacs.html";
 loadHelperScript("helper_codemirror_runner.js");
 
 function test() {
   requestLongerTimeout(4);
   waitForExplicitFinish();
 
-  let tab = gBrowser.addTab();
-  gBrowser.selectedTab = tab;
-
-  let browser = gBrowser.getBrowserForTab(tab);
-  browser.addEventListener("load", function onLoad() {
-    browser.removeEventListener("load", onLoad, true);
-    runCodeMirrorTest(browser);
-  }, true);
-
-  browser.loadURI(URI);
+  addTab(URI).then(function (tab) {
+    runCodeMirrorTest(tab.linkedBrowser);
+  });
 }
--- a/devtools/client/sourceeditor/test/head.js
+++ b/devtools/client/sourceeditor/test/head.js
@@ -16,28 +16,26 @@ SimpleTest.registerCleanupFunction(() =>
 });
 
 /**
  * Open a new tab at a URL and call a callback on load
  */
 function addTab(url, callback) {
   waitForExplicitFinish();
 
-  gBrowser.selectedTab = gBrowser.addTab();
-  content.location = url;
-
+  gBrowser.selectedTab = gBrowser.addTab(url);
   let tab = gBrowser.selectedTab;
   let browser = gBrowser.getBrowserForTab(tab);
 
-  function onTabLoad() {
-    browser.removeEventListener("load", onTabLoad, true);
-    callback(browser, tab, browser.contentDocument);
-  }
-
-  browser.addEventListener("load", onTabLoad, true);
+  return BrowserTestUtils.browserLoaded(browser).then(function () {
+    if (typeof(callback) == "function") {
+      callback(browser, tab, browser.contentDocument);
+    }
+    return tab;
+  });
 }
 
 function promiseTab(url) {
   return new Promise(resolve =>
     addTab(url, resolve));
 }
 
 function promiseWaitForFocus() {
--- a/devtools/client/styleeditor/test/head.js
+++ b/devtools/client/styleeditor/test/head.js
@@ -24,21 +24,21 @@ const TEST_HOST = "mochi.test:8888";
 var addTab = function (url, win) {
   info("Adding a new tab with URL: '" + url + "'");
   let def = defer();
 
   let targetWindow = win || window;
   let targetBrowser = targetWindow.gBrowser;
 
   let tab = targetBrowser.selectedTab = targetBrowser.addTab(url);
-  targetBrowser.selectedBrowser.addEventListener("load", function onload() {
-    targetBrowser.selectedBrowser.removeEventListener("load", onload, true);
-    info("URL '" + url + "' loading complete");
-    def.resolve(tab);
-  }, true);
+  BrowserTestUtils.browserLoaded(targetBrowser.selectedBrowser)
+    .then(function () {
+      info("URL '" + url + "' loading complete");
+      def.resolve(tab);
+    });
 
   return def.promise;
 };
 
 /**
  * Navigate the currently selected tab to a new URL and wait for it to load.
  * @param {String} url The url to be loaded in the current tab.
  * @return a promise that resolves when the page has fully loaded.
--- a/devtools/client/webaudioeditor/test/head.js
+++ b/devtools/client/webaudioeditor/test/head.js
@@ -67,21 +67,20 @@ function addTab(aUrl, aWindow) {
   let deferred = Promise.defer();
   let targetWindow = aWindow || window;
   let targetBrowser = targetWindow.gBrowser;
 
   targetWindow.focus();
   let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
   let linkedBrowser = tab.linkedBrowser;
 
-  linkedBrowser.addEventListener("load", function onLoad() {
-    linkedBrowser.removeEventListener("load", onLoad, true);
+  BrowserTestUtils.browserLoaded(linkedBrowser).then(function () {
     info("Tab added and finished loading: " + aUrl);
     deferred.resolve(tab);
-  }, true);
+  });
 
   return deferred.promise;
 }
 
 function removeTab(aTab, aWindow) {
   info("Removing tab.");
 
   let deferred = Promise.defer();
--- a/devtools/client/webide/test/head.js
+++ b/devtools/client/webide/test/head.js
@@ -161,21 +161,20 @@ function addTab(aUrl, aWindow) {
   let deferred = promise.defer();
   let targetWindow = aWindow || window;
   let targetBrowser = targetWindow.gBrowser;
 
   targetWindow.focus();
   let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
   let linkedBrowser = tab.linkedBrowser;
 
-  linkedBrowser.addEventListener("load", function onLoad() {
-    linkedBrowser.removeEventListener("load", onLoad, true);
+  BrowserTestUtils.browserLoaded(linkedBrowser).then(function () {
     info("Tab added and finished loading: " + aUrl);
     deferred.resolve(tab);
-  }, true);
+  });
 
   return deferred.promise;
 }
 
 function removeTab(aTab, aWindow) {
   info("Removing tab.");
 
   let deferred = promise.defer();
--- a/devtools/server/tests/browser/browser_canvasframe_helper_04.js
+++ b/devtools/server/tests/browser/browser_canvasframe_helper_04.js
@@ -60,17 +60,17 @@ add_task(function* () {
 
   info("Synthesizing an event on the element");
   let onDocMouseDown = once(doc, "mousedown");
   synthesizeMouseDown(100, 100, doc.defaultView);
   yield onDocMouseDown;
   is(mouseDownHandled, 1, "The mousedown event was handled once before navigation");
 
   info("Navigating to a new page");
-  let loaded = once(gBrowser.selectedBrowser, "load", true);
+  let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   content.location = TEST_URL_2;
   yield loaded;
   doc = gBrowser.selectedBrowser.contentWindow.document;
 
   info("Try to access the element again");
   is(el.getAttribute("class"), "child-element",
     "The attribute is correct after navigation");
   is(el.getTextContent(), "test content",
--- a/devtools/server/tests/browser/head.js
+++ b/devtools/server/tests/browser/head.js
@@ -28,17 +28,17 @@ waitForExplicitFinish();
  * @return a promise that resolves to the new browser that the document
  *         is loaded in. Note that we cannot return the document
  *         directly, since this would be a CPOW in the e10s case,
  *         and Promises cannot be resolved with CPOWs (see bug 1233497).
  */
 var addTab = Task.async(function* (url) {
   info(`Adding a new tab with URL: ${url}`);
   let tab = gBrowser.selectedTab = gBrowser.addTab(url);
-  yield once(gBrowser.selectedBrowser, "load", true);
+  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info(`Tab added and URL ${url} loaded`);
 
   return tab.linkedBrowser;
 });
 
 function* initAnimationsFrontForUrl(url) {
   const {AnimationsFront} = require("devtools/shared/fronts/animation");