Bug 1297362 - Part 3: Eliminate CPOWs from Netmonitor mochitests D-J r?ochameau draft
authorJarda Snajdr <jsnajdr@gmail.com>
Wed, 24 Aug 2016 15:55:56 +0200
changeset 406767 1f7243d1809eb4cf641dee6fe6baa7a904d90460
parent 406766 32db2b3cdfe1832475c9c661dc34a8d9fd03e3fd
child 406768 f298ab0c40b803fb3229c7cd772a58c9d7c2b5b0
push id27819
push userbmo:jsnajdr@gmail.com
push dateMon, 29 Aug 2016 13:56:30 +0000
reviewersochameau
bugs1297362
milestone51.0a1
Bug 1297362 - Part 3: Eliminate CPOWs from Netmonitor mochitests D-J r?ochameau MozReview-Commit-ID: AOswFvfl2wW
devtools/client/netmonitor/test/browser_net_details-no-duplicated-content.js
devtools/client/netmonitor/test/browser_net_filter-01.js
devtools/client/netmonitor/test/browser_net_filter-02.js
devtools/client/netmonitor/test/browser_net_filter-03.js
devtools/client/netmonitor/test/browser_net_filter-04.js
devtools/client/netmonitor/test/browser_net_footer-summary.js
devtools/client/netmonitor/test/browser_net_html-preview.js
devtools/client/netmonitor/test/browser_net_icon-preview.js
devtools/client/netmonitor/test/browser_net_image-tooltip.js
devtools/client/netmonitor/test/browser_net_json-long.js
devtools/client/netmonitor/test/browser_net_json-malformed.js
devtools/client/netmonitor/test/browser_net_json_custom_mime.js
devtools/client/netmonitor/test/browser_net_json_text_mime.js
devtools/client/netmonitor/test/browser_net_jsonp.js
--- a/devtools/client/netmonitor/test/browser_net_details-no-duplicated-content.js
+++ b/devtools/client/netmonitor/test/browser_net_details-no-duplicated-content.js
@@ -1,18 +1,18 @@
 /* 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/ */
+
 "use strict";
 
 // A test to ensure that the content in details pane is not duplicated.
 
-var test = Task.async(function* () {
-  info("Initializing test");
-  let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(CUSTOM_GET_URL);
   let panel = monitor.panelWin;
   let { NetMonitorView, EVENTS } = panel;
   let { RequestsMenu, NetworkDetails } = NetMonitorView;
 
   const COOKIE_UNIQUE_PATH = "/do-not-use-in-other-tests-using-cookies";
 
   let TEST_CASES = [
     {
@@ -40,69 +40,81 @@ var test = Task.async(function* () {
       isPost: true,
       tabIndex: 2,
       variablesView: NetworkDetails._params,
       expectedScopeLength: 1,
     },
   ];
 
   info("Adding a cookie for the \"Cookie\" tab test");
-  debuggee.document.cookie = "a=b; path=" + COOKIE_UNIQUE_PATH;
+  yield setDocCookie("a=b; path=" + COOKIE_UNIQUE_PATH);
 
   info("Running tests");
   for (let spec of TEST_CASES) {
     yield runTestCase(spec);
   }
 
   // Remove the cookie. If an error occurs the path of the cookie ensures it
   // doesn't mess with the other tests.
   info("Removing the added cookie.");
-  debuggee.document.cookie = "a=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=" +
-    COOKIE_UNIQUE_PATH;
+  yield setDocCookie(
+    "a=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=" + COOKIE_UNIQUE_PATH);
 
   yield teardown(monitor);
-  finish();
+
+  /**
+   * Set a content document cookie
+   */
+  function setDocCookie(cookie) {
+    return ContentTask.spawn(tab.linkedBrowser, cookie, function* (cookieArg) {
+      content.document.cookie = cookieArg;
+    });
+  }
 
   /**
    * A helper that handles the execution of each case.
    */
   function* runTestCase(spec) {
     info("Running case: " + spec.desc);
-    debuggee.content.location = spec.pageURI;
+    let wait = waitForNetworkEvents(monitor, 1);
+    tab.linkedBrowser.loadURI(spec.pageURI);
+    yield wait;
 
-    yield waitForNetworkEvents(monitor, 1);
     RequestsMenu.clear();
     yield waitForFinalDetailTabUpdate(spec.tabIndex, spec.isPost, spec.requestURI);
 
     is(spec.variablesView._store.length, spec.expectedScopeLength,
        "View contains " + spec.expectedScopeLength + " scope headers");
   }
 
   /**
    * A helper that prepares the variables view for the actual testing. It
    * - selects the correct tab
    * - performs the specified request to specified URI
    * - opens the details view
    * - waits for the final update to happen
    */
   function* waitForFinalDetailTabUpdate(tabIndex, isPost, uri) {
-    let onNetworkEvent = waitFor(panel, EVENTS.NETWORK_EVENT);
-    let onDetailsPopulated = waitFor(panel, EVENTS.NETWORKDETAILSVIEW_POPULATED);
+    let onNetworkEvent = panel.once(EVENTS.NETWORK_EVENT);
+    let onDetailsPopulated = panel.once(EVENTS.NETWORKDETAILSVIEW_POPULATED);
     let onRequestFinished = isPost ?
-      waitForNetworkEvents(monitor, 0, 1) : waitForNetworkEvents(monitor, 1);
+      waitForNetworkEvents(monitor, 0, 1) :
+      waitForNetworkEvents(monitor, 1);
 
     info("Performing a request");
-    debuggee.performRequests(1, uri);
+    yield ContentTask.spawn(tab.linkedBrowser, uri, function* (url) {
+      content.wrappedJSObject.performRequests(1, url);
+    });
 
     info("Waiting for NETWORK_EVENT");
     yield onNetworkEvent;
 
     if (!RequestsMenu.getItemAtIndex(0)) {
       info("Waiting for the request to be added to the view");
-      yield monitor.panelWin.once(monitor.panelWin.EVENTS.REQUEST_ADDED);
+      yield monitor.panelWin.once(EVENTS.REQUEST_ADDED);
     }
 
     ok(true, "Received NETWORK_EVENT. Selecting the item.");
     let item = RequestsMenu.getItemAtIndex(0);
     RequestsMenu.selectedItem = item;
 
     info("Item selected. Waiting for NETWORKDETAILSVIEW_POPULATED");
     yield onDetailsPopulated;
@@ -141,17 +153,17 @@ var test = Task.async(function* () {
     if (hasQueuedUpdates || hasRunningTabUpdate) {
       info("There's pending updates - waiting for them to finish.");
       info("  hasQueuedUpdates: " + hasQueuedUpdates);
       info("  hasRunningTabUpdate: " + hasRunningTabUpdate);
 
       if (hasQueuedUpdates && hasRunningTabUpdate) {
         info("Waiting for updates to be flushed.");
         // _flushRequests calls .populate which emits the following event
-        yield waitFor(panel, EVENTS.NETWORKDETAILSVIEW_POPULATED);
+        yield panel.once(EVENTS.NETWORKDETAILSVIEW_POPULATED);
 
         info("Requests flushed.");
       }
 
       info("Waiting for final tab update.");
       yield waitFor(panel, EVENTS.TAB_UPDATED);
     }
 
--- a/devtools/client/netmonitor/test/browser_net_filter-01.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-01.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Test if filtering items in the network table works correctly.
  */
 const BASIC_REQUESTS = [
   { url: "sjs_content-type-test-server.sjs?fmt=html&res=undefined&text=Sample" },
   { url: "sjs_content-type-test-server.sjs?fmt=css&text=sample" },
   { url: "sjs_content-type-test-server.sjs?fmt=js&text=sample" },
 ];
@@ -21,269 +23,244 @@ const REQUESTS_WITH_MEDIA_AND_FLASH = RE
   { url: "sjs_content-type-test-server.sjs?fmt=flash" },
 ]);
 
 const REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS = REQUESTS_WITH_MEDIA_AND_FLASH.concat([
   /* "Upgrade" is a reserved header and can not be set on XMLHttpRequest */
   { url: "sjs_content-type-test-server.sjs?fmt=ws" },
 ]);
 
-function test() {
-  initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
+add_task(function* () {
+  let [,, monitor] = yield initNetMonitor(FILTERING_URL);
+
+  function setFreetextFilter(value) {
+    // Set the text and manually call all callbacks synchronously to avoid the timeout
+    RequestsMenu.freetextFilterBox.value = value;
+    RequestsMenu.requestsFreetextFilterEvent();
+    RequestsMenu.userInputTimer.cancel();
+    RequestsMenu.reFilterRequests();
+  }
+
+  info("Starting test... ");
+
+  let { $, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
+
+  RequestsMenu.lazyUpdate = false;
+
+  let wait = waitForNetworkEvents(monitor, 9);
+  loadCommonFrameScript();
+  yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
+  yield wait;
+
+  EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
+
+  isnot(RequestsMenu.selectedItem, null,
+    "There should be a selected item in the requests menu.");
+  is(RequestsMenu.selectedIndex, 0,
+    "The first item should be selected in the requests menu.");
+  is(NetMonitorView.detailsPaneHidden, false,
+    "The details pane should not be hidden after toggle button was pressed.");
+
+  // First test with single filters...
+  testFilterButtons(monitor, "all");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
+  testFilterButtons(monitor, "html");
+  testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
+
+  // Reset filters
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
+  testFilterButtons(monitor, "css");
+  testContents([0, 1, 0, 0, 0, 0, 0, 0, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
+  testFilterButtons(monitor, "js");
+  testContents([0, 0, 1, 0, 0, 0, 0, 0, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
+  testFilterButtons(monitor, "xhr");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
+  testFilterButtons(monitor, "fonts");
+  testContents([0, 0, 0, 1, 0, 0, 0, 0, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
+  testFilterButtons(monitor, "images");
+  testContents([0, 0, 0, 0, 1, 0, 0, 0, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
+  testFilterButtons(monitor, "media");
+  testContents([0, 0, 0, 0, 0, 1, 1, 0, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
+  testFilterButtons(monitor, "flash");
+  testContents([0, 0, 0, 0, 0, 0, 0, 1, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-ws-button"));
+  testFilterButtons(monitor, "ws");
+  testContents([0, 0, 0, 0, 0, 0, 0, 0, 1]);
 
-    function setFreetextFilter(value) {
-      // Set the text and manually call all callbacks synchronously to avoid the timeout
-      RequestsMenu.freetextFilterBox.value = value;
-      RequestsMenu.requestsFreetextFilterEvent();
-      RequestsMenu.userInputTimer.cancel();
-      RequestsMenu.reFilterRequests();
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  testFilterButtons(monitor, "all");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
+
+  // Text in filter box that matches nothing should hide all.
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  setFreetextFilter("foobar");
+  testContents([0, 0, 0, 0, 0, 0, 0, 0, 0]);
+
+  // Text in filter box that matches should filter out everything else.
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  setFreetextFilter("sample");
+  testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]);
+
+  // Text in filter box that matches should filter out everything else.
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  setFreetextFilter("SAMPLE");
+  testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]);
+
+  // Test negative filtering (only show unmatched items)
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  setFreetextFilter("-sample");
+  testContents([0, 0, 0, 1, 1, 1, 1, 1, 1]);
+
+  // ...then combine multiple filters together.
+
+  // Enable filtering for html and css; should show request of both type.
+  setFreetextFilter("");
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
+  testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
+  testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]);
+
+  // Html and css filter enabled and text filter should show just the html and css match.
+  // Should not show both the items matching the button plus the items matching the text.
+  setFreetextFilter("sample");
+  testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]);
+
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
+  setFreetextFilter("");
+  testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0]);
+  testContents([1, 1, 0, 0, 0, 0, 0, 1, 0]);
+
+  // Disable some filters. Only one left active.
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
+  testFilterButtons(monitor, "html");
+  testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
+
+  // Disable last active filter. Should toggle to all.
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
+  testFilterButtons(monitor, "all");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
+
+  // Enable few filters and click on all. Only "all" should be checked.
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-ws-button"));
+  testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 1]);
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  testFilterButtons(monitor, "all");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
+
+  yield teardown(monitor);
+
+  function testContents(visibility) {
+    isnot(RequestsMenu.selectedItem, null,
+      "There should still be a selected item after filtering.");
+    is(RequestsMenu.selectedIndex, 0,
+      "The first item should be still selected after filtering.");
+    is(NetMonitorView.detailsPaneHidden, false,
+      "The details pane should still be visible after filtering.");
+
+    is(RequestsMenu.items.length, visibility.length,
+      "There should be a specific amount of items in the requests menu.");
+    is(RequestsMenu.visibleItems.length, visibility.filter(e => e).length,
+      "There should be a specific amount of visbile items in the requests menu.");
+
+    for (let i = 0; i < visibility.length; i++) {
+      is(RequestsMenu.getItemAtIndex(i).target.hidden, !visibility[i],
+        "The item at index " + i + " doesn't have the correct hidden state.");
     }
 
-    info("Starting test... ");
-
-    let { $, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
-
-    RequestsMenu.lazyUpdate = false;
-
-    waitForNetworkEvents(aMonitor, 9).then(() => {
-      EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
-
-      isnot(RequestsMenu.selectedItem, null,
-        "There should be a selected item in the requests menu.");
-      is(RequestsMenu.selectedIndex, 0,
-        "The first item should be selected in the requests menu.");
-      is(NetMonitorView.detailsPaneHidden, false,
-        "The details pane should not be hidden after toggle button was pressed.");
-
-      // First test with single filters...
-      testFilterButtons(aMonitor, "all");
-      testContents([1, 1, 1, 1, 1, 1, 1, 1, 1])
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-          testFilterButtons(aMonitor, "html");
-          return testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          // Reset filters
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
-          testFilterButtons(aMonitor, "css");
-          return testContents([0, 1, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
-          testFilterButtons(aMonitor, "js");
-          return testContents([0, 0, 1, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
-          testFilterButtons(aMonitor, "xhr");
-          return testContents([1, 1, 1, 1, 1, 1, 1, 1, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
-          testFilterButtons(aMonitor, "fonts");
-          return testContents([0, 0, 0, 1, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
-          testFilterButtons(aMonitor, "images");
-          return testContents([0, 0, 0, 0, 1, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
-          testFilterButtons(aMonitor, "media");
-          return testContents([0, 0, 0, 0, 0, 1, 1, 0, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
-          testFilterButtons(aMonitor, "flash");
-          return testContents([0, 0, 0, 0, 0, 0, 0, 1, 0]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-ws-button"));
-          testFilterButtons(aMonitor, "ws");
-          return testContents([0, 0, 0, 0, 0, 0, 0, 0, 1]);
-        })
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          testFilterButtons(aMonitor, "all");
-          return testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
-        })
-        .then(() => {
-          // Text in filter box that matches nothing should hide all.
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          setFreetextFilter("foobar");
-          return testContents([0, 0, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          // Text in filter box that matches should filter out everything else.
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          setFreetextFilter("sample");
-          return testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          // Text in filter box that matches should filter out everything else.
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          setFreetextFilter("SAMPLE");
-          return testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          // Test negative filtering (only show unmatched items)
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          setFreetextFilter("-sample");
-          return testContents([0, 0, 0, 1, 1, 1, 1, 1, 1]);
-        })
-        // ...then combine multiple filters together.
-        .then(() => {
-          // Enable filtering for html and css; should show request of both type.
-          setFreetextFilter("");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
-          testFilterButtonsCustom(aMonitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
-          return testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          // Html and css filter enabled and text filter should show just the html and css match.
-          // Should not show both the items that match the button plus the items that match the text.
-          setFreetextFilter("sample");
-          return testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]);
-        })
-
-        .then(() => {
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
-          setFreetextFilter("");
-          testFilterButtonsCustom(aMonitor, [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0]);
-          return testContents([1, 1, 0, 0, 0, 0, 0, 1, 0]);
-        })
-        .then(() => {
-          // Disable some filters. Only one left active.
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
-          testFilterButtons(aMonitor, "html");
-          return testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          // Disable last active filter. Should toggle to all.
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-          testFilterButtons(aMonitor, "all");
-          return testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
-        })
-        .then(() => {
-          // Enable few filters and click on all. Only "all" should be checked.
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-ws-button"));
-          testFilterButtonsCustom(aMonitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 1]);
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          testFilterButtons(aMonitor, "all");
-          return testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
-        })
-        .then(() => {
-          return teardown(aMonitor);
-        })
-        .then(finish);
-    });
-
-    function testContents(aVisibility) {
-      isnot(RequestsMenu.selectedItem, null,
-        "There should still be a selected item after filtering.");
-      is(RequestsMenu.selectedIndex, 0,
-        "The first item should be still selected after filtering.");
-      is(NetMonitorView.detailsPaneHidden, false,
-        "The details pane should still be visible after filtering.");
-
-      is(RequestsMenu.items.length, aVisibility.length,
-        "There should be a specific amount of items in the requests menu.");
-      is(RequestsMenu.visibleItems.length, aVisibility.filter(e => e).length,
-        "There should be a specific amount of visbile items in the requests menu.");
-
-      for (let i = 0; i < aVisibility.length; i++) {
-        is(RequestsMenu.getItemAtIndex(i).target.hidden, !aVisibility[i],
-          "The item at index " + i + " doesn't have the correct hidden state.");
-      }
-
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
-        "GET", CONTENT_TYPE_SJS + "?fmt=html", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "html",
-          fullMimeType: "text/html; charset=utf-8"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
-        "GET", CONTENT_TYPE_SJS + "?fmt=css", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "css",
-          fullMimeType: "text/css; charset=utf-8"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(2),
-        "GET", CONTENT_TYPE_SJS + "?fmt=js", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "js",
-          fullMimeType: "application/javascript; charset=utf-8"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(3),
-        "GET", CONTENT_TYPE_SJS + "?fmt=font", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "woff",
-          fullMimeType: "font/woff"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(4),
-        "GET", CONTENT_TYPE_SJS + "?fmt=image", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "png",
-          fullMimeType: "image/png"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(5),
-        "GET", CONTENT_TYPE_SJS + "?fmt=audio", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "ogg",
-          fullMimeType: "audio/ogg"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(6),
-        "GET", CONTENT_TYPE_SJS + "?fmt=video", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "webm",
-          fullMimeType: "video/webm"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(7),
-        "GET", CONTENT_TYPE_SJS + "?fmt=flash", {
-          fuzzyUrl: true,
-          status: 200,
-          statusText: "OK",
-          type: "x-shockwave-flash",
-          fullMimeType: "application/x-shockwave-flash"
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(8),
-        "GET", CONTENT_TYPE_SJS + "?fmt=ws", {
-          fuzzyUrl: true,
-          status: 101,
-          statusText: "Switching Protocols",
-        });
-
-      return promise.resolve(null);
-    }
-
-    loadCommonFrameScript();
-    performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
-  });
-}
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
+      "GET", CONTENT_TYPE_SJS + "?fmt=html", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "html",
+        fullMimeType: "text/html; charset=utf-8"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
+      "GET", CONTENT_TYPE_SJS + "?fmt=css", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "css",
+        fullMimeType: "text/css; charset=utf-8"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(2),
+      "GET", CONTENT_TYPE_SJS + "?fmt=js", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "js",
+        fullMimeType: "application/javascript; charset=utf-8"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(3),
+      "GET", CONTENT_TYPE_SJS + "?fmt=font", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "woff",
+        fullMimeType: "font/woff"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(4),
+      "GET", CONTENT_TYPE_SJS + "?fmt=image", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "png",
+        fullMimeType: "image/png"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(5),
+      "GET", CONTENT_TYPE_SJS + "?fmt=audio", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "ogg",
+        fullMimeType: "audio/ogg"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(6),
+      "GET", CONTENT_TYPE_SJS + "?fmt=video", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "webm",
+        fullMimeType: "video/webm"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(7),
+      "GET", CONTENT_TYPE_SJS + "?fmt=flash", {
+        fuzzyUrl: true,
+        status: 200,
+        statusText: "OK",
+        type: "x-shockwave-flash",
+        fullMimeType: "application/x-shockwave-flash"
+      });
+    verifyRequestItemTarget(RequestsMenu.getItemAtIndex(8),
+      "GET", CONTENT_TYPE_SJS + "?fmt=ws", {
+        fuzzyUrl: true,
+        status: 101,
+        statusText: "Switching Protocols",
+      });
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_filter-02.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-02.js
@@ -1,14 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Test if filtering items in the network table works correctly with new requests.
  */
+
 const BASIC_REQUESTS = [
   { url: "sjs_content-type-test-server.sjs?fmt=html&res=undefined" },
   { url: "sjs_content-type-test-server.sjs?fmt=css" },
   { url: "sjs_content-type-test-server.sjs?fmt=js" },
 ];
 
 const REQUESTS_WITH_MEDIA = BASIC_REQUESTS.concat([
   { url: "sjs_content-type-test-server.sjs?fmt=font" },
@@ -21,184 +24,177 @@ const REQUESTS_WITH_MEDIA_AND_FLASH = RE
   { url: "sjs_content-type-test-server.sjs?fmt=flash" },
 ]);
 
 const REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS = REQUESTS_WITH_MEDIA_AND_FLASH.concat([
   /* "Upgrade" is a reserved header and can not be set on XMLHttpRequest */
   { url: "sjs_content-type-test-server.sjs?fmt=ws" },
 ]);
 
-function test() {
-  initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+add_task(function* () {
+  let [,, monitor] = yield initNetMonitor(FILTERING_URL);
+  info("Starting test... ");
 
-    // It seems that this test may be slow on Ubuntu builds running on ec2.
-    requestLongerTimeout(2);
-
-    let { $, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
+  // It seems that this test may be slow on Ubuntu builds running on ec2.
+  requestLongerTimeout(2);
 
-    RequestsMenu.lazyUpdate = false;
+  let { $, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-    waitForNetworkEvents(aMonitor, 9).then(() => {
-      EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
+  RequestsMenu.lazyUpdate = false;
 
-      isnot(RequestsMenu.selectedItem, null,
-        "There should be a selected item in the requests menu.");
-      is(RequestsMenu.selectedIndex, 0,
-        "The first item should be selected in the requests menu.");
-      is(NetMonitorView.detailsPaneHidden, false,
-        "The details pane should not be hidden after toggle button was pressed.");
+  let wait = waitForNetworkEvents(monitor, 9);
+  loadCommonFrameScript();
+  yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
+  yield wait;
+
+  EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
 
-      testFilterButtons(aMonitor, "all");
-      testContents([1, 1, 1, 1, 1, 1, 1, 1, 1])
-        .then(() => {
-          info("Testing html filtering.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-          testFilterButtons(aMonitor, "html");
-          return testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          info("Performing more requests.");
-          performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
-          return waitForNetworkEvents(aMonitor, 9);
-        })
-        .then(() => {
-          info("Testing html filtering again.");
-          testFilterButtons(aMonitor, "html");
-          return testContents([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          info("Performing more requests.");
-          performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
-          return waitForNetworkEvents(aMonitor, 9);
-        })
-        .then(() => {
-          info("Testing html filtering again.");
-          testFilterButtons(aMonitor, "html");
-          return testContents([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
-        })
-        .then(() => {
-          info("Resetting filters.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
-          testFilterButtons(aMonitor, "all");
-          return testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
-        })
-        .then(() => {
-          return teardown(aMonitor);
-        })
-        .then(finish);
-    });
+  isnot(RequestsMenu.selectedItem, null,
+    "There should be a selected item in the requests menu.");
+  is(RequestsMenu.selectedIndex, 0,
+    "The first item should be selected in the requests menu.");
+  is(NetMonitorView.detailsPaneHidden, false,
+    "The details pane should not be hidden after toggle button was pressed.");
+
+  testFilterButtons(monitor, "all");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
 
-    function testContents(aVisibility) {
-      isnot(RequestsMenu.selectedItem, null,
-        "There should still be a selected item after filtering.");
-      is(RequestsMenu.selectedIndex, 0,
-        "The first item should be still selected after filtering.");
-      is(NetMonitorView.detailsPaneHidden, false,
-        "The details pane should still be visible after filtering.");
+  info("Testing html filtering.");
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
+  testFilterButtons(monitor, "html");
+  testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
 
-      is(RequestsMenu.items.length, aVisibility.length,
-        "There should be a specific amount of items in the requests menu.");
-      is(RequestsMenu.visibleItems.length, aVisibility.filter(e => e).length,
-        "There should be a specific amount of visbile items in the requests menu.");
-
-      for (let i = 0; i < aVisibility.length; i++) {
-        is(RequestsMenu.getItemAtIndex(i).target.hidden, !aVisibility[i],
-          "The item at index " + i + " doesn't have the correct hidden state.");
-      }
+  info("Performing more requests.");
+  wait = waitForNetworkEvents(monitor, 9);
+  yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
+  yield wait;
 
-      for (let i = 0; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=html", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "html",
-            fullMimeType: "text/html; charset=utf-8"
-          });
-      }
-      for (let i = 1; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=css", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "css",
-            fullMimeType: "text/css; charset=utf-8"
-          });
-      }
-      for (let i = 2; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=js", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "js",
-            fullMimeType: "application/javascript; charset=utf-8"
-          });
-      }
-      for (let i = 3; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=font", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "woff",
-            fullMimeType: "font/woff"
-          });
-      }
-      for (let i = 4; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=image", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "png",
-            fullMimeType: "image/png"
-          });
-      }
-      for (let i = 5; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=audio", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "ogg",
-            fullMimeType: "audio/ogg"
-          });
-      }
-      for (let i = 6; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=video", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "webm",
-            fullMimeType: "video/webm"
-          });
-      }
-      for (let i = 7; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=flash", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "x-shockwave-flash",
-            fullMimeType: "application/x-shockwave-flash"
-          });
-      }
-      for (let i = 8; i < aVisibility.length; i += 9) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
-          "GET", CONTENT_TYPE_SJS + "?fmt=ws", {
-            fuzzyUrl: true,
-            status: 101,
-            statusText: "Switching Protocols"
-          });
-      }
+  info("Testing html filtering again.");
+  testFilterButtons(monitor, "html");
+  testContents([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
+
+  info("Performing more requests.");
+  wait = waitForNetworkEvents(monitor, 9);
+  yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
+  yield wait;
+
+  info("Testing html filtering again.");
+  testFilterButtons(monitor, "html");
+  testContents([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+                0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
 
-      return promise.resolve(null);
+  info("Resetting filters.");
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
+  testFilterButtons(monitor, "all");
+  testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
+
+  yield teardown(monitor);
+
+  function testContents(visibility) {
+    isnot(RequestsMenu.selectedItem, null,
+      "There should still be a selected item after filtering.");
+    is(RequestsMenu.selectedIndex, 0,
+      "The first item should be still selected after filtering.");
+    is(NetMonitorView.detailsPaneHidden, false,
+      "The details pane should still be visible after filtering.");
+
+    is(RequestsMenu.items.length, visibility.length,
+      "There should be a specific amount of items in the requests menu.");
+    is(RequestsMenu.visibleItems.length, visibility.filter(e => e).length,
+      "There should be a specific amount of visbile items in the requests menu.");
+
+    for (let i = 0; i < visibility.length; i++) {
+      is(RequestsMenu.getItemAtIndex(i).target.hidden, !visibility[i],
+        "The item at index " + i + " doesn't have the correct hidden state.");
     }
 
-    loadCommonFrameScript();
-    performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
-  });
-}
+    for (let i = 0; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=html", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "html",
+          fullMimeType: "text/html; charset=utf-8"
+        });
+    }
+    for (let i = 1; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=css", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "css",
+          fullMimeType: "text/css; charset=utf-8"
+        });
+    }
+    for (let i = 2; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=js", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "js",
+          fullMimeType: "application/javascript; charset=utf-8"
+        });
+    }
+    for (let i = 3; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=font", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "woff",
+          fullMimeType: "font/woff"
+        });
+    }
+    for (let i = 4; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=image", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "png",
+          fullMimeType: "image/png"
+        });
+    }
+    for (let i = 5; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=audio", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "ogg",
+          fullMimeType: "audio/ogg"
+        });
+    }
+    for (let i = 6; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=video", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "webm",
+          fullMimeType: "video/webm"
+        });
+    }
+    for (let i = 7; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=flash", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "x-shockwave-flash",
+          fullMimeType: "application/x-shockwave-flash"
+        });
+    }
+    for (let i = 8; i < visibility.length; i += 9) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
+        "GET", CONTENT_TYPE_SJS + "?fmt=ws", {
+          fuzzyUrl: true,
+          status: 101,
+          statusText: "Switching Protocols"
+        });
+    }
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_filter-03.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-03.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Test if filtering items in the network table works correctly with new requests
  * and while sorting is enabled.
  */
 const BASIC_REQUESTS = [
   { url: "sjs_content-type-test-server.sjs?fmt=html&res=undefined" },
   { url: "sjs_content-type-test-server.sjs?fmt=css" },
   { url: "sjs_content-type-test-server.sjs?fmt=js" },
@@ -13,185 +15,171 @@ const BASIC_REQUESTS = [
 
 const REQUESTS_WITH_MEDIA = BASIC_REQUESTS.concat([
   { url: "sjs_content-type-test-server.sjs?fmt=font" },
   { url: "sjs_content-type-test-server.sjs?fmt=image" },
   { url: "sjs_content-type-test-server.sjs?fmt=audio" },
   { url: "sjs_content-type-test-server.sjs?fmt=video" },
 ]);
 
-const REQUESTS_WITH_MEDIA_AND_FLASH = REQUESTS_WITH_MEDIA.concat([
-  { url: "sjs_content-type-test-server.sjs?fmt=flash" },
-]);
+add_task(function* () {
+  let [,, monitor] = yield initNetMonitor(FILTERING_URL);
+  info("Starting test... ");
+
+  // It seems that this test may be slow on Ubuntu builds running on ec2.
+  requestLongerTimeout(2);
+
+  let { $, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-function test() {
-  initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+  RequestsMenu.lazyUpdate = false;
 
-    // It seems that this test may be slow on Ubuntu builds running on ec2.
-    requestLongerTimeout(2);
+  // The test assumes that the first HTML request here has a longer response
+  // body than the other HTML requests performed later during the test.
+  let requests = Cu.cloneInto(REQUESTS_WITH_MEDIA, {});
+  let newres = "res=<p>" + new Array(10).join(Math.random(10)) + "</p>";
+  requests[0].url = requests[0].url.replace("res=undefined", newres);
+
+  loadCommonFrameScript();
 
-    let { $, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
+  let wait = waitForNetworkEvents(monitor, 7);
+  yield performRequestsInContent(requests);
+  yield wait;
 
-    RequestsMenu.lazyUpdate = false;
+  EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
 
-    waitForNetworkEvents(aMonitor, 7).then(() => {
-      EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
+  isnot(RequestsMenu.selectedItem, null,
+    "There should be a selected item in the requests menu.");
+  is(RequestsMenu.selectedIndex, 0,
+    "The first item should be selected in the requests menu.");
+  is(NetMonitorView.detailsPaneHidden, false,
+    "The details pane should not be hidden after toggle button was pressed.");
 
-      isnot(RequestsMenu.selectedItem, null,
-        "There should be a selected item in the requests menu.");
-      is(RequestsMenu.selectedIndex, 0,
-        "The first item should be selected in the requests menu.");
-      is(NetMonitorView.detailsPaneHidden, false,
-        "The details pane should not be hidden after toggle button was pressed.");
+  testFilterButtons(monitor, "all");
+  testContents([0, 1, 2, 3, 4, 5, 6], 7, 0);
+
+  info("Sorting by size, ascending.");
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
+  testFilterButtons(monitor, "all");
+  testContents([6, 4, 5, 0, 1, 2, 3], 7, 6);
 
-      testFilterButtons(aMonitor, "all");
-      testContents([0, 1, 2, 3, 4, 5, 6], 7, 0)
-        .then(() => {
-          info("Sorting by size, ascending.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
-          testFilterButtons(aMonitor, "all");
-          return testContents([6, 4, 5, 0, 1, 2, 3], 7, 6);
-        })
-        .then(() => {
-          info("Testing html filtering.");
-          EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-          testFilterButtons(aMonitor, "html");
-          return testContents([6, 4, 5, 0, 1, 2, 3], 1, 6);
-        })
-        .then(() => {
-          info("Performing more requests.");
-          performRequestsInContent(REQUESTS_WITH_MEDIA);
-          return waitForNetworkEvents(aMonitor, 7);
-        })
-        .then(() => {
-          info("Testing html filtering again.");
-          resetSorting();
-          testFilterButtons(aMonitor, "html");
-          return testContents([8, 13, 9, 11, 10, 12, 0, 4, 1, 5, 2, 6, 3, 7], 2, 13);
-        })
-        .then(() => {
-          info("Performing more requests.");
-          performRequestsInContent(REQUESTS_WITH_MEDIA);
-          return waitForNetworkEvents(aMonitor, 7);
-        })
-        .then(() => {
-          info("Testing html filtering again.");
-          resetSorting();
-          testFilterButtons(aMonitor, "html");
-          return testContents([12, 13, 20, 14, 16, 18, 15, 17, 19, 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11], 3, 20);
-        })
-        .then(() => {
-          return teardown(aMonitor);
-        })
-        .then(finish);
-    });
+  info("Testing html filtering.");
+  EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
+  testFilterButtons(monitor, "html");
+  testContents([6, 4, 5, 0, 1, 2, 3], 1, 6);
+
+  info("Performing more requests.");
+  wait = waitForNetworkEvents(monitor, 7);
+  performRequestsInContent(REQUESTS_WITH_MEDIA);
+  yield wait;
+
+  info("Testing html filtering again.");
+  resetSorting();
+  testFilterButtons(monitor, "html");
+  testContents([8, 13, 9, 11, 10, 12, 0, 4, 1, 5, 2, 6, 3, 7], 2, 13);
+
+  info("Performing more requests.");
+  performRequestsInContent(REQUESTS_WITH_MEDIA);
+  yield waitForNetworkEvents(monitor, 7);
 
-    function resetSorting() {
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-waterfall-button"));
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
+  info("Testing html filtering again.");
+  resetSorting();
+  testFilterButtons(monitor, "html");
+  testContents([12, 13, 20, 14, 16, 18, 15, 17, 19, 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11],
+    3, 20);
+
+  yield teardown(monitor);
+
+  function resetSorting() {
+    EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-waterfall-button"));
+    EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
+  }
+
+  function testContents(order, visible, selection) {
+    isnot(RequestsMenu.selectedItem, null,
+      "There should still be a selected item after filtering.");
+    is(RequestsMenu.selectedIndex, selection,
+      "The first item should be still selected after filtering.");
+    is(NetMonitorView.detailsPaneHidden, false,
+      "The details pane should still be visible after filtering.");
+
+    is(RequestsMenu.items.length, order.length,
+      "There should be a specific amount of items in the requests menu.");
+    is(RequestsMenu.visibleItems.length, visible,
+      "There should be a specific amount of visbile items in the requests menu.");
+
+    for (let i = 0; i < order.length; i++) {
+      is(RequestsMenu.getItemAtIndex(i), RequestsMenu.items[i],
+        "The requests menu items aren't ordered correctly. Misplaced item " + i + ".");
     }
 
-    function testContents(aOrder, aVisible, aSelection) {
-      isnot(RequestsMenu.selectedItem, null,
-        "There should still be a selected item after filtering.");
-      is(RequestsMenu.selectedIndex, aSelection,
-        "The first item should be still selected after filtering.");
-      is(NetMonitorView.detailsPaneHidden, false,
-        "The details pane should still be visible after filtering.");
-
-      is(RequestsMenu.items.length, aOrder.length,
-        "There should be a specific amount of items in the requests menu.");
-      is(RequestsMenu.visibleItems.length, aVisible,
-        "There should be a specific amount of visbile items in the requests menu.");
-
-      for (let i = 0; i < aOrder.length; i++) {
-        is(RequestsMenu.getItemAtIndex(i), RequestsMenu.items[i],
-          "The requests menu items aren't ordered correctly. Misplaced item " + i + ".");
-      }
-
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=html", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "html",
-            fullMimeType: "text/html; charset=utf-8"
-          });
-      }
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=css", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "css",
-            fullMimeType: "text/css; charset=utf-8"
-          });
-      }
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=js", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "js",
-            fullMimeType: "application/javascript; charset=utf-8"
-          });
-      }
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=font", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "woff",
-            fullMimeType: "font/woff"
-          });
-      }
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=image", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "png",
-            fullMimeType: "image/png"
-          });
-      }
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 5]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=audio", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "ogg",
-            fullMimeType: "audio/ogg"
-          });
-      }
-      for (let i = 0, len = aOrder.length / 7; i < len; i++) {
-        verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 6]),
-          "GET", CONTENT_TYPE_SJS + "?fmt=video", {
-            fuzzyUrl: true,
-            status: 200,
-            statusText: "OK",
-            type: "webm",
-            fullMimeType: "video/webm"
-          });
-      }
-
-      return promise.resolve(null);
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=html", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "html",
+          fullMimeType: "text/html; charset=utf-8"
+        });
+    }
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i + len]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=css", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "css",
+          fullMimeType: "text/css; charset=utf-8"
+        });
+    }
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i + len * 2]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=js", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "js",
+          fullMimeType: "application/javascript; charset=utf-8"
+        });
     }
-
-    // The test assumes that the first HTML request here has a longer response
-    // body than the other HTML requests performed later during the test.
-    let requests = Cu.cloneInto(REQUESTS_WITH_MEDIA, {});
-
-    let newres = "res=<p>" + new Array(10).join(Math.random(10)) + "</p>";
-    requests[0].url = requests[0].url.replace("res=undefined", newres);
-
-    loadCommonFrameScript();
-    performRequestsInContent(requests);
-
-  });
-}
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i + len * 3]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=font", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "woff",
+          fullMimeType: "font/woff"
+        });
+    }
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i + len * 4]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=image", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "png",
+          fullMimeType: "image/png"
+        });
+    }
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i + len * 5]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=audio", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "ogg",
+          fullMimeType: "audio/ogg"
+        });
+    }
+    for (let i = 0, len = order.length / 7; i < len; i++) {
+      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(order[i + len * 6]),
+        "GET", CONTENT_TYPE_SJS + "?fmt=video", {
+          fuzzyUrl: true,
+          status: 200,
+          statusText: "OK",
+          type: "webm",
+          fullMimeType: "video/webm"
+        });
+    }
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_filter-04.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-04.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if invalid filter types are sanitized when loaded from the preferences.
  */
 
 const BASIC_REQUESTS = [
   { url: "sjs_content-type-test-server.sjs?fmt=html&res=undefined" },
   { url: "sjs_content-type-test-server.sjs?fmt=css" },
   { url: "sjs_content-type-test-server.sjs?fmt=js" },
@@ -22,43 +24,40 @@ const REQUESTS_WITH_MEDIA_AND_FLASH = RE
   { url: "sjs_content-type-test-server.sjs?fmt=flash" },
 ]);
 
 const REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS = REQUESTS_WITH_MEDIA_AND_FLASH.concat([
   /* "Upgrade" is a reserved header and can not be set on XMLHttpRequest */
   { url: "sjs_content-type-test-server.sjs?fmt=ws" },
 ]);
 
-function test() {
+add_task(function* () {
   Services.prefs.setCharPref("devtools.netmonitor.filters", '["js", "bogus"]');
 
-  initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+  let [,, monitor] = yield initNetMonitor(FILTERING_URL);
+  info("Starting test... ");
 
-    let { Prefs, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
+  let { Prefs, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-    RequestsMenu.lazyUpdate = false;
+  RequestsMenu.lazyUpdate = false;
 
-    is(Prefs.filters.length, 2,
-      "All filter types were loaded as an array from the preferences.");
-    is(Prefs.filters[0], "js",
-      "The first filter type is correct.");
-    is(Prefs.filters[1], "bogus",
-      "The second filter type is invalid, but loaded anyway.");
+  is(Prefs.filters.length, 2,
+    "All filter types were loaded as an array from the preferences.");
+  is(Prefs.filters[0], "js",
+    "The first filter type is correct.");
+  is(Prefs.filters[1], "bogus",
+    "The second filter type is invalid, but loaded anyway.");
 
-    waitForNetworkEvents(aMonitor, 9).then(() => {
-      testFilterButtons(aMonitor, "js");
-      ok(true, "Only the correct filter type was taken into consideration.");
-
-      teardown(aMonitor).then(() => {
-        let filters = Services.prefs.getCharPref("devtools.netmonitor.filters");
-        is(filters, '["js"]',
-          "The bogus filter type was ignored and removed from the preferences.");
+  let wait = waitForNetworkEvents(monitor, 9);
+  loadCommonFrameScript();
+  yield performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
+  yield wait;
 
-        finish();
-      });
-    });
+  testFilterButtons(monitor, "js");
+  ok(true, "Only the correct filter type was taken into consideration.");
+
+  yield teardown(monitor);
 
-    loadCommonFrameScript();
-    performRequestsInContent(REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS);
-  });
-}
+  let filters = Services.prefs.getCharPref("devtools.netmonitor.filters");
+  is(filters, '["js"]',
+    "The bogus filter type was ignored and removed from the preferences.");
+});
--- a/devtools/client/netmonitor/test/browser_net_footer-summary.js
+++ b/devtools/client/netmonitor/test/browser_net_footer-summary.js
@@ -1,116 +1,74 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Test if the summary text displayed in the network requests menu footer
  * is correct.
  */
 
-function test() {
+add_task(function* () {
   requestLongerTimeout(2);
   let { PluralForm } = Cu.import("resource://gre/modules/PluralForm.jsm", {});
 
-  initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+  let [tab,, monitor] = yield initNetMonitor(FILTERING_URL);
+  info("Starting test... ");
+
+  let { $, L10N, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
+
+  RequestsMenu.lazyUpdate = false;
+  testStatus();
 
-    let { $, L10N, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
+  for (let i = 0; i < 2; i++) {
+    info(`Performing requests in batch #${i}`);
+    let wait = waitForNetworkEvents(monitor, 8);
+    yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+      content.wrappedJSObject.performRequests('{ "getMedia": true, "getFlash": true }');
+    });
+    yield wait;
 
-    RequestsMenu.lazyUpdate = false;
     testStatus();
 
-    waitForNetworkEvents(aMonitor, 8).then(() => {
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
-      testStatus();
-
-      info("Performing more requests.");
-      aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
-      return waitForNetworkEvents(aMonitor, 8);
-    })
-    .then(() => {
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
+    let buttons = ["html", "css", "js", "xhr", "fonts", "images", "media", "flash"];
+    for (let button of buttons) {
+      let buttonEl = $(`#requests-menu-filter-${button}-button`);
+      EventUtils.sendMouseEvent({ type: "click" }, buttonEl);
       testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
-      testStatus();
+    }
+  }
 
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
-      testStatus();
-
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
-      testStatus();
+  yield teardown(monitor);
 
-      EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
-      testStatus();
-
-      teardown(aMonitor).then(finish);
-    });
-
-    function testStatus() {
-      let summary = $("#requests-menu-network-summary-button");
-      let value = summary.getAttribute("label");
-      info("Current summary: " + value);
+  function testStatus() {
+    let summary = $("#requests-menu-network-summary-button");
+    let value = summary.getAttribute("label");
+    info("Current summary: " + value);
 
-      let visibleItems = RequestsMenu.visibleItems;
-      let visibleRequestsCount = visibleItems.length;
-      let totalRequestsCount = RequestsMenu.itemCount;
-      info("Current requests: " + visibleRequestsCount + " of " + totalRequestsCount + ".");
-
-      if (!totalRequestsCount || !visibleRequestsCount) {
-        is(value, L10N.getStr("networkMenu.empty"),
-          "The current summary text is incorrect, expected an 'empty' label.");
-        return;
-      }
+    let visibleItems = RequestsMenu.visibleItems;
+    let visibleRequestsCount = visibleItems.length;
+    let totalRequestsCount = RequestsMenu.itemCount;
+    info("Current requests: " + visibleRequestsCount + " of " + totalRequestsCount + ".");
 
-      let totalBytes = RequestsMenu._getTotalBytesOfRequests(visibleItems);
-      let totalMillis =
-        RequestsMenu._getNewestRequest(visibleItems).attachment.endedMillis -
-        RequestsMenu._getOldestRequest(visibleItems).attachment.startedMillis;
-
-      info("Computed total bytes: " + totalBytes);
-      info("Computed total millis: " + totalMillis);
-
-      is(value, PluralForm.get(visibleRequestsCount, L10N.getStr("networkMenu.summary"))
-        .replace("#1", visibleRequestsCount)
-        .replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, 2))
-        .replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, 2))
-      , "The current summary text is incorrect.");
+    if (!totalRequestsCount || !visibleRequestsCount) {
+      is(value, L10N.getStr("networkMenu.empty"),
+        "The current summary text is incorrect, expected an 'empty' label.");
+      return;
     }
 
-    aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
-  });
-}
+    let totalBytes = RequestsMenu._getTotalBytesOfRequests(visibleItems);
+    let totalMillis =
+      RequestsMenu._getNewestRequest(visibleItems).attachment.endedMillis -
+      RequestsMenu._getOldestRequest(visibleItems).attachment.startedMillis;
+
+    info("Computed total bytes: " + totalBytes);
+    info("Computed total millis: " + totalMillis);
+
+    is(value, PluralForm.get(visibleRequestsCount, L10N.getStr("networkMenu.summary"))
+      .replace("#1", visibleRequestsCount)
+      .replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, 2))
+      .replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, 2))
+    , "The current summary text is incorrect.");
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_html-preview.js
+++ b/devtools/client/netmonitor/test/browser_net_html-preview.js
@@ -1,60 +1,62 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if html responses show and properly populate a "Preview" tab.
  */
 
-function test() {
-  initNetMonitor(CONTENT_TYPE_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(CONTENT_TYPE_URL);
+  info("Starting test... ");
 
-    let { $, document, EVENTS, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
+  let { $, document, EVENTS, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-    RequestsMenu.lazyUpdate = false;
+  RequestsMenu.lazyUpdate = false;
 
-    waitForNetworkEvents(aMonitor, 6).then(() => {
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.getElementById("details-pane-toggle"));
+  let wait = waitForNetworkEvents(monitor, 6);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
 
-      is($("#event-details-pane").selectedIndex, 0,
-        "The first tab in the details pane should be selected.");
-      is($("#preview-tab").hidden, true,
-        "The preview tab should be hidden for non html responses.");
-      is($("#preview-tabpanel").hidden, false,
-        "The preview tabpanel is not hidden for non html responses.");
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
 
-      RequestsMenu.selectedIndex = 4;
-      NetMonitorView.toggleDetailsPane({ visible: true, animated: false }, 6);
+  is($("#event-details-pane").selectedIndex, 0,
+    "The first tab in the details pane should be selected.");
+  is($("#preview-tab").hidden, true,
+    "The preview tab should be hidden for non html responses.");
+  is($("#preview-tabpanel").hidden, false,
+    "The preview tabpanel is not hidden for non html responses.");
 
-      is($("#event-details-pane").selectedIndex, 6,
-        "The sixth tab in the details pane should be selected.");
-      is($("#preview-tab").hidden, false,
-        "The preview tab should be visible now.");
+  RequestsMenu.selectedIndex = 4;
+  NetMonitorView.toggleDetailsPane({ visible: true, animated: false }, 6);
 
-      waitFor(aMonitor.panelWin, EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED).then(() => {
-        let iframe = $("#response-preview");
-        ok(iframe,
-          "There should be a response preview iframe available.");
-        ok(iframe.contentDocument,
-          "The iframe's content document should be available.");
-        is(iframe.contentDocument.querySelector("blink").textContent, "Not Found",
-          "The iframe's content document should be loaded and correct.");
+  is($("#event-details-pane").selectedIndex, 6,
+    "The sixth tab in the details pane should be selected.");
+  is($("#preview-tab").hidden, false,
+    "The preview tab should be visible now.");
 
-        RequestsMenu.selectedIndex = 5;
+  yield monitor.panelWin.once(EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED);
+  let iframe = $("#response-preview");
+  ok(iframe,
+    "There should be a response preview iframe available.");
+  ok(iframe.contentDocument,
+    "The iframe's content document should be available.");
+  is(iframe.contentDocument.querySelector("blink").textContent, "Not Found",
+    "The iframe's content document should be loaded and correct.");
 
-        is($("#event-details-pane").selectedIndex, 0,
-          "The first tab in the details pane should be selected again.");
-        is($("#preview-tab").hidden, true,
-          "The preview tab should be hidden again for non html responses.");
-        is($("#preview-tabpanel").hidden, false,
-          "The preview tabpanel is not hidden again for non html responses.");
+  RequestsMenu.selectedIndex = 5;
 
-        teardown(aMonitor).then(finish);
-      });
-    });
+  is($("#event-details-pane").selectedIndex, 0,
+    "The first tab in the details pane should be selected again.");
+  is($("#preview-tab").hidden, true,
+    "The preview tab should be hidden again for non html responses.");
+  is($("#preview-tabpanel").hidden, false,
+    "The preview tabpanel is not hidden again for non html responses.");
 
-    aDebuggee.performRequests();
-  });
-}
+  yield teardown(monitor);
+});
--- a/devtools/client/netmonitor/test/browser_net_icon-preview.js
+++ b/devtools/client/netmonitor/test/browser_net_icon-preview.js
@@ -1,61 +1,69 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if image responses show a thumbnail in the requests menu.
  */
 
-function test() {
-  initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
+  info("Starting test... ");
 
-    let { $, $all, EVENTS, ACTIVITY_TYPE, NetMonitorView, NetMonitorController } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
+  let { $, $all, EVENTS, ACTIVITY_TYPE, NetMonitorView, NetMonitorController } =
+    monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
+
+  let wait = waitForEvents();
+  yield performRequests();
+  yield wait;
 
-    promise.all([
-      waitForNetworkEvents(aMonitor, 7),
-      waitFor(aMonitor.panelWin, EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED)
-    ]).then(() => {
-      info("Checking the image thumbnail when all items are shown.");
-      checkImageThumbnail();
+  info("Checking the image thumbnail when all items are shown.");
+  checkImageThumbnail();
+
+  RequestsMenu.sortBy("size");
+  info("Checking the image thumbnail when all items are sorted.");
+  checkImageThumbnail();
 
-      RequestsMenu.sortBy("size");
-      info("Checking the image thumbnail when all items are sorted.");
-      checkImageThumbnail();
+  RequestsMenu.filterOn("images");
+  info("Checking the image thumbnail when only images are shown.");
+  checkImageThumbnail();
 
-      RequestsMenu.filterOn("images");
-      info("Checking the image thumbnail when only images are shown.");
-      checkImageThumbnail();
-
-      info("Reloading the debuggee and performing all requests again...");
-      reloadAndPerformRequests();
+  info("Reloading the debuggee and performing all requests again...");
+  wait = waitForEvents();
+  yield reloadAndPerformRequests();
+  yield wait;
 
-      return promise.all([
-        waitForNetworkEvents(aMonitor, 7), // 6 + 1
-        waitFor(aMonitor.panelWin, EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED)
-      ]);
-    }).then(() => {
-      info("Checking the image thumbnail after a reload.");
-      checkImageThumbnail();
+  info("Checking the image thumbnail after a reload.");
+  checkImageThumbnail();
+
+  yield teardown(monitor);
 
-      teardown(aMonitor).then(finish);
-    });
+  function waitForEvents() {
+    return promise.all([
+      waitForNetworkEvents(monitor, 7),
+      monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED)
+    ]);
+  }
 
-    function reloadAndPerformRequests() {
-      NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED).then(() => {
-        aDebuggee.performRequests();
-      });
-    }
+  function performRequests() {
+    return ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+      content.wrappedJSObject.performRequests();
+    });
+  }
 
-    function checkImageThumbnail() {
-      is($all(".requests-menu-icon[type=thumbnail]").length, 1,
-        "There should be only one image request with a thumbnail displayed.");
-      is($(".requests-menu-icon[type=thumbnail]").src, TEST_IMAGE_DATA_URI,
-        "The image requests-menu-icon thumbnail is displayed correctly.");
-      is($(".requests-menu-icon[type=thumbnail]").hidden, false,
-        "The image requests-menu-icon thumbnail should not be hidden.");
-    }
+  function* reloadAndPerformRequests() {
+    yield NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
+    yield performRequests();
+  }
 
-    aDebuggee.performRequests();
-  });
-}
+  function checkImageThumbnail() {
+    is($all(".requests-menu-icon[type=thumbnail]").length, 1,
+      "There should be only one image request with a thumbnail displayed.");
+    is($(".requests-menu-icon[type=thumbnail]").src, TEST_IMAGE_DATA_URI,
+      "The image requests-menu-icon thumbnail is displayed correctly.");
+    is($(".requests-menu-icon[type=thumbnail]").hidden, false,
+      "The image requests-menu-icon thumbnail should not be hidden.");
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_image-tooltip.js
+++ b/devtools/client/netmonitor/test/browser_net_image-tooltip.js
@@ -2,55 +2,60 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 /**
  * Tests if image responses show a popup in the requests menu when hovered.
  */
 add_task(function* test() {
-  let [, debuggee, monitor] = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
+  let [tab, , monitor] = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
   info("Starting test... ");
 
   let { $, EVENTS, ACTIVITY_TYPE, NetMonitorView, NetMonitorController } =
     monitor.panelWin;
   let { RequestsMenu } = NetMonitorView;
   RequestsMenu.lazyUpdate = true;
 
   let onEvents = waitForNetworkEvents(monitor, 7);
-  let onThumbnail = waitFor(monitor.panelWin, EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
+  let onThumbnail = monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
 
-  debuggee.performRequests();
+  yield performRequests();
   yield onEvents;
   yield onThumbnail;
 
   info("Checking the image thumbnail after a few requests were made...");
   yield showTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.items[5]);
 
   // 7 XHRs as before + 1 extra document reload
   onEvents = waitForNetworkEvents(monitor, 8);
-  onThumbnail = waitFor(monitor.panelWin, EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
+  onThumbnail = monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
 
   info("Reloading the debuggee and performing all requests again...");
   yield NetMonitorController.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
-  debuggee.performRequests();
+  yield performRequests();
   yield onEvents;
   yield onThumbnail;
 
   info("Checking the image thumbnail after a reload.");
   yield showTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.items[6]);
 
   info("Checking if the image thumbnail is hidden when mouse leaves the menu widget");
   let requestsMenuEl = $("#requests-menu-contents");
   let onHidden = RequestsMenu.tooltip.once("hidden");
   EventUtils.synthesizeMouse(requestsMenuEl, 0, 0, {type: "mouseout"}, monitor.panelWin);
   yield onHidden;
 
   yield teardown(monitor);
-  finish();
+
+  function performRequests() {
+    return ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+      content.wrappedJSObject.performRequests();
+    });
+  }
 
   /**
    * Show a tooltip on the {requestItem} and verify that it was displayed
    * with the expected content.
    */
   function* showTooltipAndVerify(tooltip, requestItem) {
     let anchor = $(".requests-menu-file", requestItem.target);
     yield showTooltipOn(tooltip, anchor);
--- a/devtools/client/netmonitor/test/browser_net_json-long.js
+++ b/devtools/client/netmonitor/test/browser_net_json-long.js
@@ -1,91 +1,96 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if very long JSON responses are handled correctly.
  */
 
-function test() {
-  initNetMonitor(JSON_LONG_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
-
-    // This is receiving over 80 KB of json and will populate over 6000 items
-    // in a variables view instance. Debug builds are slow.
-    requestLongerTimeout(4);
-
-    let { document, L10N, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
-
-    RequestsMenu.lazyUpdate = false;
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(JSON_LONG_URL);
+  info("Starting test... ");
 
-    waitForNetworkEvents(aMonitor, 1).then(() => {
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
-        "GET", CONTENT_TYPE_SJS + "?fmt=json-long", {
-          status: 200,
-          statusText: "OK",
-          type: "json",
-          fullMimeType: "text/json; charset=utf-8",
-          size: L10N.getFormatStr("networkMenu.sizeKB", L10N.numberWithDecimals(85975 / 1024, 2)),
-          time: true
-        });
+  // This is receiving over 80 KB of json and will populate over 6000 items
+  // in a variables view instance. Debug builds are slow.
+  requestLongerTimeout(4);
 
-      aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED, () => {
-        testResponseTab();
-        teardown(aMonitor).then(finish);
-      });
+  let { document, EVENTS, L10N, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.getElementById("details-pane-toggle"));
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.querySelectorAll("#details-pane tab")[3]);
-
-      function testResponseTab() {
-        let tab = document.querySelectorAll("#details-pane tab")[3];
-        let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+  RequestsMenu.lazyUpdate = false;
 
-        is(tab.getAttribute("selected"), "true",
-          "The response tab in the network details pane should be selected.");
-
-        is(tabpanel.querySelector("#response-content-info-header")
-          .hasAttribute("hidden"), true,
-          "The response info header doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-json-box")
-          .hasAttribute("hidden"), false,
-          "The response content json box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-textarea-box")
-          .hasAttribute("hidden"), true,
-          "The response content textarea box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-image-box")
-          .hasAttribute("hidden"), true,
-          "The response content image box doesn't have the intended visibility.");
+  let wait = waitForNetworkEvents(monitor, 1);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
 
-        is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-          "There should be 1 json scope displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-property").length, 6143,
-          "There should be 6143 json properties displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
-          "The empty notice should not be displayed in this tabpanel.");
-
-        let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-        let names = ".variables-view-property > .title > .name";
-        let values = ".variables-view-property > .title > .value";
-
-        is(jsonScope.querySelector(".name").getAttribute("value"),
-          L10N.getStr("jsonScopeName"),
-          "The json scope doesn't have the correct title.");
-
-        is(jsonScope.querySelectorAll(names)[0].getAttribute("value"),
-          "0", "The first json property name was incorrect.");
-        is(jsonScope.querySelectorAll(values)[0].getAttribute("value"),
-          "Object", "The first json property value was incorrect.");
-
-        is(jsonScope.querySelectorAll(names)[1].getAttribute("value"),
-          "greeting", "The second json property name was incorrect.");
-        is(jsonScope.querySelectorAll(values)[1].getAttribute("value"),
-          "\"Hello long string JSON!\"", "The second json property value was incorrect.");
-      }
+  verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
+    "GET", CONTENT_TYPE_SJS + "?fmt=json-long", {
+      status: 200,
+      statusText: "OK",
+      type: "json",
+      fullMimeType: "text/json; charset=utf-8",
+      size: L10N.getFormatStr("networkMenu.sizeKB",
+        L10N.numberWithDecimals(85975 / 1024, 2)),
+      time: true
     });
 
-    aDebuggee.performRequests();
-  });
-}
+  let onEvent = monitor.panelWin.once(EVENTS.RESPONSE_BODY_DISPLAYED);
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[3]);
+  yield onEvent;
+
+  testResponseTab();
+
+  yield teardown(monitor);
+
+  function testResponseTab() {
+    let tabEl = document.querySelectorAll("#details-pane tab")[3];
+    let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+
+    is(tabEl.getAttribute("selected"), "true",
+      "The response tab in the network details pane should be selected.");
+
+    is(tabpanel.querySelector("#response-content-info-header")
+      .hasAttribute("hidden"), true,
+      "The response info header doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-json-box")
+      .hasAttribute("hidden"), false,
+      "The response content json box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-textarea-box")
+      .hasAttribute("hidden"), true,
+      "The response content textarea box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-image-box")
+      .hasAttribute("hidden"), true,
+      "The response content image box doesn't have the intended visibility.");
+
+    is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
+      "There should be 1 json scope displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-property").length, 6143,
+      "There should be 6143 json properties displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+      "The empty notice should not be displayed in this tabpanel.");
+
+    let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
+    let names = ".variables-view-property > .title > .name";
+    let values = ".variables-view-property > .title > .value";
+
+    is(jsonScope.querySelector(".name").getAttribute("value"),
+      L10N.getStr("jsonScopeName"),
+      "The json scope doesn't have the correct title.");
+
+    is(jsonScope.querySelectorAll(names)[0].getAttribute("value"),
+      "0", "The first json property name was incorrect.");
+    is(jsonScope.querySelectorAll(values)[0].getAttribute("value"),
+      "Object", "The first json property value was incorrect.");
+
+    is(jsonScope.querySelectorAll(names)[1].getAttribute("value"),
+      "greeting", "The second json property name was incorrect.");
+    is(jsonScope.querySelectorAll(values)[1].getAttribute("value"),
+      "\"Hello long string JSON!\"", "The second json property value was incorrect.");
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_json-malformed.js
+++ b/devtools/client/netmonitor/test/browser_net_json-malformed.js
@@ -1,74 +1,77 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if malformed JSON responses are handled correctly.
  */
 
-function test() {
-  initNetMonitor(JSON_MALFORMED_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
-
-    let { document, Editor, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
-
-    RequestsMenu.lazyUpdate = false;
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(JSON_MALFORMED_URL);
+  info("Starting test... ");
 
-    waitForNetworkEvents(aMonitor, 1).then(() => {
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
-        "GET", CONTENT_TYPE_SJS + "?fmt=json-malformed", {
-          status: 200,
-          statusText: "OK",
-          type: "json",
-          fullMimeType: "text/json; charset=utf-8"
-        });
+  let { document, EVENTS, Editor, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.getElementById("details-pane-toggle"));
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.querySelectorAll("#details-pane tab")[3]);
-
-      let tab = document.querySelectorAll("#details-pane tab")[3];
-      let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
-
-      let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
-      waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED).then(() => {
-        is(tab.getAttribute("selected"), "true",
-          "The response tab in the network details pane should be selected.");
+  RequestsMenu.lazyUpdate = false;
 
-        is(tabpanel.querySelector("#response-content-info-header")
-          .hasAttribute("hidden"), false,
-          "The response info header doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-info-header")
-          .getAttribute("value"),
-          "SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 40 of the JSON data",
-          "The response info header doesn't have the intended value attribute.");
-        is(tabpanel.querySelector("#response-content-info-header")
-          .getAttribute("tooltiptext"),
-          "SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 40 of the JSON data",
-          "The response info header doesn't have the intended tooltiptext attribute.");
+  let wait = waitForNetworkEvents(monitor, 1);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
 
-        is(tabpanel.querySelector("#response-content-json-box")
-          .hasAttribute("hidden"), true,
-          "The response content json box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-textarea-box")
-          .hasAttribute("hidden"), false,
-          "The response content textarea box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-image-box")
-          .hasAttribute("hidden"), true,
-          "The response content image box doesn't have the intended visibility.");
-
-        NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
-          is(aEditor.getText(), "{ \"greeting\": \"Hello malformed JSON!\" },",
-            "The text shown in the source editor is incorrect.");
-          is(aEditor.getMode(), Editor.modes.js,
-            "The mode active in the source editor is incorrect.");
-
-          teardown(aMonitor).then(finish);
-        });
-      });
+  verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
+    "GET", CONTENT_TYPE_SJS + "?fmt=json-malformed", {
+      status: 200,
+      statusText: "OK",
+      type: "json",
+      fullMimeType: "text/json; charset=utf-8"
     });
 
-    aDebuggee.performRequests();
-  });
-}
+  let onEvent = monitor.panelWin.once(EVENTS.RESPONSE_BODY_DISPLAYED);
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[3]);
+  yield onEvent;
+
+  let tabEl = document.querySelectorAll("#details-pane tab")[3];
+  let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+
+  is(tabEl.getAttribute("selected"), "true",
+    "The response tab in the network details pane should be selected.");
+
+  is(tabpanel.querySelector("#response-content-info-header")
+    .hasAttribute("hidden"), false,
+    "The response info header doesn't have the intended visibility.");
+  is(tabpanel.querySelector("#response-content-info-header")
+    .getAttribute("value"),
+    "SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data" +
+      " at line 1 column 40 of the JSON data",
+    "The response info header doesn't have the intended value attribute.");
+  is(tabpanel.querySelector("#response-content-info-header")
+    .getAttribute("tooltiptext"),
+    "SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data" +
+      " at line 1 column 40 of the JSON data",
+    "The response info header doesn't have the intended tooltiptext attribute.");
+
+  is(tabpanel.querySelector("#response-content-json-box")
+    .hasAttribute("hidden"), true,
+    "The response content json box doesn't have the intended visibility.");
+  is(tabpanel.querySelector("#response-content-textarea-box")
+    .hasAttribute("hidden"), false,
+    "The response content textarea box doesn't have the intended visibility.");
+  is(tabpanel.querySelector("#response-content-image-box")
+    .hasAttribute("hidden"), true,
+    "The response content image box doesn't have the intended visibility.");
+
+  let editor = yield NetMonitorView.editor("#response-content-textarea");
+  is(editor.getText(), "{ \"greeting\": \"Hello malformed JSON!\" },",
+    "The text shown in the source editor is incorrect.");
+  is(editor.getMode(), Editor.modes.js,
+    "The mode active in the source editor is incorrect.");
+
+  yield teardown(monitor);
+});
--- a/devtools/client/netmonitor/test/browser_net_json_custom_mime.js
+++ b/devtools/client/netmonitor/test/browser_net_json_custom_mime.js
@@ -1,81 +1,88 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if JSON responses with unusal/custom MIME types are handled correctly.
  */
 
-function test() {
-  initNetMonitor(JSON_CUSTOM_MIME_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
-
-    let { document, L10N, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
-
-    RequestsMenu.lazyUpdate = false;
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(JSON_CUSTOM_MIME_URL);
+  info("Starting test... ");
 
-    waitForNetworkEvents(aMonitor, 1).then(() => {
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
-        "GET", CONTENT_TYPE_SJS + "?fmt=json-custom-mime", {
-          status: 200,
-          statusText: "OK",
-          type: "x-bigcorp-json",
-          fullMimeType: "text/x-bigcorp-json; charset=utf-8",
-          size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
-          time: true
-        });
+  let { document, EVENTS, L10N, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.getElementById("details-pane-toggle"));
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.querySelectorAll("#details-pane tab")[3]);
-
-      let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
-      waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED)
-        .then(testResponseTab)
-        .then(() => teardown(aMonitor))
-        .then(finish);
-
-      function testResponseTab() {
-        let tab = document.querySelectorAll("#details-pane tab")[3];
-        let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+  RequestsMenu.lazyUpdate = false;
 
-        is(tab.getAttribute("selected"), "true",
-          "The response tab in the network details pane should be selected.");
-
-        is(tabpanel.querySelector("#response-content-info-header")
-          .hasAttribute("hidden"), true,
-          "The response info header doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-json-box")
-          .hasAttribute("hidden"), false,
-          "The response content json box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-textarea-box")
-          .hasAttribute("hidden"), true,
-          "The response content textarea box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-image-box")
-          .hasAttribute("hidden"), true,
-          "The response content image box doesn't have the intended visibility.");
+  let wait = waitForNetworkEvents(monitor, 1);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
 
-        is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-          "There should be 1 json scope displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
-          "There should be 2 json properties displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
-          "The empty notice should not be displayed in this tabpanel.");
-
-        let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-        is(jsonScope.querySelectorAll(".variables-view-property .name")[0].getAttribute("value"),
-          "greeting", "The first json property name was incorrect.");
-        is(jsonScope.querySelectorAll(".variables-view-property .value")[0].getAttribute("value"),
-          "\"Hello oddly-named JSON!\"", "The first json property value was incorrect.");
-
-        is(jsonScope.querySelectorAll(".variables-view-property .name")[1].getAttribute("value"),
-          "__proto__", "The second json property name was incorrect.");
-        is(jsonScope.querySelectorAll(".variables-view-property .value")[1].getAttribute("value"),
-          "Object", "The second json property value was incorrect.");
-      }
+  verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
+    "GET", CONTENT_TYPE_SJS + "?fmt=json-custom-mime", {
+      status: 200,
+      statusText: "OK",
+      type: "x-bigcorp-json",
+      fullMimeType: "text/x-bigcorp-json; charset=utf-8",
+      size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
+      time: true
     });
 
-    aDebuggee.performRequests();
-  });
-}
+  let onEvent = monitor.panelWin.once(EVENTS.RESPONSE_BODY_DISPLAYED);
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[3]);
+  yield onEvent;
+
+  testResponseTab();
+
+  yield teardown(monitor);
+
+  function testResponseTab() {
+    let tabEl = document.querySelectorAll("#details-pane tab")[3];
+    let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+
+    is(tabEl.getAttribute("selected"), "true",
+      "The response tab in the network details pane should be selected.");
+
+    is(tabpanel.querySelector("#response-content-info-header")
+      .hasAttribute("hidden"), true,
+      "The response info header doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-json-box")
+      .hasAttribute("hidden"), false,
+      "The response content json box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-textarea-box")
+      .hasAttribute("hidden"), true,
+      "The response content textarea box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-image-box")
+      .hasAttribute("hidden"), true,
+      "The response content image box doesn't have the intended visibility.");
+
+    is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
+      "There should be 1 json scope displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
+      "There should be 2 json properties displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+      "The empty notice should not be displayed in this tabpanel.");
+
+    let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
+    is(jsonScope.querySelectorAll(".variables-view-property .name")[0]
+      .getAttribute("value"),
+      "greeting", "The first json property name was incorrect.");
+    is(jsonScope.querySelectorAll(".variables-view-property .value")[0]
+      .getAttribute("value"),
+      "\"Hello oddly-named JSON!\"", "The first json property value was incorrect.");
+
+    is(jsonScope.querySelectorAll(".variables-view-property .name")[1]
+      .getAttribute("value"),
+      "__proto__", "The second json property name was incorrect.");
+    is(jsonScope.querySelectorAll(".variables-view-property .value")[1]
+      .getAttribute("value"),
+      "Object", "The second json property value was incorrect.");
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_json_text_mime.js
+++ b/devtools/client/netmonitor/test/browser_net_json_text_mime.js
@@ -1,81 +1,88 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if JSON responses with unusal/custom MIME types are handled correctly.
  */
 
-function test() {
-  initNetMonitor(JSON_TEXT_MIME_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
-
-    let { document, L10N, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu } = NetMonitorView;
-
-    RequestsMenu.lazyUpdate = false;
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(JSON_TEXT_MIME_URL);
+  info("Starting test... ");
 
-    waitForNetworkEvents(aMonitor, 1).then(() => {
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
-        "GET", CONTENT_TYPE_SJS + "?fmt=json-text-mime", {
-          status: 200,
-          statusText: "OK",
-          type: "plain",
-          fullMimeType: "text/plain; charset=utf-8",
-          size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
-          time: true
-        });
+  let { document, EVENTS, L10N, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu } = NetMonitorView;
 
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.getElementById("details-pane-toggle"));
-      EventUtils.sendMouseEvent({ type: "mousedown" },
-        document.querySelectorAll("#details-pane tab")[3]);
-
-      let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
-      waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED)
-        .then(testResponseTab)
-        .then(() => teardown(aMonitor))
-        .then(finish);
-
-      function testResponseTab() {
-        let tab = document.querySelectorAll("#details-pane tab")[3];
-        let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+  RequestsMenu.lazyUpdate = false;
 
-        is(tab.getAttribute("selected"), "true",
-          "The response tab in the network details pane should be selected.");
-
-        is(tabpanel.querySelector("#response-content-info-header")
-          .hasAttribute("hidden"), true,
-          "The response info header doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-json-box")
-          .hasAttribute("hidden"), false,
-          "The response content json box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-textarea-box")
-          .hasAttribute("hidden"), true,
-          "The response content textarea box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-image-box")
-          .hasAttribute("hidden"), true,
-          "The response content image box doesn't have the intended visibility.");
+  let wait = waitForNetworkEvents(monitor, 1);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
 
-        is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-          "There should be 1 json scope displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
-          "There should be 2 json properties displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
-          "The empty notice should not be displayed in this tabpanel.");
-
-        let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-        is(jsonScope.querySelectorAll(".variables-view-property .name")[0].getAttribute("value"),
-          "greeting", "The first json property name was incorrect.");
-        is(jsonScope.querySelectorAll(".variables-view-property .value")[0].getAttribute("value"),
-          "\"Hello third-party JSON!\"", "The first json property value was incorrect.");
-
-        is(jsonScope.querySelectorAll(".variables-view-property .name")[1].getAttribute("value"),
-          "__proto__", "The second json property name was incorrect.");
-        is(jsonScope.querySelectorAll(".variables-view-property .value")[1].getAttribute("value"),
-          "Object", "The second json property value was incorrect.");
-      }
+  verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
+    "GET", CONTENT_TYPE_SJS + "?fmt=json-text-mime", {
+      status: 200,
+      statusText: "OK",
+      type: "plain",
+      fullMimeType: "text/plain; charset=utf-8",
+      size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
+      time: true
     });
 
-    aDebuggee.performRequests();
-  });
-}
+  let onEvent = monitor.panelWin.once(EVENTS.RESPONSE_BODY_DISPLAYED);
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[3]);
+  yield onEvent;
+
+  testResponseTab();
+
+  yield teardown(monitor);
+
+  function testResponseTab() {
+    let tabEl = document.querySelectorAll("#details-pane tab")[3];
+    let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+
+    is(tabEl.getAttribute("selected"), "true",
+      "The response tab in the network details pane should be selected.");
+
+    is(tabpanel.querySelector("#response-content-info-header")
+      .hasAttribute("hidden"), true,
+      "The response info header doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-json-box")
+      .hasAttribute("hidden"), false,
+      "The response content json box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-textarea-box")
+      .hasAttribute("hidden"), true,
+      "The response content textarea box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-image-box")
+      .hasAttribute("hidden"), true,
+      "The response content image box doesn't have the intended visibility.");
+
+    is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
+      "There should be 1 json scope displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
+      "There should be 2 json properties displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+      "The empty notice should not be displayed in this tabpanel.");
+
+    let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
+    is(jsonScope.querySelectorAll(".variables-view-property .name")[0]
+      .getAttribute("value"),
+      "greeting", "The first json property name was incorrect.");
+    is(jsonScope.querySelectorAll(".variables-view-property .value")[0]
+      .getAttribute("value"),
+      "\"Hello third-party JSON!\"", "The first json property value was incorrect.");
+
+    is(jsonScope.querySelectorAll(".variables-view-property .name")[1]
+      .getAttribute("value"),
+      "__proto__", "The second json property name was incorrect.");
+    is(jsonScope.querySelectorAll(".variables-view-property .value")[1]
+      .getAttribute("value"),
+      "Object", "The second json property value was incorrect.");
+  }
+});
--- a/devtools/client/netmonitor/test/browser_net_jsonp.js
+++ b/devtools/client/netmonitor/test/browser_net_jsonp.js
@@ -1,105 +1,109 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+"use strict";
+
 /**
  * Tests if JSONP responses are handled correctly.
  */
 
-function test() {
-  initNetMonitor(JSONP_URL).then(([aTab, aDebuggee, aMonitor]) => {
-    info("Starting test... ");
+add_task(function* () {
+  let [tab, , monitor] = yield initNetMonitor(JSONP_URL);
+  info("Starting test... ");
 
-    let { document, L10N, NetMonitorView } = aMonitor.panelWin;
-    let { RequestsMenu, NetworkDetails } = NetMonitorView;
-
-    RequestsMenu.lazyUpdate = false;
-    NetworkDetails._json.lazyEmpty = false;
+  let { document, EVENTS, L10N, NetMonitorView } = monitor.panelWin;
+  let { RequestsMenu, NetworkDetails } = NetMonitorView;
 
-    waitForNetworkEvents(aMonitor, 2).then(() => {
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
-        "GET", CONTENT_TYPE_SJS + "?fmt=jsonp&jsonp=$_0123Fun", {
-          status: 200,
-          statusText: "OK",
-          type: "json",
-          fullMimeType: "text/json; charset=utf-8",
-          size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
-          time: true
-        });
-      verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
-        "GET", CONTENT_TYPE_SJS + "?fmt=jsonp2&jsonp=$_4567Sad", {
-          status: 200,
-          statusText: "OK",
-          type: "json",
-          fullMimeType: "text/json; charset=utf-8",
-          size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 54),
-          time: true
-        });
+  RequestsMenu.lazyUpdate = false;
+  NetworkDetails._json.lazyEmpty = false;
 
-      Task.spawn(function* () {
-        let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
-
-        EventUtils.sendMouseEvent({ type: "mousedown" },
-          document.getElementById("details-pane-toggle"));
-        EventUtils.sendMouseEvent({ type: "mousedown" },
-          document.querySelectorAll("#details-pane tab")[3]);
-
-        yield waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED);
-        testResponseTab("$_0123Fun", "\"Hello JSONP!\"");
-
-        RequestsMenu.selectedIndex = 1;
-
-        yield waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED);
-        testResponseTab("$_4567Sad", "\"Hello weird JSONP!\"");
+  let wait = waitForNetworkEvents(monitor, 2);
+  yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+    content.wrappedJSObject.performRequests();
+  });
+  yield wait;
 
-        yield teardown(aMonitor);
-        finish();
-      });
-
-      function testResponseTab(aFunction, aGreeting) {
-        let tab = document.querySelectorAll("#details-pane tab")[3];
-        let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
-
-        is(tab.getAttribute("selected"), "true",
-          "The response tab in the network details pane should be selected.");
-
-        is(tabpanel.querySelector("#response-content-info-header")
-          .hasAttribute("hidden"), true,
-          "The response info header doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-json-box")
-          .hasAttribute("hidden"), false,
-          "The response content json box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-textarea-box")
-          .hasAttribute("hidden"), true,
-          "The response content textarea box doesn't have the intended visibility.");
-        is(tabpanel.querySelector("#response-content-image-box")
-          .hasAttribute("hidden"), true,
-          "The response content image box doesn't have the intended visibility.");
-
-        is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
-          "There should be 1 json scope displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
-          "There should be 2 json properties displayed in this tabpanel.");
-        is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
-          "The empty notice should not be displayed in this tabpanel.");
-
-        let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
-
-        is(jsonScope.querySelector(".name").getAttribute("value"),
-          L10N.getFormatStr("jsonpScopeName", aFunction),
-          "The json scope doesn't have the correct title.");
-
-        is(jsonScope.querySelectorAll(".variables-view-property .name")[0].getAttribute("value"),
-          "greeting", "The first json property name was incorrect.");
-        is(jsonScope.querySelectorAll(".variables-view-property .value")[0].getAttribute("value"),
-          aGreeting, "The first json property value was incorrect.");
-
-        is(jsonScope.querySelectorAll(".variables-view-property .name")[1].getAttribute("value"),
-          "__proto__", "The second json property name was incorrect.");
-        is(jsonScope.querySelectorAll(".variables-view-property .value")[1].getAttribute("value"),
-          "Object", "The second json property value was incorrect.");
-      }
+  verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
+    "GET", CONTENT_TYPE_SJS + "?fmt=jsonp&jsonp=$_0123Fun", {
+      status: 200,
+      statusText: "OK",
+      type: "json",
+      fullMimeType: "text/json; charset=utf-8",
+      size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 41),
+      time: true
+    });
+  verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
+    "GET", CONTENT_TYPE_SJS + "?fmt=jsonp2&jsonp=$_4567Sad", {
+      status: 200,
+      statusText: "OK",
+      type: "json",
+      fullMimeType: "text/json; charset=utf-8",
+      size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 54),
+      time: true
     });
 
-    aDebuggee.performRequests();
-  });
-}
+  let onEvent = monitor.panelWin.once(EVENTS.RESPONSE_BODY_DISPLAYED);
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.getElementById("details-pane-toggle"));
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    document.querySelectorAll("#details-pane tab")[3]);
+  yield onEvent;
+
+  testResponseTab("$_0123Fun", "\"Hello JSONP!\"");
+
+  onEvent = monitor.panelWin.once(EVENTS.RESPONSE_BODY_DISPLAYED);
+  RequestsMenu.selectedIndex = 1;
+  yield onEvent;
+
+  testResponseTab("$_4567Sad", "\"Hello weird JSONP!\"");
+
+  yield teardown(monitor);
+
+  function testResponseTab(func, greeting) {
+    let tabEl = document.querySelectorAll("#details-pane tab")[3];
+    let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
+
+    is(tabEl.getAttribute("selected"), "true",
+      "The response tab in the network details pane should be selected.");
+
+    is(tabpanel.querySelector("#response-content-info-header")
+      .hasAttribute("hidden"), true,
+      "The response info header doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-json-box")
+      .hasAttribute("hidden"), false,
+      "The response content json box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-textarea-box")
+      .hasAttribute("hidden"), true,
+      "The response content textarea box doesn't have the intended visibility.");
+    is(tabpanel.querySelector("#response-content-image-box")
+      .hasAttribute("hidden"), true,
+      "The response content image box doesn't have the intended visibility.");
+
+    is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
+      "There should be 1 json scope displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
+      "There should be 2 json properties displayed in this tabpanel.");
+    is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
+      "The empty notice should not be displayed in this tabpanel.");
+
+    let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
+
+    is(jsonScope.querySelector(".name").getAttribute("value"),
+      L10N.getFormatStr("jsonpScopeName", func),
+      "The json scope doesn't have the correct title.");
+
+    is(jsonScope.querySelectorAll(".variables-view-property .name")[0]
+      .getAttribute("value"),
+      "greeting", "The first json property name was incorrect.");
+    is(jsonScope.querySelectorAll(".variables-view-property .value")[0]
+      .getAttribute("value"),
+      greeting, "The first json property value was incorrect.");
+
+    is(jsonScope.querySelectorAll(".variables-view-property .name")[1]
+      .getAttribute("value"),
+      "__proto__", "The second json property name was incorrect.");
+    is(jsonScope.querySelectorAll(".variables-view-property .value")[1]
+      .getAttribute("value"),
+      "Object", "The second json property value was incorrect.");
+  }
+});