Browse Source

Some devtool backports

Ian Neal 10 months ago
parent
commit
8d873ef341

+ 225 - 0
mozilla-release/patches/1248498-60a1.patch

@@ -0,0 +1,225 @@
+# HG changeset patch
+# User J. Ryan Stinnett <jryans@gmail.com>
+# Date 1519868934 21600
+# Node ID f0a37e1760649e4af7949045f1afaa3095817267
+# Parent  65eabe9f1c84bf145571181f6c902b7b28d14676
+Bug 1248498 - Check document cache status when loading HTML sources. r=jlast
+
+When getting the source for inline scripts in documents, we generally try to use
+the cache.  However, the toolbox allows you to disable the HTTP cache while open
+if you wish.
+
+If the toolbox has disabled the cache, using `fetchFromCache: true` will give
+stale data (from the most recent cache-enabled request).
+
+We can avoid stale data here by checking the document's cache state.
+
+MozReview-Commit-ID: J5SJciSyQNj
+
+diff --git a/devtools/client/debugger/new/test/mochitest/browser.ini b/devtools/client/debugger/new/test/mochitest/browser.ini
+--- a/devtools/client/debugger/new/test/mochitest/browser.ini
++++ b/devtools/client/debugger/new/test/mochitest/browser.ini
+@@ -137,16 +137,17 @@ skip-if = !e10s # This test is only vali
+ [browser_dbg-content-script-sources.js]
+ [browser_dbg-debugger-buttons.js]
+ [browser_dbg-editor-gutter.js]
+ [browser_dbg-editor-select.js]
+ [browser_dbg-editor-highlight.js]
+ [browser_dbg-expressions.js]
+ [browser_dbg-expressions-error.js]
+ [browser_dbg-iframes.js]
++[browser_dbg-inline-cache.js]
+ [browser_dbg-keyboard-navigation.js]
+ [browser_dbg-keyboard-shortcuts.js]
+ skip-if = os == "linux" # bug 1351952
+ [browser_dbg-layout-changes.js]
+ [browser_dbg-outline.js]
+ [browser_dbg-pause-exceptions.js]
+ [browser_dbg-pause-ux.js]
+ skip-if = os == "win"
+diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg-inline-cache.js b/devtools/client/debugger/new/test/mochitest/browser_dbg-inline-cache.js
+new file mode 100644
+--- /dev/null
++++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-inline-cache.js
+@@ -0,0 +1,132 @@
++/* Any copyright is dedicated to the Public Domain.
++ http://creativecommons.org/publicdomain/zero/1.0/ */
++
++"use strict";
++
++/*
++ * Test loading inline scripts from cache:
++ *   - Load document with inline script
++ *   - Reload inside debugger with toolbox caching disabled
++ *   - Reload inside debugger with toolbox caching enabled
++ */
++
++const server = createTestHTTPServer();
++
++let docValue = 1;
++server.registerPathHandler("/inline-cache.html", (request, response) => {
++  response.setHeader("Content-Type", "text/html");
++  // HTTP should assume cacheable by default.
++  // Toolbox defaults to disabling cache for subsequent loads when open.
++  response.setHeader("Cache-Control", "public, max-age=3600");
++  response.write(`
++    <html>
++    <head>
++    <script>
++      let x = ${docValue};
++    </script>
++    </head>
++    </html>
++  `);
++});
++
++const SOURCE_URL = `http://localhost:${server.identity.primaryPort}/inline-cache.html`;
++
++/**
++ * This is meant to simulate the developer editing the inline source and saving.
++ * Effectively, we change the source during the test at specific controlled points.
++ */
++function makeChanges() {
++  docValue++;
++}
++
++function getPageValue(tab) {
++  return ContentTask.spawn(tab.linkedBrowser, {}, function () {
++    return content.document.querySelector("script").textContent.trim();
++  });
++}
++
++async function reloadTabAndDebugger(tab, dbg) {
++  let navigated = waitForDispatch(dbg, "NAVIGATE");
++  let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
++  await reload(dbg, "inline-cache.html");
++  return Promise.all([ navigated, loaded ]);
++}
++
++add_task(async function () {
++  info("Load document with inline script");
++  const tab = await addTab(SOURCE_URL);
++  info("Open debugger");
++  clearDebuggerPreferences();
++  const toolbox = await openToolboxForTab(tab, "jsdebugger");
++  const dbg = createDebuggerContext(toolbox);
++  info("Reload tab to ensure debugger finds script");
++  await reloadTabAndDebugger(tab, dbg);
++  let pageValue = await getPageValue(tab);
++  is(pageValue, "let x = 1;", "Content loads from network, has doc value 1");
++  await waitForSource(dbg, "inline-cache.html");
++  await selectSource(dbg, "inline-cache.html");
++  await waitForLoadedSource(dbg, "inline-cache.html");
++  let dbgValue = await findSource(dbg, "inline-cache.html");
++  info(`Debugger text: ${dbgValue.text}`);
++  ok(dbgValue.text.includes(pageValue),
++     "Debugger loads from cache, gets value 1 like page");
++
++  info("Disable HTTP cache for page");
++  await toolbox.target.activeTab.reconfigure({ cacheDisabled: true });
++  makeChanges();
++
++  info("Reload inside debugger with toolbox caching disabled (attempt 1)");
++  await reloadTabAndDebugger(tab, dbg);
++  pageValue = await getPageValue(tab);
++  is(pageValue, "let x = 2;", "Content loads from network, has doc value 2");
++  await waitForLoadedSource(dbg, "inline-cache.html");
++  dbgValue = await findSource(dbg, "inline-cache.html");
++  info(`Debugger text: ${dbgValue.text}`);
++  ok(dbgValue.text.includes(pageValue),
++     "Debugger loads from network, gets value 2 like page");
++
++  makeChanges();
++
++  info("Reload inside debugger with toolbox caching disabled (attempt 2)");
++  await reloadTabAndDebugger(tab, dbg);
++  pageValue = await getPageValue(tab);
++  is(pageValue, "let x = 3;", "Content loads from network, has doc value 3");
++  await waitForLoadedSource(dbg, "inline-cache.html");
++  dbgValue = await findSource(dbg, "inline-cache.html");
++  info(`Debugger text: ${dbgValue.text}`);
++  ok(dbgValue.text.includes(pageValue),
++     "Debugger loads from network, gets value 3 like page");
++
++  info("Enable HTTP cache for page");
++  await toolbox.target.activeTab.reconfigure({ cacheDisabled: false });
++  makeChanges();
++
++  // Even though the HTTP cache is now enabled, Gecko sets the VALIDATE_ALWAYS flag when
++  // reloading the page.  So, it will always make a request to the server for the main
++  // document contents.
++
++  info("Reload inside debugger with toolbox caching enabled (attempt 1)");
++  await reloadTabAndDebugger(tab, dbg);
++  pageValue = await getPageValue(tab);
++  is(pageValue, "let x = 4;", "Content loads from network, has doc value 4");
++  await waitForLoadedSource(dbg, "inline-cache.html");
++  dbgValue = await findSource(dbg, "inline-cache.html");
++  info(`Debugger text: ${dbgValue.text}`);
++  ok(dbgValue.text.includes(pageValue),
++     "Debugger loads from cache, gets value 4 like page");
++
++  makeChanges();
++
++  info("Reload inside debugger with toolbox caching enabled (attempt 2)");
++  await reloadTabAndDebugger(tab, dbg);
++  pageValue = await getPageValue(tab);
++  is(pageValue, "let x = 5;", "Content loads from network, has doc value 5");
++  await waitForLoadedSource(dbg, "inline-cache.html");
++  dbgValue = await findSource(dbg, "inline-cache.html");
++  info(`Debugger text: ${dbgValue.text}`);
++  ok(dbgValue.text.includes(pageValue),
++     "Debugger loads from cache, gets value 5 like page");
++
++  await toolbox.destroy();
++  await removeTab(tab);
++});
+diff --git a/devtools/server/actors/source.js b/devtools/server/actors/source.js
+--- a/devtools/server/actors/source.js
++++ b/devtools/server/actors/source.js
+@@ -207,16 +207,23 @@ let SourceActor = ActorClassWithSpec(sou
+   get addonPath() {
+     return this._addonPath;
+   },
+ 
+   get prettyPrintWorker() {
+     return this.threadActor.prettyPrintWorker;
+   },
+ 
++  get isCacheEnabled() {
++    if (this.threadActor._parent._getCacheDisabled) {
++      return !this.threadActor._parent._getCacheDisabled();
++    }
++    return true;
++  },
++
+   form: function () {
+     let source = this.source || this.generatedSource;
+     // This might not have a source or a generatedSource because we
+     // treat HTML pages with inline scripts as a special SourceActor
+     // that doesn't have either
+     let introductionUrl = null;
+     if (source && source.introductionScript) {
+       introductionUrl = source.introductionScript.source.url;
+@@ -371,17 +378,20 @@ let SourceActor = ActorClassWithSpec(sou
+       }
+ 
+       // Only load the HTML page source from cache (which exists when
+       // there are inline sources). Otherwise, we can't trust the
+       // cache because we are most likely here because we are
+       // fetching the original text for sourcemapped code, and the
+       // page hasn't requested it before (if it has, it was a
+       // previous debugging session).
+-      let loadFromCache = this.isInlineSource;
++      // Additionally, we should only try the cache if it is currently enabled
++      // for the document.  Without this check, the cache may return stale data
++      // that doesn't match the document shown in the browser.
++      let loadFromCache = this.isInlineSource && this.isCacheEnabled;
+ 
+       // Fetch the sources with the same principal as the original document
+       let win = this.threadActor._parent.window;
+       let principal, cacheKey;
+       // On xpcshell, we don't have a window but a Sandbox
+       if (!isWorker && win instanceof Ci.nsIDOMWindow) {
+         let webNav = win.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIWebNavigation);

+ 72 - 0
mozilla-release/patches/1422061-59a1.patch

@@ -0,0 +1,72 @@
+# HG changeset patch
+# User Alexandre Poirot <poirot.alex@gmail.com>
+# Date 1516119990 28800
+# Node ID cccd776a80d97621554ed046072bc7ea3dc0bdad
+# Parent  8745bd1cf5d365a959014e9b6405b23784b68414
+Bug 1422061 - Prevent performance actor from stopping profiler started by Talos. r=gregtatum
+
+MozReview-Commit-ID: 7PrI9ZwUMtX
+
+diff --git a/devtools/server/performance/profiler.js b/devtools/server/performance/profiler.js
+--- a/devtools/server/performance/profiler.js
++++ b/devtools/server/performance/profiler.js
+@@ -45,16 +45,19 @@ const ProfilerManager = (function () {
+   return {
+ 
+     // How often the "profiler-status" is emitted
+     _profilerStatusInterval: BUFFER_STATUS_INTERVAL_DEFAULT,
+ 
+     // How many subscribers there
+     _profilerStatusSubscribers: 0,
+ 
++    // Has the profiler ever been started by the actor?
++    started: false,
++
+     /**
+      * The nsIProfiler is target agnostic and interacts with the whole platform.
+      * Therefore, special care needs to be given to make sure different profiler
+      * consumers (i.e. "toolboxes") don't interfere with each other. Register
+      * the profiler actor instances here.
+      *
+      * @param Profiler instance
+      *        A profiler actor class.
+@@ -119,33 +122,38 @@ const ProfilerManager = (function () {
+           config.threadFilters.length
+         );
+       } catch (e) {
+         // For some reason, the profiler couldn't be started. This could happen,
+         // for example, when in private browsing mode.
+         Cu.reportError(`Could not start the profiler module: ${e.message}`);
+         return { started: false, reason: e, currentTime };
+       }
++      this.started = true;
+ 
+       this._updateProfilerStatusPolling();
+ 
+       let { position, totalSize, generation } = this.getBufferInfo();
+       return { started: true, position, totalSize, generation, currentTime };
+     },
+ 
+     /**
+      * Attempts to stop the nsIProfiler module.
+      */
+     stop: function () {
+       // Actually stop the profiler only if the last client has stopped profiling.
+       // Since this is used as a root actor, and the profiler module interacts
+       // with the whole platform, we need to avoid a case in which the profiler
+       // is stopped when there might be other clients still profiling.
+-      if (this.length <= 1) {
++      // Also check for `started` to only stop the profiler when the actor
++      // actually started it. This is to prevent stopping the profiler initiated
++      // by some other code, like Talos.
++      if (this.length <= 1 && this.started) {
+         nsIProfilerModule.StopProfiler();
++        this.started = false;
+       }
+       this._updateProfilerStatusPolling();
+       return { started: false };
+     },
+ 
+     /**
+      * Returns all the samples accumulated since the profiler was started,
+      * along with the current time. The data has the following format:

+ 28 - 0
mozilla-release/patches/1424154-60a1.patch

@@ -0,0 +1,28 @@
+# HG changeset patch
+# User Narcis Beleuzu <nbeleuzu>
+# Date 1520026860 -7200
+# Node ID 9da21200c6b3cc3309e1e5925f306af343b8dfe3
+# Parent  415bad6e7221e40b09793005468319880185d51c
+Bug 1424154 - Disable test on WinCCOV - Intermittent /browser_dbg-content-script-sources.js | This test exceeded the timeout threshold. r=jmaher
+
+diff --git a/devtools/client/debugger/new/test/mochitest/browser.ini b/devtools/client/debugger/new/test/mochitest/browser.ini
+--- a/devtools/client/debugger/new/test/mochitest/browser.ini
++++ b/devtools/client/debugger/new/test/mochitest/browser.ini
+@@ -130,16 +130,17 @@ skip-if = (os == "win" && ccov) # bug 14
+ skip-if = !e10s # This test is only valid in e10s
+ [browser_dbg-call-stack.js]
+ [browser_dbg-scopes.js]
+ [browser_dbg-chrome-create.js]
+ [browser_dbg-chrome-debugging.js]
+ [browser_dbg-console.js]
+ [browser_dbg-console-link.js]
+ [browser_dbg-content-script-sources.js]
++skip-if = (os == "win" && ccov) # Bug 1424154
+ [browser_dbg-debugger-buttons.js]
+ [browser_dbg-editor-gutter.js]
+ [browser_dbg-editor-select.js]
+ [browser_dbg-editor-highlight.js]
+ [browser_dbg-expressions.js]
+ [browser_dbg-expressions-error.js]
+ [browser_dbg-iframes.js]
+ [browser_dbg-inline-cache.js]

+ 0 - 0
mozilla-release/patches/1431050-60a1.patch → mozilla-release/patches/1431050-61a1.patch


+ 158 - 0
mozilla-release/patches/1436151-60a1.patch

@@ -0,0 +1,158 @@
+# HG changeset patch
+# User Jason Laster <jason.laster.11@gmail.com>
+# Date 1517946957 18000
+# Node ID 29223aed98f36328b8c004ffea430ce659a1ab33
+# Parent  8137524fa19f4499f92310040bab6c9f5e821bb6
+Bug 1436151 - Breakpoints at the beginning of a line are missed. r=jimb
+
+diff --git a/devtools/server/actors/source.js b/devtools/server/actors/source.js
+--- a/devtools/server/actors/source.js
++++ b/devtools/server/actors/source.js
+@@ -903,32 +903,52 @@ let SourceActor = ActorClassWithSpec(sou
+       // that correspond to the given line number.
+       for (let script of scripts) {
+         let offsets = script.getLineOffsets(generatedLine);
+         if (offsets.length > 0) {
+           entryPoints.push({ script, offsets });
+         }
+       }
+     } else {
++      // Compute columnToOffsetMaps for each script so that we can
++      // find matching entrypoints for the column breakpoint.
++      const columnToOffsetMaps = scripts.map(script =>
++        [
++          script,
++          script.getAllColumnOffsets()
++            .filter(({ lineNumber }) => lineNumber === generatedLine)
++        ]
++      );
++
+       // This is a column breakpoint, so we are interested in all column
+       // offsets that correspond to the given line *and* column number.
+-      for (let script of scripts) {
+-        let columnToOffsetMap = script.getAllColumnOffsets()
+-                                      .filter(({ lineNumber }) => {
+-                                        return lineNumber === generatedLine;
+-                                      });
++      for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
+         for (let { columnNumber: column, offset } of columnToOffsetMap) {
+           if (column >= generatedColumn && column <= generatedLastColumn) {
+             entryPoints.push({ script, offsets: [offset] });
+           }
+         }
+       }
++
++      // If we don't find any matching entrypoints, then
++      // we should check to see if the breakpoint is to the left of the first offset.
++      if (entryPoints.length === 0) {
++        for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
++          if (columnToOffsetMap.length > 0) {
++            let { columnNumber: column, offset } = columnToOffsetMap[0];
++            if (generatedColumn < column) {
++              entryPoints.push({ script, offsets: [offset] });
++            }
++          }
++        }
++      }
+     }
+ 
+     if (entryPoints.length === 0) {
+       return false;
+     }
++
+     setBreakpointAtEntryPoints(actor, entryPoints);
+     return true;
+   }
+ });
+ 
+ exports.SourceActor = SourceActor;
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js b/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js
+new file mode 100644
+--- /dev/null
++++ b/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js
+@@ -0,0 +1,64 @@
++"use strict";
++
++var SOURCE_URL = getFileUrl("setBreakpoint-on-column.js");
++
++function run_test() {
++  return async function () {
++    do_test_pending();
++
++    DebuggerServer.registerModule("xpcshell-test/testactors");
++    DebuggerServer.init(() => true);
++
++    let global = createTestGlobal("test");
++    DebuggerServer.addTestGlobal(global);
++
++    let client = new DebuggerClient(DebuggerServer.connectPipe());
++    await connect(client);
++
++    let { tabs } = await listTabs(client);
++    let tab = findTab(tabs, "test");
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
++
++    let promise = waitForNewSource(threadClient, SOURCE_URL);
++    loadSubScript(SOURCE_URL, global);
++    let { source } = await promise;
++    let sourceClient = threadClient.source(source);
++
++    let location = { line: 4, column: 2 };
++    let [packet, breakpointClient] = await setBreakpoint(
++      sourceClient,
++      location
++    );
++
++    Assert.ok(!packet.isPending);
++    Assert.equal(false, "actualLocation" in packet);
++
++    packet = await executeOnNextTickAndWaitForPause(function () {
++      Cu.evalInSandbox("f()", global);
++    }, client);
++
++    Assert.equal(packet.type, "paused");
++    let why = packet.why;
++    Assert.equal(why.type, "breakpoint");
++    Assert.equal(why.actors.length, 1);
++    Assert.equal(why.actors[0], breakpointClient.actor);
++
++    let frame = packet.frame;
++    let where = frame.where;
++    Assert.equal(where.source.actor, source.actor);
++    Assert.equal(where.line, location.line);
++    Assert.equal(where.column, 6);
++
++    let variables = frame.environment.bindings.variables;
++    Assert.equal(variables.a.value.type, "undefined");
++    Assert.equal(variables.b.value.type, "undefined");
++    Assert.equal(variables.c.value.type, "undefined");
++
++    await resume(threadClient);
++    await close(client);
++
++    do_test_finished();
++  };
++}
+diff --git a/devtools/server/tests/unit/xpcshell.ini b/devtools/server/tests/unit/xpcshell.ini
+--- a/devtools/server/tests/unit/xpcshell.ini
++++ b/devtools/server/tests/unit/xpcshell.ini
+@@ -214,16 +214,17 @@ reason = bug 937197
+ [test_registerClient.js]
+ [test_client_request.js]
+ [test_symbols-01.js]
+ [test_symbols-02.js]
+ [test_get-executable-lines.js]
+ [test_get-executable-lines-source-map.js]
+ [test_xpcshell_debugging.js]
+ support-files = xpcshell_debugging_script.js
++[test_setBreakpoint-at-the-beginning-of-a-line.js]
+ [test_setBreakpoint-on-column.js]
+ [test_setBreakpoint-on-column-in-gcd-script.js]
+ [test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js]
+ [test_setBreakpoint-on-line.js]
+ [test_setBreakpoint-on-line-in-gcd-script.js]
+ [test_setBreakpoint-on-line-with-multiple-offsets.js]
+ [test_setBreakpoint-on-line-with-multiple-statements.js]
+ [test_setBreakpoint-on-line-with-no-offsets.js]

+ 1354 - 0
mozilla-release/patches/1436978-60a1.patch

@@ -0,0 +1,1354 @@
+# HG changeset patch
+# User Alexandre Poirot <poirot.alex@gmail.com>
+# Date 1518517874 28800
+# Node ID 46a5b62580f6184ae1423527688f40ae3932c326
+# Parent  bb8cc916586a7a7b9af639f98f52ce944e8d7372
+Bug 1436978 - Stop using Promise.jsm in devtools/server in favor of DOM Promises. r=jdescottes
+
+MozReview-Commit-ID: Hv7uYZKZGIO
+
+diff --git a/devtools/server/actors/animation.js b/devtools/server/actors/animation.js
+--- a/devtools/server/actors/animation.js
++++ b/devtools/server/actors/animation.js
+@@ -21,17 +21,16 @@
+  * References:
+  * - WebAnimation spec:
+  *   http://drafts.csswg.org/web-animations/
+  * - WebAnimation WebIDL files:
+  *   /dom/webidl/Animation*.webidl
+  */
+ 
+ const {Cu, Ci} = require("chrome");
+-const promise = require("promise");
+ const protocol = require("devtools/shared/protocol");
+ const {Actor} = protocol;
+ const {animationPlayerSpec, animationsSpec} = require("devtools/shared/specs/animation");
+ 
+ // Types of animations.
+ const ANIMATION_TYPES = {
+   CSS_ANIMATION: "cssanimation",
+   CSS_TRANSITION: "csstransition",
+@@ -811,64 +810,64 @@ exports.AnimationsActor = protocol.Actor
+     // Until the WebAnimations API provides a way to play/pause via the document
+     // timeline, we have to iterate through the whole DOM to find all players.
+     for (let player of
+          this.getAllAnimations(this.tabActor.window.document, true)) {
+       player.pause();
+       readyPromises.push(player.ready);
+     }
+     this.allAnimationsPaused = true;
+-    return promise.all(readyPromises);
++    return Promise.all(readyPromises);
+   },
+ 
+   /**
+    * Play all animations in the current tabActor's frames.
+    * This method only returns when animations have left their pending states.
+    */
+   playAll: function () {
+     let readyPromises = [];
+     // Until the WebAnimations API provides a way to play/pause via the document
+     // timeline, we have to iterate through the whole DOM to find all players.
+     for (let player of
+          this.getAllAnimations(this.tabActor.window.document, true)) {
+       player.play();
+       readyPromises.push(player.ready);
+     }
+     this.allAnimationsPaused = false;
+-    return promise.all(readyPromises);
++    return Promise.all(readyPromises);
+   },
+ 
+   toggleAll: function () {
+     if (this.allAnimationsPaused) {
+       return this.playAll();
+     }
+     return this.pauseAll();
+   },
+ 
+   /**
+    * Toggle (play/pause) several animations at the same time.
+    * @param {Array} players A list of AnimationPlayerActor objects.
+    * @param {Boolean} shouldPause If set to true, the players will be paused,
+    * otherwise they will be played.
+    */
+   toggleSeveral: function (players, shouldPause) {
+-    return promise.all(players.map(player => {
++    return Promise.all(players.map(player => {
+       return shouldPause ? player.pause() : player.play();
+     }));
+   },
+ 
+   /**
+    * Set the current time of several animations at the same time.
+    * @param {Array} players A list of AnimationPlayerActor.
+    * @param {Number} time The new currentTime.
+    * @param {Boolean} shouldPause Should the players be paused too.
+    */
+   setCurrentTimes: function (players, time, shouldPause) {
+-    return promise.all(players.map(player => {
+-      let pause = shouldPause ? player.pause() : promise.resolve();
++    return Promise.all(players.map(player => {
++      let pause = shouldPause ? player.pause() : Promise.resolve();
+       return pause.then(() => player.setCurrentTime(time));
+     }));
+   },
+ 
+   /**
+    * Set the playback rate of several animations at the same time.
+    * @param {Array} players A list of AnimationPlayerActor.
+    * @param {Number} rate The new rate.
+diff --git a/devtools/server/actors/common.js b/devtools/server/actors/common.js
+--- a/devtools/server/actors/common.js
++++ b/devtools/server/actors/common.js
+@@ -1,17 +1,16 @@
+ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+-const promise = require("promise");
+ const { method } = require("devtools/shared/protocol");
+ 
+ /**
+  * Creates "registered" actors factory meant for creating another kind of
+  * factories, ObservedActorFactory, during the call to listTabs.
+  * These factories live in DebuggerServer.{tab|global}ActorFactories.
+  *
+  * These actors only exposes:
+@@ -482,17 +481,17 @@ exports.GeneratedLocation = GeneratedLoc
+  *          The decorated method.
+  */
+ function expectState(expectedState, methodFunc, activity) {
+   return function (...args) {
+     if (this.state !== expectedState) {
+       const msg = `Wrong state while ${activity}:` +
+                   `Expected '${expectedState}', ` +
+                   `but current state is '${this.state}'.`;
+-      return promise.reject(new Error(msg));
++      return Promise.reject(new Error(msg));
+     }
+ 
+     return methodFunc.apply(this, args);
+   };
+ }
+ 
+ exports.expectState = expectState;
+ 
+diff --git a/devtools/server/actors/inspector/utils.js b/devtools/server/actors/inspector/utils.js
+--- a/devtools/server/actors/inspector/utils.js
++++ b/devtools/server/actors/inspector/utils.js
+@@ -1,17 +1,16 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {Ci, Cu} = require("chrome");
+ 
+-const promise = require("promise");
+ const {Task} = require("devtools/shared/task");
+ 
+ loader.lazyRequireGetter(this, "AsyncUtils", "devtools/shared/async-utils");
+ loader.lazyRequireGetter(this, "flags", "devtools/shared/flags");
+ loader.lazyRequireGetter(this, "DevToolsUtils", "devtools/shared/DevToolsUtils");
+ loader.lazyRequireGetter(this, "nodeFilterConstants", "devtools/shared/dom-node-filter-constants");
+ 
+ loader.lazyRequireGetter(this, "isNativeAnonymous", "devtools/shared/layout/utils", true);
+@@ -135,44 +134,44 @@ function nodeHasSize(node) {
+  * before the waiting is aborted. Ignored if flags.testing is set.
+  *
+  * @return {Promise} that is fulfilled once the image has loaded. If the image
+  * fails to load or the load takes too long, the promise is rejected.
+  */
+ function ensureImageLoaded(image, timeout) {
+   let { HTMLImageElement } = image.ownerGlobal;
+   if (!(image instanceof HTMLImageElement)) {
+-    return promise.reject("image must be an HTMLImageELement");
++    return Promise.reject("image must be an HTMLImageELement");
+   }
+ 
+   if (image.complete) {
+     // The image has already finished loading.
+-    return promise.resolve();
++    return Promise.resolve();
+   }
+ 
+   // This image is still loading.
+   let onLoad = AsyncUtils.listenOnce(image, "load");
+ 
+   // Reject if loading fails.
+   let onError = AsyncUtils.listenOnce(image, "error").then(() => {
+-    return promise.reject("Image '" + image.src + "' failed to load.");
++    return Promise.reject("Image '" + image.src + "' failed to load.");
+   });
+ 
+   // Don't timeout when testing. This is never settled.
+   let onAbort = new Promise(() => {});
+ 
+   if (!flags.testing) {
+     // Tests are not running. Reject the promise after given timeout.
+     onAbort = DevToolsUtils.waitForTime(timeout).then(() => {
+-      return promise.reject("Image '" + image.src + "' took too long to load.");
++      return Promise.reject("Image '" + image.src + "' took too long to load.");
+     });
+   }
+ 
+   // See which happens first.
+-  return promise.race([onLoad, onError, onAbort]);
++  return Promise.race([onLoad, onError, onAbort]);
+ }
+ 
+ /**
+  * Given an <img> or <canvas> element, return the image data-uri. If @param node
+  * is an <img> element, the method waits a while for the image to load before
+  * the data is generated. If the image does not finish loading in a reasonable
+  * time (IMAGE_FETCHING_TIMEOUT milliseconds) the process aborts.
+  *
+diff --git a/devtools/server/actors/source.js b/devtools/server/actors/source.js
+--- a/devtools/server/actors/source.js
++++ b/devtools/server/actors/source.js
+@@ -10,17 +10,16 @@ const { Cc, Ci } = require("chrome");
+ const Services = require("Services");
+ const { BreakpointActor, setBreakpointAtEntryPoints } = require("devtools/server/actors/breakpoint");
+ const { OriginalLocation, GeneratedLocation } = require("devtools/server/actors/common");
+ const { createValueGrip, arrayBufferGrip } = require("devtools/server/actors/object");
+ const { ActorClassWithSpec } = require("devtools/shared/protocol");
+ const DevToolsUtils = require("devtools/shared/DevToolsUtils");
+ const { assert, fetch } = DevToolsUtils;
+ const { joinURI } = require("devtools/shared/path");
+-const promise = require("promise");
+ const { sourceSpec } = require("devtools/shared/specs/source");
+ 
+ loader.lazyRequireGetter(this, "SourceMapConsumer", "source-map", true);
+ loader.lazyRequireGetter(this, "SourceMapGenerator", "source-map", true);
+ loader.lazyRequireGetter(this, "mapURIToAddonID", "devtools/server/actors/utils/map-uri-to-addon-id");
+ 
+ function isEvalSource(source) {
+   let introType = source.introductionType;
+@@ -474,17 +473,17 @@ let SourceActor = ActorClassWithSpec(sou
+ 
+     return offsets;
+   },
+ 
+   /**
+    * Handler for the "source" packet.
+    */
+   onSource: function () {
+-    return promise.resolve(this._init)
++    return Promise.resolve(this._init)
+       .then(this._getSourceText)
+       .then(({ content, contentType }) => {
+         if (typeof content === "object" && content && content.constructor &&
+             content.constructor.name === "ArrayBuffer") {
+           return {
+             source: arrayBufferGrip(content, this.threadActor.threadLifetimePool),
+             contentType,
+           };
+@@ -783,17 +782,17 @@ let SourceActor = ActorClassWithSpec(sou
+         // to how scripts are kept alive. A parent Debugger.Script
+         // keeps all of its children alive, so as long as we have a
+         // valid script, we can slide through it and know we won't
+         // slide through any of its child scripts. Additionally, if a
+         // script gets GCed, that means that all parents scripts are
+         // GCed as well, and no scripts will exist on those lines
+         // anymore. We will never slide through a GCed script.
+         if (originalLocation.originalColumn || scripts.length === 0) {
+-          return promise.resolve(actor);
++          return Promise.resolve(actor);
+         }
+ 
+         // Find the script that spans the largest amount of code to
+         // determine the bounds for sliding.
+         const largestScript = scripts.reduce((largestScr, script) => {
+           if (script.lineCount > largestScr.lineCount) {
+             return script;
+           }
+@@ -809,17 +808,17 @@ let SourceActor = ActorClassWithSpec(sou
+           }
+         }
+ 
+         // The above loop should never complete. We only did breakpoint sliding
+         // because we found scripts on the line we started from,
+         // which means there must be valid entry points somewhere
+         // within those scripts.
+         if (actualLine > maxLine) {
+-          return promise.reject({
++          return Promise.reject({
+             error: "noCodeAtLineColumn",
+             message:
+               "Could not find any entry points to set a breakpoint on, " +
+               "even though I was told a script existed on the line I started " +
+               "the search with."
+           });
+         }
+ 
+@@ -832,17 +831,17 @@ let SourceActor = ActorClassWithSpec(sou
+           actor.delete();
+           actor = existingActor;
+         } else {
+           actor.originalLocation = actualLocation;
+           this.breakpointActorMap.setActor(actualLocation, actor);
+         }
+       }
+ 
+-      return promise.resolve(actor);
++      return Promise.resolve(actor);
+     }
+     return this.sources.getAllGeneratedLocations(originalLocation)
+       .then((generatedLocations) => {
+         this._setBreakpointAtAllGeneratedLocations(
+           actor,
+           generatedLocations
+         );
+ 
+diff --git a/devtools/server/actors/storage.js b/devtools/server/actors/storage.js
+--- a/devtools/server/actors/storage.js
++++ b/devtools/server/actors/storage.js
+@@ -4,17 +4,16 @@
+ 
+ "use strict";
+ 
+ const {Cc, Ci, Cu, CC} = require("chrome");
+ const protocol = require("devtools/shared/protocol");
+ const {LongStringActor} = require("devtools/server/actors/string");
+ const {DebuggerServer} = require("devtools/server/main");
+ const Services = require("Services");
+-const promise = require("promise");
+ const defer = require("devtools/shared/defer");
+ const {isWindowIncluded} = require("devtools/shared/layout/utils");
+ const specs = require("devtools/shared/specs/storage");
+ const { Task } = require("devtools/shared/task");
+ 
+ const DEFAULT_VALUE = "value";
+ 
+ loader.lazyRequireGetter(this, "naturalSortCaseInsensitive",
+@@ -1449,17 +1448,17 @@ StorageActors.createActor({
+     const parsedName = JSON.parse(name);
+ 
+     // Only a Cache object is a valid object to clear
+     if (parsedName.length == 1) {
+       const [ cacheName ] = parsedName;
+       const cache = cacheMap.get(cacheName);
+       if (cache) {
+         let keys = yield cache.keys();
+-        yield promise.all(keys.map(key => cache.delete(key)));
++        yield Promise.all(keys.map(key => cache.delete(key)));
+         this.onItemUpdated("cleared", host, [ cacheName ]);
+       }
+     }
+   }),
+ 
+   /**
+    * CacheStorage API doesn't support any notifications, we must fake them
+    */
+diff --git a/devtools/server/actors/string.js b/devtools/server/actors/string.js
+--- a/devtools/server/actors/string.js
++++ b/devtools/server/actors/string.js
+@@ -1,18 +1,16 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ var {DebuggerServer} = require("devtools/server/main");
+ 
+-var promise = require("promise");
+-
+ var protocol = require("devtools/shared/protocol");
+ const {longStringSpec} = require("devtools/shared/specs/string");
+ 
+ exports.LongStringActor = protocol.ActorClassWithSpec(longStringSpec, {
+   initialize: function (conn, str) {
+     protocol.Actor.prototype.initialize.call(this, conn);
+     this.str = str;
+     this.short = (this.str.length < DebuggerServer.LONG_STRING_LENGTH);
+@@ -31,13 +29,13 @@ exports.LongStringActor = protocol.Actor
+       type: "longString",
+       actor: this.actorID,
+       length: this.str.length,
+       initial: this.str.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH)
+     };
+   },
+ 
+   substring: function (start, end) {
+-    return promise.resolve(this.str.substring(start, end));
++    return Promise.resolve(this.str.substring(start, end));
+   },
+ 
+   release: function () { }
+ });
+diff --git a/devtools/server/actors/styles.js b/devtools/server/actors/styles.js
+--- a/devtools/server/actors/styles.js
++++ b/devtools/server/actors/styles.js
+@@ -1,16 +1,15 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {Ci} = require("chrome");
+-const promise = require("promise");
+ const protocol = require("devtools/shared/protocol");
+ const {LongStringActor} = require("devtools/server/actors/string");
+ const {Task} = require("devtools/shared/task");
+ 
+ // This will also add the "stylesheet" actor type for protocol.js to recognize
+ 
+ const {pageStyleSpec, styleRuleSpec, ELEMENT_STYLE} = require("devtools/shared/specs/styles");
+ 
+@@ -1227,21 +1226,21 @@ var StyleRuleActor = protocol.ActorClass
+    * authored form is available, this also sets |this.authoredText|.
+    * The authored text will include invalid and otherwise ignored
+    * properties.
+    */
+   getAuthoredCssText: function () {
+     if (!this.canSetRuleText ||
+         (this.type !== Ci.nsIDOMCSSRule.STYLE_RULE &&
+          this.type !== Ci.nsIDOMCSSRule.KEYFRAME_RULE)) {
+-      return promise.resolve("");
++      return Promise.resolve("");
+     }
+ 
+     if (typeof this.authoredText === "string") {
+-      return promise.resolve(this.authoredText);
++      return Promise.resolve(this.authoredText);
+     }
+ 
+     let parentStyleSheet =
+         this.pageStyle._sheetRef(this._parentSheet);
+     return parentStyleSheet.getText().then((longStr) => {
+       let cssText = longStr.str;
+       let {text} = getRuleText(cssText, this.line, this.column);
+ 
+diff --git a/devtools/server/actors/stylesheets.js b/devtools/server/actors/stylesheets.js
+--- a/devtools/server/actors/stylesheets.js
++++ b/devtools/server/actors/stylesheets.js
+@@ -1,17 +1,16 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {Ci} = require("chrome");
+ const Services = require("Services");
+-const promise = require("promise");
+ const defer = require("devtools/shared/defer");
+ const {Task} = require("devtools/shared/task");
+ const protocol = require("devtools/shared/protocol");
+ const {LongStringActor} = require("devtools/server/actors/string");
+ const {fetch} = require("devtools/shared/DevToolsUtils");
+ const {mediaRuleSpec, styleSheetSpec,
+        styleSheetsSpec} = require("devtools/shared/specs/stylesheets");
+ const {
+@@ -271,21 +270,21 @@ var StyleSheetActor = protocol.ActorClas
+     let rules;
+     try {
+       rules = this.rawSheet.cssRules;
+     } catch (e) {
+       // sheet isn't loaded yet
+     }
+ 
+     if (rules) {
+-      return promise.resolve(rules);
++      return Promise.resolve(rules);
+     }
+ 
+     if (!this.ownerNode) {
+-      return promise.resolve([]);
++      return Promise.resolve([]);
+     }
+ 
+     if (this._cssRules) {
+       return this._cssRules;
+     }
+ 
+     let deferred = defer();
+ 
+@@ -383,30 +382,30 @@ var StyleSheetActor = protocol.ActorClas
+    * Fetch the text for this stylesheet from the cache or network. Return
+    * cached text if it's already been fetched.
+    *
+    * @return {Promise}
+    *         Promise that resolves with a string text of the stylesheet.
+    */
+   _getText: function () {
+     if (typeof this.text === "string") {
+-      return promise.resolve(this.text);
++      return Promise.resolve(this.text);
+     }
+ 
+     let cssText = modifiedStyleSheets.get(this.rawSheet);
+     if (cssText !== undefined) {
+       this.text = cssText;
+-      return promise.resolve(cssText);
++      return Promise.resolve(cssText);
+     }
+ 
+     if (!this.href) {
+       // this is an inline <style> sheet
+       let content = this.ownerNode.textContent;
+       this.text = content;
+-      return promise.resolve(content);
++      return Promise.resolve(content);
+     }
+ 
+     return this.fetchStylesheet(this.href).then(({ content }) => {
+       this.text = content;
+       return content;
+     });
+   },
+ 
+diff --git a/devtools/server/actors/thread.js b/devtools/server/actors/thread.js
+--- a/devtools/server/actors/thread.js
++++ b/devtools/server/actors/thread.js
+@@ -9,22 +9,19 @@
+ const Services = require("Services");
+ const { Cc, Ci, Cr } = require("chrome");
+ const { ActorPool, GeneratedLocation } = require("devtools/server/actors/common");
+ const { createValueGrip, longStringGrip } = require("devtools/server/actors/object");
+ const { ActorClassWithSpec } = require("devtools/shared/protocol");
+ const DevToolsUtils = require("devtools/shared/DevToolsUtils");
+ const flags = require("devtools/shared/flags");
+ const { assert, dumpn } = DevToolsUtils;
+-const promise = require("promise");
+ const { DevToolsWorker } = require("devtools/shared/worker/worker");
+ const { threadSpec } = require("devtools/shared/specs/script");
+ 
+-const { resolve, reject, all } = promise;
+-
+ loader.lazyGetter(this, "Debugger", () => {
+   let Debugger = require("Debugger");
+   hackDebugger(Debugger);
+   return Debugger;
+ });
+ loader.lazyRequireGetter(this, "findCssSelector", "devtools/shared/inspector/css-logic", true);
+ loader.lazyRequireGetter(this, "BreakpointActor", "devtools/server/actors/breakpoint", true);
+ loader.lazyRequireGetter(this, "setBreakpointAtEntryPoints", "devtools/server/actors/breakpoint", true);
+@@ -375,17 +372,17 @@ const ThreadActor = ActorClassWithSpec(t
+                       return undefined;
+                     }
+ 
+                     packet.frame.where = {
+                       source: originalLocation.originalSourceActor.form(),
+                       line: originalLocation.originalLine,
+                       column: originalLocation.originalColumn
+                     };
+-                    resolve(onPacket(packet))
++                    Promise.resolve(onPacket(packet))
+           .catch(error => {
+             reportError(error);
+             return {
+               error: "unknownError",
+               message: error.message + "\n" + error.stack
+             };
+           })
+           .then(pkt => {
+@@ -560,18 +557,18 @@ const ThreadActor = ActorClassWithSpec(t
+    * @param Object request
+    *        The request packet received over the RDP.
+    * @returns A promise that resolves to true once the hooks are attached, or is
+    *          rejected with an error packet.
+    */
+   _handleResumeLimit: function (request) {
+     let steppingType = request.resumeLimit.type;
+     if (!["break", "step", "next", "finish"].includes(steppingType)) {
+-      return reject({ error: "badParameterType",
+-                      message: "Unknown resumeLimit type" });
++      return Promise.reject({ error: "badParameterType",
++                              message: "Unknown resumeLimit type" });
+     }
+ 
+     const generatedLocation = this.sources.getFrameLocation(this.youngestFrame);
+     return this.sources.getOriginalLocation(generatedLocation)
+       .then(originalLocation => {
+         const { onEnterFrame, onPop, onStep } = this._makeSteppingHooks(originalLocation,
+                                                                         steppingType);
+ 
+@@ -671,17 +668,17 @@ const ThreadActor = ActorClassWithSpec(t
+       };
+     }
+ 
+     let resumeLimitHandled;
+     if (request && request.resumeLimit) {
+       resumeLimitHandled = this._handleResumeLimit(request);
+     } else {
+       this._clearSteppingHooks(this.youngestFrame);
+-      resumeLimitHandled = resolve(true);
++      resumeLimitHandled = Promise.resolve(true);
+     }
+ 
+     return resumeLimitHandled.then(() => {
+       if (request) {
+         this._options.pauseOnExceptions = request.pauseOnExceptions;
+         this._options.ignoreCaughtExceptions = request.ignoreCaughtExceptions;
+         this.maybePauseOnExceptions();
+         this._maybeListenToEvents(request);
+@@ -942,17 +939,17 @@ const ThreadActor = ActorClassWithSpec(t
+           column: originalLocation.originalColumn
+         };
+         form.source = sourceForm;
+         return form;
+       });
+       promises.push(framePromise);
+     }
+ 
+-    return all(promises).then(function (frames) {
++    return Promise.all(promises).then(function (frames) {
+       // Filter null values because sourcemapping may have failed.
+       return { frames: frames.filter(x => !!x) };
+     });
+   },
+ 
+   onReleaseMany: function (request) {
+     if (!request.actors) {
+       return { error: "missingParameter",
+@@ -984,17 +981,17 @@ const ThreadActor = ActorClassWithSpec(t
+ 
+     for (let i = 0, len = scripts.length; i < len; i++) {
+       let s = scripts[i];
+       if (s.source) {
+         sourcesToScripts.set(s.source, s);
+       }
+     }
+ 
+-    return all([...sourcesToScripts.values()].map(script => {
++    return Promise.all([...sourcesToScripts.values()].map(script => {
+       return this.sources.createSourceActors(script.source);
+     }));
+   },
+ 
+   onSources: function (request) {
+     return this._discoverSources().then(() => {
+       // No need to flush the new source packets here, as we are sending the
+       // list of sources out immediately and we don't need to invoke the
+@@ -1639,17 +1636,17 @@ const ThreadActor = ActorClassWithSpec(t
+                   sourceActor._setBreakpointAtAllGeneratedLocations(
+                     actor, generatedLocations);
+                 }
+               }));
+         }
+       }
+ 
+       if (promises.length > 0) {
+-        this.unsafeSynchronize(promise.all(promises));
++        this.unsafeSynchronize(Promise.all(promises));
+       }
+     } else {
+       // Bug 1225160: If addSource is called in response to a new script
+       // notification, and this notification was triggered by loading a JSM from
+       // chrome code, calling unsafeSynchronize could cause a debuggee timer to
+       // fire. If this causes the JSM to be loaded a second time, the browser
+       // will crash, because loading JSMS is not reentrant, and the first load
+       // has not completed yet.
+diff --git a/devtools/server/actors/utils/TabSources.js b/devtools/server/actors/utils/TabSources.js
+--- a/devtools/server/actors/utils/TabSources.js
++++ b/devtools/server/actors/utils/TabSources.js
+@@ -3,17 +3,16 @@
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const DevToolsUtils = require("devtools/shared/DevToolsUtils");
+ const { assert, fetch } = DevToolsUtils;
+ const EventEmitter = require("devtools/shared/old-event-emitter");
+ const { OriginalLocation, GeneratedLocation } = require("devtools/server/actors/common");
+-const { resolve } = require("promise");
+ const { joinURI } = require("devtools/shared/path");
+ 
+ loader.lazyRequireGetter(this, "SourceActor", "devtools/server/actors/source", true);
+ loader.lazyRequireGetter(this, "isEvalSource", "devtools/server/actors/source", true);
+ loader.lazyRequireGetter(this, "SourceMapConsumer", "source-map", true);
+ loader.lazyRequireGetter(this, "SourceMapGenerator", "source-map", true);
+ loader.lazyRequireGetter(this, "WasmRemap", "devtools/shared/wasm-source-map", true);
+ 
+@@ -367,17 +366,17 @@ TabSources.prototype = {
+    * instead of this.
+    *
+    * @param Debugger.Source source
+    *        The source instance to create actors for.
+    * @return Promise of an array of source actors
+    */
+   _createSourceMappedActors: function (source) {
+     if (!this._useSourceMaps || !source.sourceMapURL) {
+-      return resolve(null);
++      return Promise.resolve(null);
+     }
+ 
+     return this.fetchSourceMap(source)
+       .then(map => {
+         if (map) {
+           return map.sources.map(s => {
+             return this.source({ originalUrl: s, generatedSource: source });
+           }).filter(isNotNull);
+@@ -410,21 +409,21 @@ TabSources.prototype = {
+    * and source maps are enabled (see `_fetchSourceMap`).
+    *
+    * @param Debugger.Source source
+    *        The source instance to get sourcemaps for.
+    * @return Promise of a SourceMapConsumer
+    */
+   fetchSourceMap: function (source) {
+     if (!this._useSourceMaps) {
+-      return resolve(null);
++      return Promise.resolve(null);
+     } else if (this._sourceMaps.has(source)) {
+       return this._sourceMaps.get(source);
+     } else if (!source || !source.sourceMapURL) {
+-      return resolve(null);
++      return Promise.resolve(null);
+     }
+ 
+     let sourceMapURL = source.sourceMapURL;
+     if (source.url) {
+       sourceMapURL = joinURI(source.url, sourceMapURL);
+     }
+     let result = this._fetchSourceMap(sourceMapURL, source.url);
+ 
+@@ -441,24 +440,24 @@ TabSources.prototype = {
+   },
+ 
+   /**
+    * Return a promise of a SourceMapConsumer for the source map for
+    * `source`. The resolved result may be null if the source does not
+    * have a source map or source maps are disabled.
+    */
+   getSourceMap: function (source) {
+-    return resolve(this._sourceMaps.get(source));
++    return Promise.resolve(this._sourceMaps.get(source));
+   },
+ 
+   /**
+    * Set a SourceMapConsumer for the source map for |source|.
+    */
+   setSourceMap: function (source, map) {
+-    this._sourceMaps.set(source, resolve(map));
++    this._sourceMaps.set(source, Promise.resolve(map));
+   },
+ 
+   /**
+    * Return a promise of a SourceMapConsumer for the source map located at
+    * |absSourceMapURL|, which must be absolute. If there is already such a
+    * promise extant, return it. This will not fetch if source maps are
+    * disabled.
+    *
+@@ -561,17 +560,17 @@ TabSources.prototype = {
+       // avoid tons of work serializing the sourcemap into a data url,
+       // just make a fake URL and stick the sourcemap there.
+       url = "internal://sourcemap" + (this._anonSourceMapId++) + "/";
+     }
+     source.sourceMapURL = url;
+ 
+     // Forcefully set the sourcemap cache. This will be used even if
+     // sourcemaps are disabled.
+-    this._sourceMapCache[url] = resolve(map);
++    this._sourceMapCache[url] = Promise.resolve(map);
+     this.emit("updatedSource", this.getSourceActor(source));
+   },
+ 
+   /**
+    * Return the non-source-mapped location of the given Debugger.Frame. If the
+    * frame does not have a script, the location's properties are all null.
+    *
+    * @param Debugger.Frame frame
+diff --git a/devtools/server/actors/webbrowser.js b/devtools/server/actors/webbrowser.js
+--- a/devtools/server/actors/webbrowser.js
++++ b/devtools/server/actors/webbrowser.js
+@@ -3,17 +3,16 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ var { Ci } = require("chrome");
+ var Services = require("Services");
+-var promise = require("promise");
+ const defer = require("devtools/shared/defer");
+ var { DebuggerServer } = require("devtools/server/main");
+ var DevToolsUtils = require("devtools/shared/DevToolsUtils");
+ 
+ loader.lazyRequireGetter(this, "RootActor", "devtools/server/actors/root", true);
+ loader.lazyRequireGetter(this, "BrowserAddonActor", "devtools/server/actors/addon", true);
+ loader.lazyRequireGetter(this, "WebExtensionParentActor", "devtools/server/actors/webextension-parent", true);
+ loader.lazyRequireGetter(this, "WorkerActorList", "devtools/server/actors/worker-list", true);
+@@ -299,17 +298,17 @@ BrowserTabList.prototype.getList = funct
+ 
+   if (this._testing && initialMapSize !== this._foundCount) {
+     throw new Error("_actorByBrowser map contained actors for dead tabs");
+   }
+ 
+   this._mustNotify = true;
+   this._checkListening();
+ 
+-  return promise.all(actorPromises).then(values => {
++  return Promise.all(actorPromises).then(values => {
+     // Filter out null values if we received a tabDestroyed error.
+     return values.filter(value => value != null);
+   });
+ };
+ 
+ /**
+  * @param browserActorOptions see options argument of BrowserTabActor constructor.
+  */
+@@ -328,17 +327,17 @@ BrowserTabList.prototype._getActorForBro
+ };
+ 
+ BrowserTabList.prototype.getTab = function ({ outerWindowID, tabId }) {
+   if (typeof outerWindowID == "number") {
+     // First look for in-process frames with this ID
+     let window = Services.wm.getOuterWindowWithId(outerWindowID);
+     // Safety check to prevent debugging top level window via getTab
+     if (window instanceof Ci.nsIDOMChromeWindow) {
+-      return promise.reject({
++      return Promise.reject({
+         error: "forbidden",
+         message: "Window with outerWindowID '" + outerWindowID + "' is chrome"
+       });
+     }
+     if (window) {
+       let iframe = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                          .getInterface(Ci.nsIDOMWindowUtils)
+                          .containerElement;
+@@ -348,42 +347,42 @@ BrowserTabList.prototype.getTab = functi
+     }
+     // Then also look on registered <xul:browsers> when using outerWindowID for
+     // OOP tabs
+     for (let browser of this._getBrowsers()) {
+       if (browser.outerWindowID == outerWindowID) {
+         return this._getActorForBrowser(browser);
+       }
+     }
+-    return promise.reject({
++    return Promise.reject({
+       error: "noTab",
+       message: "Unable to find tab with outerWindowID '" + outerWindowID + "'"
+     });
+   } else if (typeof tabId == "number") {
+     // Tabs OOP
+     for (let browser of this._getBrowsers()) {
+       if (browser.frameLoader &&
+           browser.frameLoader.tabParent &&
+           browser.frameLoader.tabParent.tabId === tabId) {
+         return this._getActorForBrowser(browser);
+       }
+     }
+-    return promise.reject({
++    return Promise.reject({
+       error: "noTab",
+       message: "Unable to find tab with tabId '" + tabId + "'"
+     });
+   }
+ 
+   let topXULWindow = Services.wm.getMostRecentWindow(
+     DebuggerServer.chromeWindowType);
+   if (topXULWindow) {
+     let selectedBrowser = this._getSelectedBrowser(topXULWindow);
+     return this._getActorForBrowser(selectedBrowser);
+   }
+-  return promise.reject({
++  return Promise.reject({
+     error: "noTab",
+     message: "Unable to find any selected browser"
+   });
+ };
+ 
+ Object.defineProperty(BrowserTabList.prototype, "onListChanged", {
+   enumerable: true,
+   configurable: true,
+diff --git a/devtools/server/performance/recorder.js b/devtools/server/performance/recorder.js
+--- a/devtools/server/performance/recorder.js
++++ b/devtools/server/performance/recorder.js
+@@ -2,17 +2,16 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ "use strict";
+ 
+ const { Cu } = require("chrome");
+ const { Task } = require("devtools/shared/task");
+ 
+ loader.lazyRequireGetter(this, "Services");
+-loader.lazyRequireGetter(this, "promise");
+ loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
+ 
+ loader.lazyRequireGetter(this, "Memory",
+   "devtools/server/performance/memory", true);
+ loader.lazyRequireGetter(this, "Timeline",
+   "devtools/server/performance/timeline", true);
+ loader.lazyRequireGetter(this, "Profiler",
+   "devtools/server/performance/profiler", true);
+@@ -343,17 +342,17 @@ PerformanceRecorder.prototype = {
+         this._memory.attach();
+       }
+       let recordingOptions = Object.assign(mapRecordingOptions("memory", options), {
+         drainAllocationsTimeout: DRAIN_ALLOCATIONS_TIMEOUT
+       });
+       memoryStart = this._memory.startRecordingAllocations(recordingOptions);
+     }
+ 
+-    let [profilerStartData, timelineStartData, memoryStartData] = yield promise.all([
++    let [profilerStartData, timelineStartData, memoryStartData] = yield Promise.all([
+       profilerStart, timelineStart, memoryStart
+     ]);
+ 
+     let data = Object.create(null);
+     // Filter out start times that are not actually used (0 or undefined), and
+     // find the earliest time since all sources use same epoch.
+     let startTimes = [
+       profilerStartData.currentTime,
+diff --git a/devtools/server/tests/mochitest/inspector-helpers.js b/devtools/server/tests/mochitest/inspector-helpers.js
+--- a/devtools/server/tests/mochitest/inspector-helpers.js
++++ b/devtools/server/tests/mochitest/inspector-helpers.js
+@@ -6,17 +6,16 @@
+ 
+ const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+ const {DebuggerClient} = require("devtools/shared/client/debugger-client");
+ const {DebuggerServer} = require("devtools/server/main");
+ const { Task } = require("devtools/shared/task");
+ 
+ const Services = require("Services");
+ // promise is still used in tests using this helper
+-const promise = require("promise"); // eslint-disable-line no-unused-vars
+ const defer = require("devtools/shared/defer");
+ const {DocumentWalker: _documentWalker} = require("devtools/server/actors/inspector/document-walker");
+ 
+ // Always log packets when running tests.
+ Services.prefs.setBoolPref("devtools.debugger.log", true);
+ SimpleTest.registerCleanupFunction(function () {
+   Services.prefs.clearUserPref("devtools.debugger.log");
+ });
+diff --git a/devtools/server/tests/mochitest/test_inspector-mutations-childlist.html b/devtools/server/tests/mochitest/test_inspector-mutations-childlist.html
+--- a/devtools/server/tests/mochitest/test_inspector-mutations-childlist.html
++++ b/devtools/server/tests/mochitest/test_inspector-mutations-childlist.html
+@@ -59,17 +59,17 @@ function setParent(nodeSelector, newPare
+ 
+ function loadSelector(selector) {
+   return gWalker.querySelectorAll(gWalker.rootNode, selector).then(nodeList => {
+     return nodeList.items();
+   });
+ }
+ 
+ function loadSelectors(selectors) {
+-  return promise.all(Array.from(selectors, (sel) => loadSelector(sel)));
++  return Promise.all(Array.from(selectors, (sel) => loadSelector(sel)));
+ }
+ 
+ function doMoves(moves) {
+   for (let move of moves) {
+     setParent(move[0], move[1]);
+   }
+ }
+ 
+diff --git a/devtools/server/tests/mochitest/test_inspector-resize.html b/devtools/server/tests/mochitest/test_inspector-resize.html
+--- a/devtools/server/tests/mochitest/test_inspector-resize.html
++++ b/devtools/server/tests/mochitest/test_inspector-resize.html
+@@ -10,31 +10,30 @@ https://bugzilla.mozilla.org/show_bug.cg
+   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+   <script type="application/javascript" src="inspector-helpers.js"></script>
+   <script type="application/javascript">
+ "use strict";
+ 
+ window.onload = function () {
+   const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+-  const promise = require("promise");
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+   SimpleTest.waitForExplicitFinish();
+ 
+   let win = null;
+   let inspector = null;
+ 
+   addAsyncTest(function* setup() {
+     info("Setting up inspector and walker actors.");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+     // eslint-disable-next-line new-cap
+-    yield new promise(resolve => {
++    yield new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         win = doc.defaultView;
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+     runNextTest();
+@@ -44,17 +43,17 @@ window.onload = function () {
+     let walker = yield inspector.getWalker();
+ 
+     // We can't receive events from the walker if we haven't first executed a
+     // method on the actor to initialize it.
+     yield walker.querySelector(walker.rootNode, "img");
+ 
+     let {outerWidth, outerHeight} = win;
+     // eslint-disable-next-line new-cap
+-    let onResize = new promise(resolve => {
++    let onResize = new Promise(resolve => {
+       walker.once("resize", () => {
+         resolve();
+       });
+     });
+     win.resizeTo(800, 600);
+     yield onResize;
+ 
+     ok(true, "The resize event was emitted");
+diff --git a/devtools/server/tests/mochitest/test_inspector-retain.html b/devtools/server/tests/mochitest/test_inspector-retain.html
+--- a/devtools/server/tests/mochitest/test_inspector-retain.html
++++ b/devtools/server/tests/mochitest/test_inspector-retain.html
+@@ -106,17 +106,17 @@ addTest(function testRetain() {
+ // retain request), because we haven't issued `getMutations` yet.
+ addTest(function testWinRace() {
+   let front = null;
+   promiseDone(gWalker.querySelector(gWalker.rootNode, "#a").then(node => {
+     front = node;
+     let contentNode = gInspectee.querySelector("#a");
+     contentNode.remove();
+     // Now wait for that mutation and retain response to come in.
+-    return promise.all([
++    return Promise.all([
+       gWalker.retainNode(front),
+       waitForMutation(gWalker, isChildList)
+     ]);
+   }).then(() => {
+     assertOwnership();
+     is(gWalker._retainedOrphans.size, 1, "Should have a retained orphan.");
+     ok(gWalker._retainedOrphans.has(front), "Should have retained our expected node.");
+     return gWalker.unretainNode(front);
+diff --git a/devtools/server/tests/mochitest/test_inspector-search-front.html b/devtools/server/tests/mochitest/test_inspector-search-front.html
+--- a/devtools/server/tests/mochitest/test_inspector-search-front.html
++++ b/devtools/server/tests/mochitest/test_inspector-search-front.html
+@@ -9,17 +9,16 @@ https://bugzilla.mozilla.org/show_bug.cg
+   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+   <script type="application/javascript" src="inspector-helpers.js"></script>
+   <script type="application/javascript">
+ "use strict";
+ 
+ window.onload = function () {
+   const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+-  const promise = require("promise");
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+   SimpleTest.waitForExplicitFinish();
+ 
+   let walkerFront = null;
+   let inspector = null;
+ 
+   // WalkerFront specific tests.  These aren't to excercise search
+@@ -28,17 +27,17 @@ window.onload = function () {
+   // See also test_inspector-search.html
+ 
+   addAsyncTest(function* setup() {
+     info("Setting up inspector and walker actors.");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+     // eslint-disable-next-line new-cap
+-    yield new promise(resolve => {
++    yield new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+     walkerFront = yield inspector.getWalker();
+     ok(walkerFront, "getWalker() should return an actor.");
+diff --git a/devtools/server/tests/mochitest/test_inspector-search.html b/devtools/server/tests/mochitest/test_inspector-search.html
+--- a/devtools/server/tests/mochitest/test_inspector-search.html
++++ b/devtools/server/tests/mochitest/test_inspector-search.html
+@@ -9,17 +9,16 @@ https://bugzilla.mozilla.org/show_bug.cg
+   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+   <script type="application/javascript" src="inspector-helpers.js"></script>
+   <script type="application/javascript">
+ "use strict";
+ 
+ window.onload = function () {
+   const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+-  const promise = require("promise");
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+   const {WalkerSearch, WalkerIndex} =
+     require("devtools/server/actors/utils/walker-search");
+ 
+   SimpleTest.waitForExplicitFinish();
+ 
+   let walkerActor = null;
+   let walkerSearch = null;
+@@ -31,17 +30,17 @@ window.onload = function () {
+   // See also test_inspector-search-front.html.
+ 
+   addAsyncTest(function* setup() {
+     info("Setting up inspector and walker actors.");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+     // eslint-disable-next-line new-cap
+-    yield new promise(resolve => {
++    yield new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         inspectee = doc;
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+     let walkerFront = yield inspector.getWalker();
+@@ -235,34 +234,34 @@ window.onload = function () {
+ 
+     results = walkerSearch.search("h3");
+     isDeeply(results, [
+       expected[1],
+       expected[2]
+     ], "Results are updated after removal");
+ 
+     // eslint-disable-next-line new-cap
+-    yield new promise(resolve => {
++    yield new Promise(resolve => {
+       info("Waiting for a mutation to happen");
+       let observer = new inspectee.defaultView.MutationObserver(() => {
+         resolve();
+       });
+       observer.observe(inspectee, {attributes: true, subtree: true});
+       inspectee.body.setAttribute("h3", "true");
+     });
+ 
+     results = walkerSearch.search("h3");
+     isDeeply(results, [
+       {node: inspectee.body, type: "attributeName"},
+       expected[1],
+       expected[2]
+     ], "Results are updated after addition");
+ 
+     // eslint-disable-next-line new-cap
+-    yield new promise(resolve => {
++    yield new Promise(resolve => {
+       info("Waiting for a mutation to happen");
+       let observer = new inspectee.defaultView.MutationObserver(() => {
+         resolve();
+       });
+       observer.observe(inspectee, {attributes: true, childList: true, subtree: true});
+       inspectee.body.removeAttribute("h3");
+       expected[1].node.remove();
+       expected[2].node.remove();
+@@ -273,17 +272,17 @@ window.onload = function () {
+ 
+     runNextTest();
+   });
+ 
+   runNextTest();
+ 
+   function mutateDocumentAndWaitForMutation(mutationFn) {
+     // eslint-disable-next-line new-cap
+-    return new promise(resolve => {
++    return new Promise(resolve => {
+       info("Listening to markup mutation on the inspectee");
+       let observer = new inspectee.defaultView.MutationObserver(resolve);
+       observer.observe(inspectee, {childList: true, subtree: true});
+       mutationFn();
+     });
+   }
+ };
+   </script>
+diff --git a/devtools/server/tests/mochitest/test_inspector-traversal.html b/devtools/server/tests/mochitest/test_inspector-traversal.html
+--- a/devtools/server/tests/mochitest/test_inspector-traversal.html
++++ b/devtools/server/tests/mochitest/test_inspector-traversal.html
+@@ -332,17 +332,17 @@ addTest(function testShortValue() {
+   }).then(runNextTest));
+ });
+ 
+ addTest(function testReleaseWalker() {
+   checkActorIDs.push(gWalker.actorID);
+ 
+   promiseDone(gWalker.release().then(() => {
+     let promises = Array.from(checkActorIDs, (id) => checkMissing(gClient, id));
+-    return promise.all(promises);
++    return Promise.all(promises);
+   }).then(runNextTest));
+ });
+ 
+ addTest(function cleanup() {
+   gWalker = null;
+   gInspectee = null;
+   gClient = null;
+   runNextTest();
+diff --git a/devtools/server/tests/unit/head_dbg.js b/devtools/server/tests/unit/head_dbg.js
+--- a/devtools/server/tests/unit/head_dbg.js
++++ b/devtools/server/tests/unit/head_dbg.js
+@@ -15,17 +15,16 @@ ChromeUtils.import("resource://testing-c
+   name: "devtools-tests",
+   version: "1",
+   platformVersion: "42",
+   crashReporter: true,
+ });
+ 
+ const { require, loader } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+ const { worker } = ChromeUtils.import("resource://devtools/shared/worker/loader.js", {});
+-const promise = require("promise");
+ const defer = require("devtools/shared/defer");
+ const { Task } = require("devtools/shared/task");
+ const { console } = require("resource://gre/modules/Console.jsm");
+ const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
+ 
+ const Services = require("Services");
+ // Always log packets when running tests. runxpcshelltests.py will throw
+ // the output away anyway, unless you give it the --verbose flag.
+diff --git a/devtools/server/tests/unit/test_blackboxing-06.js b/devtools/server/tests/unit/test_blackboxing-06.js
+--- a/devtools/server/tests/unit/test_blackboxing-06.js
++++ b/devtools/server/tests/unit/test_blackboxing-06.js
+@@ -19,17 +19,17 @@ function run_test() {
+   gDebuggee = addTestGlobal("test-black-box");
+   gClient = new DebuggerClient(DebuggerServer.connectPipe());
+   gClient.connect().then(function () {
+     attachTestTabAndResume(
+       gClient, "test-black-box",
+       function (response, tabClient, threadClient) {
+         gThreadClient = threadClient;
+ 
+-        promise.resolve(setup_code())
++        Promise.resolve(setup_code())
+           .then(black_box_code)
+           .then(run_code)
+           .then(test_correct_location)
+           .catch(function (error) {
+             Assert.ok(false, "Should not get an error, got " + error);
+           })
+           .then(function () {
+             finishClient(gClient);
+diff --git a/devtools/server/tests/unit/test_protocol_async.js b/devtools/server/tests/unit/test_protocol_async.js
+--- a/devtools/server/tests/unit/test_protocol_async.js
++++ b/devtools/server/tests/unit/test_protocol_async.js
+@@ -183,16 +183,16 @@ function run_test() {
+       return deferAfterRejection.promise.then(function () {
+         // Check right return order
+         Assert.equal(sequence, 7);
+         // Check request handling order
+         Assert.equal(ret, sequence++);
+       });
+     }));
+ 
+-    promise.all(calls).then(() => {
++    Promise.all(calls).then(() => {
+       client.close().then(() => {
+         do_test_finished();
+       });
+     });
+   });
+   do_test_pending();
+ }
+diff --git a/devtools/server/tests/unit/test_protocol_children.js b/devtools/server/tests/unit/test_protocol_children.js
+--- a/devtools/server/tests/unit/test_protocol_children.js
++++ b/devtools/server/tests/unit/test_protocol_children.js
+@@ -187,17 +187,17 @@ var ChildFront = protocol.FrontClassWith
+     this.detail = form.detail;
+   },
+ 
+   onEvent1: preEvent("event1", function (a, b, c) {
+     this.event1arg3 = c;
+   }),
+ 
+   onEvent2a: preEvent("event2", function (a, b, c) {
+-    return promise.resolve().then(() => {
++    return Promise.resolve().then(() => {
+       this.event2arg3 = c;
+     });
+   }),
+ 
+   onEvent2b: preEvent("event2", function (a, b, c) {
+     this.event2arg2 = b;
+   }),
+ });
+@@ -320,17 +320,17 @@ var RootFront = protocol.FrontClassWithS
+     }
+     return this._getTemporaryChild(id);
+   }, {
+     impl: "_getTemporaryChild"
+   }),
+ 
+   clearTemporaryChildren: protocol.custom(function () {
+     if (!this._temporaryHolder) {
+-      return promise.resolve(undefined);
++      return Promise.resolve(undefined);
+     }
+     this._temporaryHolder.destroy();
+     delete this._temporaryHolder;
+     return this._clearTemporaryChildren();
+   }, {
+     impl: "_clearTemporaryChildren"
+   })
+ });
+diff --git a/devtools/server/tests/unit/test_protocol_simple.js b/devtools/server/tests/unit/test_protocol_simple.js
+--- a/devtools/server/tests/unit/test_protocol_simple.js
++++ b/devtools/server/tests/unit/test_protocol_simple.js
+@@ -113,17 +113,17 @@ var RootActor = protocol.ActorClassWithS
+ 
+   sayHello: simpleHello,
+ 
+   simpleReturn: function () {
+     return 1;
+   },
+ 
+   promiseReturn: function () {
+-    return promise.resolve(1);
++    return Promise.resolve(1);
+   },
+ 
+   simpleArgs: function (a, b) {
+     return { firstResponse: a + 1, secondResponse: b + 1 };
+   },
+ 
+   nestedArgs: function (a, b, c) {
+     return { a: a, b: b, c: c };
+diff --git a/devtools/server/tests/unit/test_sourcemaps-10.js b/devtools/server/tests/unit/test_sourcemaps-10.js
+--- a/devtools/server/tests/unit/test_sourcemaps-10.js
++++ b/devtools/server/tests/unit/test_sourcemaps-10.js
+@@ -17,17 +17,17 @@ function run_test() {
+   initTestDebuggerServer();
+   gDebuggee = addTestGlobal("test-source-map");
+   gClient = new DebuggerClient(DebuggerServer.connectPipe());
+   gClient.connect().then(function () {
+     attachTestTabAndResume(
+       gClient, "test-source-map",
+       function (response, tabClient, threadClient) {
+         gThreadClient = threadClient;
+-        promise.resolve(define_code())
++        Promise.resolve(define_code())
+           .then(run_code)
+           .then(test_frame_location)
+           .catch(error => {
+             dump(error + "\n");
+             dump(error.stack);
+             Assert.ok(false);
+           })
+           .then(() => {
+diff --git a/devtools/server/tests/unit/test_sourcemaps-11.js b/devtools/server/tests/unit/test_sourcemaps-11.js
+--- a/devtools/server/tests/unit/test_sourcemaps-11.js
++++ b/devtools/server/tests/unit/test_sourcemaps-11.js
+@@ -17,17 +17,17 @@ function run_test() {
+   initTestDebuggerServer();
+   gDebuggee = addTestGlobal("test-source-map");
+   gClient = new DebuggerClient(DebuggerServer.connectPipe());
+   gClient.connect().then(function () {
+     attachTestTabAndResume(
+       gClient, "test-source-map",
+       function (response, tabClient, threadClient) {
+         gThreadClient = threadClient;
+-        promise.resolve(define_code())
++        Promise.resolve(define_code())
+           .then(run_code)
+           .then(test_frames)
+           .catch(error => {
+             dump(error + "\n");
+             dump(error.stack);
+             Assert.ok(false);
+           })
+           .then(() => {

+ 12184 - 0
mozilla-release/patches/1437828-60a1.patch

@@ -0,0 +1,12184 @@
+# HG changeset patch
+# User Alexandre Poirot <poirot.alex@gmail.com>
+# Date 1518521800 28800
+# Node ID 3b06c176e18dee55b119dd4137e159782da68f5d
+# Parent  d34158f37556a16862094bc95bef22ee3b0c1dbd
+Bug 1437828 - Convert Task.jsm to async/await in devtools/server. r=jryans
+
+MozReview-Commit-ID: I1GlhEdco3H
+
+diff --git a/devtools/server/actors/addons.js b/devtools/server/actors/addons.js
+--- a/devtools/server/actors/addons.js
++++ b/devtools/server/actors/addons.js
+@@ -2,39 +2,38 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {AddonManager} = require("resource://gre/modules/AddonManager.jsm");
+ const protocol = require("devtools/shared/protocol");
+ const {FileUtils} = require("resource://gre/modules/FileUtils.jsm");
+-const {Task} = require("devtools/shared/task");
+ const {addonsSpec} = require("devtools/shared/specs/addons");
+ 
+ const AddonsActor = protocol.ActorClassWithSpec(addonsSpec, {
+ 
+   initialize: function (conn) {
+     protocol.Actor.prototype.initialize.call(this, conn);
+   },
+ 
+-  installTemporaryAddon: Task.async(function* (addonPath) {
++  async installTemporaryAddon(addonPath) {
+     let addonFile;
+     let addon;
+     try {
+       addonFile = new FileUtils.File(addonPath);
+-      addon = yield AddonManager.installTemporaryAddon(addonFile);
++      addon = await AddonManager.installTemporaryAddon(addonFile);
+     } catch (error) {
+       throw new Error(`Could not install add-on at '${addonPath}': ${error}`);
+     }
+ 
+     // TODO: once the add-on actor has been refactored to use
+     // protocol.js, we could return it directly.
+     // return new BrowserAddonActor(this.conn, addon);
+ 
+     // Return a pseudo add-on object that a calling client can work
+     // with. Provide a flag that the client can use to detect when it
+     // gets upgraded to a real actor object.
+     return { id: addon.id, actor: false };
+-  }),
++  },
+ });
+ 
+ exports.AddonsActor = AddonsActor;
+diff --git a/devtools/server/actors/heap-snapshot-file.js b/devtools/server/actors/heap-snapshot-file.js
+--- a/devtools/server/actors/heap-snapshot-file.js
++++ b/devtools/server/actors/heap-snapshot-file.js
+@@ -1,17 +1,16 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const protocol = require("devtools/shared/protocol");
+ const Services = require("Services");
+-const { Task } = require("devtools/shared/task");
+ 
+ const { heapSnapshotFileSpec } = require("devtools/shared/specs/heap-snapshot-file");
+ 
+ loader.lazyRequireGetter(this, "DevToolsUtils",
+                          "devtools/shared/DevToolsUtils");
+ loader.lazyRequireGetter(this, "OS", "resource://gre/modules/osfile.jsm", true);
+ loader.lazyRequireGetter(this, "HeapSnapshotFileUtils",
+                          "devtools/shared/heapsnapshot/HeapSnapshotFileUtils");
+@@ -34,34 +33,34 @@ exports.HeapSnapshotFileActor = protocol
+     }
+ 
+     protocol.Actor.prototype.initialize.call(this, conn, parent);
+   },
+ 
+   /**
+    * @see MemoryFront.prototype.transferHeapSnapshot
+    */
+-  transferHeapSnapshot: Task.async(function* (snapshotId) {
++  async transferHeapSnapshot(snapshotId) {
+     const snapshotFilePath =
+           HeapSnapshotFileUtils.getHeapSnapshotTempFilePath(snapshotId);
+     if (!snapshotFilePath) {
+       throw new Error(`No heap snapshot with id: ${snapshotId}`);
+     }
+ 
+     const streamPromise = DevToolsUtils.openFileStream(snapshotFilePath);
+ 
+-    const { size } = yield OS.File.stat(snapshotFilePath);
++    const { size } = await OS.File.stat(snapshotFilePath);
+     const bulkPromise = this.conn.startBulkSend({
+       actor: this.actorID,
+       type: "heap-snapshot",
+       length: size
+     });
+ 
+-    const [bulk, stream] = yield Promise.all([bulkPromise, streamPromise]);
++    const [bulk, stream] = await Promise.all([bulkPromise, streamPromise]);
+ 
+     try {
+-      yield bulk.copyFrom(stream);
++      await bulk.copyFrom(stream);
+     } finally {
+       stream.close();
+     }
+-  }),
++  },
+ 
+ });
+diff --git a/devtools/server/actors/inspector/utils.js b/devtools/server/actors/inspector/utils.js
+--- a/devtools/server/actors/inspector/utils.js
++++ b/devtools/server/actors/inspector/utils.js
+@@ -1,18 +1,16 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {Ci, Cu} = require("chrome");
+ 
+-const {Task} = require("devtools/shared/task");
+-
+ loader.lazyRequireGetter(this, "AsyncUtils", "devtools/shared/async-utils");
+ loader.lazyRequireGetter(this, "flags", "devtools/shared/flags");
+ loader.lazyRequireGetter(this, "DevToolsUtils", "devtools/shared/DevToolsUtils");
+ loader.lazyRequireGetter(this, "nodeFilterConstants", "devtools/shared/dom-node-filter-constants");
+ 
+ loader.lazyRequireGetter(this, "isNativeAnonymous", "devtools/shared/layout/utils", true);
+ loader.lazyRequireGetter(this, "isXBLAnonymous", "devtools/shared/layout/utils", true);
+ 
+@@ -186,29 +184,29 @@ function ensureImageLoaded(image, timeou
+  *   size: {
+  *     naturalWidth: 400,
+  *     naturalHeight: 300,
+  *     resized: true }
+  *  }.
+  *
+  * If something goes wrong, the promise is rejected.
+  */
+-const imageToImageData = Task.async(function* (node, maxDim) {
++const imageToImageData = async function (node, maxDim) {
+   let { HTMLCanvasElement, HTMLImageElement } = node.ownerGlobal;
+ 
+   let isImg = node instanceof HTMLImageElement;
+   let isCanvas = node instanceof HTMLCanvasElement;
+ 
+   if (!isImg && !isCanvas) {
+     throw new Error("node is not a <canvas> or <img> element.");
+   }
+ 
+   if (isImg) {
+     // Ensure that the image is ready.
+-    yield ensureImageLoaded(node, IMAGE_FETCHING_TIMEOUT);
++    await ensureImageLoaded(node, IMAGE_FETCHING_TIMEOUT);
+   }
+ 
+   // Get the image resize ratio if a maxDim was provided
+   let resizeRatio = 1;
+   let imgWidth = node.naturalWidth || node.width;
+   let imgHeight = node.naturalHeight || node.height;
+   let imgMax = Math.max(imgWidth, imgHeight);
+   if (maxDim && imgMax > maxDim) {
+@@ -237,17 +235,17 @@ const imageToImageData = Task.async(func
+   return {
+     data: imageData,
+     size: {
+       naturalWidth: imgWidth,
+       naturalHeight: imgHeight,
+       resized: resizeRatio !== 1
+     }
+   };
+-});
++};
+ 
+ module.exports = {
+   allAnonymousContentTreeWalkerFilter,
+   getNodeDisplayName,
+   imageToImageData,
+   isNodeDead,
+   nodeDocument,
+   standardTreeWalkerFilter,
+diff --git a/devtools/server/actors/performance.js b/devtools/server/actors/performance.js
+--- a/devtools/server/actors/performance.js
++++ b/devtools/server/actors/performance.js
+@@ -1,15 +1,14 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+-const { Task } = require("devtools/shared/task");
+ const { Actor, ActorClassWithSpec } = require("devtools/shared/protocol");
+ const { actorBridgeWithSpec } = require("devtools/server/actors/common");
+ const { performanceSpec } = require("devtools/shared/specs/performance");
+ 
+ loader.lazyRequireGetter(this, "PerformanceRecorder",
+   "devtools/server/performance/recorder", true);
+ loader.lazyRequireGetter(this, "normalizePerformanceFeatures",
+   "devtools/shared/performance/recording-utils", true);
+@@ -59,27 +58,27 @@ var PerformanceActor = ActorClassWithSpe
+     this.bridge.connect({ systemClient: config.systemClient });
+     return { traits: this.traits };
+   },
+ 
+   canCurrentlyRecord: function () {
+     return this.bridge.canCurrentlyRecord();
+   },
+ 
+-  startRecording: Task.async(function* (options = {}) {
++  async startRecording(options = {}) {
+     if (!this.bridge.canCurrentlyRecord().success) {
+       return null;
+     }
+ 
+     let normalizedOptions = normalizePerformanceFeatures(options, this.traits.features);
+-    let recording = yield this.bridge.startRecording(normalizedOptions);
++    let recording = await this.bridge.startRecording(normalizedOptions);
+     this.manage(recording);
+ 
+     return recording;
+-  }),
++  },
+ 
+   stopRecording: actorBridgeWithSpec("stopRecording"),
+   isRecording: actorBridgeWithSpec("isRecording"),
+   getRecordings: actorBridgeWithSpec("getRecordings"),
+   getConfiguration: actorBridgeWithSpec("getConfiguration"),
+   setProfilerStatusInterval: actorBridgeWithSpec("setProfilerStatusInterval"),
+ 
+   /**
+diff --git a/devtools/server/actors/storage.js b/devtools/server/actors/storage.js
+--- a/devtools/server/actors/storage.js
++++ b/devtools/server/actors/storage.js
+@@ -7,17 +7,16 @@
+ const {Cc, Ci, Cu, CC} = require("chrome");
+ const protocol = require("devtools/shared/protocol");
+ const {LongStringActor} = require("devtools/server/actors/string");
+ const {DebuggerServer} = require("devtools/server/main");
+ const Services = require("Services");
+ const defer = require("devtools/shared/defer");
+ const {isWindowIncluded} = require("devtools/shared/layout/utils");
+ const specs = require("devtools/shared/specs/storage");
+-const { Task } = require("devtools/shared/task");
+ 
+ const DEFAULT_VALUE = "value";
+ 
+ loader.lazyRequireGetter(this, "naturalSortCaseInsensitive",
+   "devtools/client/shared/natural-sort", true);
+ 
+ // "Lax", "Strict" and "Unset" are special values of the sameSite property
+ // that should not be translated.
+@@ -235,25 +234,25 @@ StorageActors.defaults = function (typeN
+ 
+     /**
+      * When a new window is added to the page. This generally means that a new
+      * iframe is created, or the current window is completely reloaded.
+      *
+      * @param {window} window
+      *        The window which was added.
+      */
+-    onWindowReady: Task.async(function* (window) {
++    async onWindowReady(window) {
+       let host = this.getHostName(window.location);
+       if (host && !this.hostVsStores.has(host)) {
+-        yield this.populateStoresForHost(host, window);
++        await this.populateStoresForHost(host, window);
+         let data = {};
+         data[host] = this.getNamesForHost(host);
+         this.storageActor.update("added", typeName, data);
+       }
+-    }),
++    },
+ 
+     /**
+      * When a window is removed from the page. This generally means that an
+      * iframe was removed, or the current window reload is triggered.
+      *
+      * @param {window} window
+      *        The window which was removed.
+      */
+@@ -319,17 +318,17 @@ StorageActors.defaults = function (typeN
+      *
+      * @return {object} An object containing following properties:
+      *          - offset - The actual offset of the returned array. This might
+      *                     be different from the requested offset if that was
+      *                     invalid
+      *          - total - The total number of entries possible.
+      *          - data - The requested values.
+      */
+-    getStoreObjects: Task.async(function* (host, names, options = {}) {
++    async getStoreObjects(host, names, options = {}) {
+       let offset = options.offset || 0;
+       let size = options.size || MAX_STORE_OBJECT_COUNT;
+       if (size > MAX_STORE_OBJECT_COUNT) {
+         size = MAX_STORE_OBJECT_COUNT;
+       }
+       let sortOn = options.sortOn || "name";
+ 
+       let toReturn = {
+@@ -345,17 +344,17 @@ StorageActors.defaults = function (typeN
+         let win = this.storageActor.getWindowFromHost(host);
+         if (win) {
+           principal = win.document.nodePrincipal;
+         }
+       }
+ 
+       if (names) {
+         for (let name of names) {
+-          let values = yield this.getValuesForHost(host, name, options,
++          let values = await this.getValuesForHost(host, name, options,
+             this.hostVsStores, principal);
+ 
+           let {result, objectStores} = values;
+ 
+           if (result && typeof result.objectsSize !== "undefined") {
+             for (let {key, count} of result.objectsSize) {
+               this.objectsSize[key] = count;
+             }
+@@ -380,17 +379,17 @@ StorageActors.defaults = function (typeN
+           // We need to use natural sort before slicing.
+           let sorted = toReturn.data.sort((a, b) => {
+             return naturalSortCaseInsensitive(a[sortOn], b[sortOn]);
+           });
+           let sliced = sorted.slice(offset, offset + size);
+           toReturn.data = sliced.map(a => this.toStoreObject(a));
+         }
+       } else {
+-        let obj = yield this.getValuesForHost(host, undefined, undefined,
++        let obj = await this.getValuesForHost(host, undefined, undefined,
+                                               this.hostVsStores, principal);
+         if (obj.dbs) {
+           obj = obj.dbs;
+         }
+ 
+         toReturn.total = obj.length;
+ 
+         if (offset > toReturn.total) {
+@@ -403,17 +402,17 @@ StorageActors.defaults = function (typeN
+             return naturalSortCaseInsensitive(a[sortOn], b[sortOn]);
+           });
+           let sliced = sorted.slice(offset, offset + size);
+           toReturn.data = sliced.map(object => this.toStoreObject(object));
+         }
+       }
+ 
+       return toReturn;
+-    })
++    }
+   };
+ };
+ 
+ /**
+  * Creates an actor and its corresponding front and registers it to the Storage
+  * Actor.
+  *
+  * @See StorageActors.defaults()
+@@ -655,71 +654,71 @@ StorageActors.createActor({
+           }
+           this.storageActor.update("cleared", "cookies", data);
+         }
+         break;
+     }
+     return null;
+   },
+ 
+-  getFields: Task.async(function* () {
++  async getFields() {
+     return [
+       { name: "uniqueKey", editable: false, private: true },
+       { name: "name", editable: true, hidden: false },
+       { name: "host", editable: true, hidden: false },
+       { name: "path", editable: true, hidden: false },
+       { name: "expires", editable: true, hidden: false },
+       { name: "lastAccessed", editable: false, hidden: false },
+       { name: "creationTime", editable: false, hidden: true },
+       { name: "value", editable: true, hidden: false },
+       { name: "isDomain", editable: false, hidden: true },
+       { name: "isSecure", editable: true, hidden: true },
+       { name: "isHttpOnly", editable: true, hidden: false },
+       { name: "sameSite", editable: false, hidden: false }
+     ];
+-  }),
++  },
+ 
+   /**
+    * Pass the editItem command from the content to the chrome process.
+    *
+    * @param {Object} data
+    *        See editCookie() for format details.
+    */
+-  editItem: Task.async(function* (data) {
++  async editItem(data) {
+     let doc = this.storageActor.document;
+     data.originAttributes = doc.nodePrincipal
+                                .originAttributes;
+     this.editCookie(data);
+-  }),
+-
+-  addItem: Task.async(function* (guid) {
++  },
++
++  async addItem(guid) {
+     let doc = this.storageActor.document;
+     let time = new Date().getTime();
+     let expiry = new Date(time + 3600 * 24 * 1000).toGMTString();
+ 
+     doc.cookie = `${guid}=${DEFAULT_VALUE};expires=${expiry}`;
+-  }),
+-
+-  removeItem: Task.async(function* (host, name) {
++  },
++
++  async removeItem(host, name) {
+     let doc = this.storageActor.document;
+     this.removeCookie(host, name, doc.nodePrincipal
+                                      .originAttributes);
+-  }),
+-
+-  removeAll: Task.async(function* (host, domain) {
++  },
++
++  async removeAll(host, domain) {
+     let doc = this.storageActor.document;
+     this.removeAllCookies(host, domain, doc.nodePrincipal
+                                            .originAttributes);
+-  }),
+-
+-  removeAllSessionCookies: Task.async(function* (host, domain) {
++  },
++
++  async removeAllSessionCookies(host, domain) {
+     let doc = this.storageActor.document;
+     this.removeAllSessionCookies(host, domain, doc.nodePrincipal
+         .originAttributes);
+-  }),
++  },
+ 
+   maybeSetupChildProcess() {
+     cookieHelpers.onCookieChanged = this.onCookieChanged.bind(this);
+ 
+     if (!DebuggerServer.isInChildProcess) {
+       this.getCookiesFromHost =
+         cookieHelpers.getCookiesFromHost.bind(cookieHelpers);
+       this.addCookieObservers =
+@@ -1167,65 +1166,65 @@ function getObjectForLocalOrSessionStora
+       for (let window of this.windows) {
+         let host = this.getHostName(window.location);
+         if (host) {
+           this.populateStoresForHost(host, window);
+         }
+       }
+     },
+ 
+-    getFields: Task.async(function* () {
++    async getFields() {
+       return [
+         { name: "name", editable: true },
+         { name: "value", editable: true }
+       ];
+-    }),
+-
+-    addItem: Task.async(function* (guid, host) {
++    },
++
++    async addItem(guid, host) {
+       let storage = this.hostVsStores.get(host);
+       if (!storage) {
+         return;
+       }
+       storage.setItem(guid, DEFAULT_VALUE);
+-    }),
++    },
+ 
+     /**
+      * Edit localStorage or sessionStorage fields.
+      *
+      * @param {Object} data
+      *        See editCookie() for format details.
+      */
+-    editItem: Task.async(function* ({host, field, oldValue, items}) {
++    async editItem({host, field, oldValue, items}) {
+       let storage = this.hostVsStores.get(host);
+       if (!storage) {
+         return;
+       }
+ 
+       if (field === "name") {
+         storage.removeItem(oldValue);
+       }
+ 
+       storage.setItem(items.name, items.value);
+-    }),
+-
+-    removeItem: Task.async(function* (host, name) {
++    },
++
++    async removeItem(host, name) {
+       let storage = this.hostVsStores.get(host);
+       if (!storage) {
+         return;
+       }
+       storage.removeItem(name);
+-    }),
+-
+-    removeAll: Task.async(function* (host) {
++    },
++
++    async removeAll(host) {
+       let storage = this.hostVsStores.get(host);
+       if (!storage) {
+         return;
+       }
+       storage.clear();
+-    }),
++    },
+ 
+     observe(subject, topic, data) {
+       if ((topic != "dom-storage2-changed" &&
+            topic != "dom-private-storage2-changed") ||
+           data != type) {
+         return null;
+       }
+ 
+@@ -1286,17 +1285,17 @@ StorageActors.createActor({
+ StorageActors.createActor({
+   typeName: "sessionStorage",
+   observationTopics: ["dom-storage2-changed", "dom-private-storage2-changed"]
+ }, getObjectForLocalOrSessionStorage("sessionStorage"));
+ 
+ StorageActors.createActor({
+   typeName: "Cache"
+ }, {
+-  getCachesForHost: Task.async(function* (host) {
++  async getCachesForHost(host) {
+     let uri = Services.io.newURI(host);
+     let attrs = this.storageActor
+                     .document
+                     .nodePrincipal
+                     .originAttributes;
+     let principal =
+       Services.scriptSecurityManager.createCodebasePrincipal(uri, attrs);
+ 
+@@ -1309,23 +1308,23 @@ StorageActors.createActor({
+     let { CacheStorage } = this.storageActor.window;
+ 
+     if (!CacheStorage) {
+       return [];
+     }
+ 
+     let cache = new CacheStorage("content", principal);
+     return cache;
+-  }),
+-
+-  preListStores: Task.async(function* () {
++  },
++
++  async preListStores() {
+     for (let host of this.hosts) {
+-      yield this.populateStoresForHost(host);
++      await this.populateStoresForHost(host);
+     }
+-  }),
++  },
+ 
+   form(form, detail) {
+     if (detail === "actorid") {
+       return this.actorID;
+     }
+ 
+     let hosts = {};
+     for (let host of this.hosts) {
+@@ -1340,62 +1339,62 @@ StorageActors.createActor({
+ 
+   getNamesForHost(host) {
+     // UI code expect each name to be a JSON string of an array :/
+     return [...this.hostVsStores.get(host).keys()].map(a => {
+       return JSON.stringify([a]);
+     });
+   },
+ 
+-  getValuesForHost: Task.async(function* (host, name) {
++  async getValuesForHost(host, name) {
+     if (!name) {
+       return [];
+     }
+     // UI is weird and expect a JSON stringified array... and pass it back :/
+     name = JSON.parse(name)[0];
+ 
+     let cache = this.hostVsStores.get(host).get(name);
+-    let requests = yield cache.keys();
++    let requests = await cache.keys();
+     let results = [];
+     for (let request of requests) {
+-      let response = yield cache.match(request);
++      let response = await cache.match(request);
+       // Unwrap the response to get access to all its properties if the
+       // response happen to be 'opaque', when it is a Cross Origin Request.
+       response = response.cloneUnfiltered();
+-      results.push(yield this.processEntry(request, response));
++      results.push(await this.processEntry(request, response));
+     }
+     return results;
+-  }),
+-
+-  processEntry: Task.async(function* (request, response) {
++  },
++
++  async processEntry(request, response) {
+     return {
+       url: String(request.url),
+       status: String(response.statusText),
+     };
+-  }),
+-
+-  getFields: Task.async(function* () {
++  },
++
++  async getFields() {
+     return [
+       { name: "url", editable: false },
+       { name: "status", editable: false }
+     ];
+-  }),
+-
+-  populateStoresForHost: Task.async(function* (host) {
++  },
++
++  async populateStoresForHost(host) {
+     let storeMap = new Map();
+-    let caches = yield this.getCachesForHost(host);
++    let caches = await this.getCachesForHost(host);
+     try {
+-      for (let name of (yield caches.keys())) {
+-        storeMap.set(name, (yield caches.open(name)));
++      for (let name of (await caches.keys())) {
++        storeMap.set(name, (await caches.open(name)));
+       }
+     } catch (ex) {
+       console.warn(`Failed to enumerate CacheStorage for host ${host}: ${ex}`);
+     }
+     this.hostVsStores.set(host, storeMap);
+-  }),
++  },
+ 
+   /**
+    * This method is overriden and left blank as for Cache Storage, this
+    * operation cannot be performed synchronously. Thus, the preListStores
+    * method exists to do the same task asynchronously.
+    */
+   populateStoresForHosts() {
+     this.hostVsStores = new Map();
+@@ -1408,61 +1407,61 @@ StorageActors.createActor({
+     let uri = Services.io.newURI(url);
+     return uri.scheme + "://" + uri.hostPort;
+   },
+ 
+   toStoreObject(item) {
+     return item;
+   },
+ 
+-  removeItem: Task.async(function* (host, name) {
++  async removeItem(host, name) {
+     const cacheMap = this.hostVsStores.get(host);
+     if (!cacheMap) {
+       return;
+     }
+ 
+     const parsedName = JSON.parse(name);
+ 
+     if (parsedName.length == 1) {
+       // Delete the whole Cache object
+       const [ cacheName ] = parsedName;
+       cacheMap.delete(cacheName);
+-      const cacheStorage = yield this.getCachesForHost(host);
+-      yield cacheStorage.delete(cacheName);
++      const cacheStorage = await this.getCachesForHost(host);
++      await cacheStorage.delete(cacheName);
+       this.onItemUpdated("deleted", host, [ cacheName ]);
+     } else if (parsedName.length == 2) {
+       // Delete one cached request
+       const [ cacheName, url ] = parsedName;
+       const cache = cacheMap.get(cacheName);
+       if (cache) {
+-        yield cache.delete(url);
++        await cache.delete(url);
+         this.onItemUpdated("deleted", host, [ cacheName, url ]);
+       }
+     }
+-  }),
+-
+-  removeAll: Task.async(function* (host, name) {
++  },
++
++  async removeAll(host, name) {
+     const cacheMap = this.hostVsStores.get(host);
+     if (!cacheMap) {
+       return;
+     }
+ 
+     const parsedName = JSON.parse(name);
+ 
+     // Only a Cache object is a valid object to clear
+     if (parsedName.length == 1) {
+       const [ cacheName ] = parsedName;
+       const cache = cacheMap.get(cacheName);
+       if (cache) {
+-        let keys = yield cache.keys();
+-        yield Promise.all(keys.map(key => cache.delete(key)));
++        let keys = await cache.keys();
++        await Promise.all(keys.map(key => cache.delete(key)));
+         this.onItemUpdated("cleared", host, [ cacheName ]);
+       }
+     }
+-  }),
++  },
+ 
+   /**
+    * CacheStorage API doesn't support any notifications, we must fake them
+    */
+   onItemUpdated(action, host, path) {
+     this.storageActor.update(action, "Cache", {
+       [host]: [ JSON.stringify(path) ]
+     });
+@@ -1615,49 +1614,49 @@ StorageActors.createActor({
+     protocol.Actor.prototype.destroy.call(this);
+ 
+     this.storageActor = null;
+   },
+ 
+   /**
+    * Remove an indexedDB database from given host with a given name.
+    */
+-  removeDatabase: Task.async(function* (host, name) {
++  async removeDatabase(host, name) {
+     let win = this.storageActor.getWindowFromHost(host);
+     if (!win) {
+       return { error: `Window for host ${host} not found` };
+     }
+ 
+     let principal = win.document.nodePrincipal;
+     return this.removeDB(host, principal, name);
+-  }),
+-
+-  removeAll: Task.async(function* (host, name) {
++  },
++
++  async removeAll(host, name) {
+     let [db, store] = JSON.parse(name);
+ 
+     let win = this.storageActor.getWindowFromHost(host);
+     if (!win) {
+       return;
+     }
+ 
+     let principal = win.document.nodePrincipal;
+     this.clearDBStore(host, principal, db, store);
+-  }),
+-
+-  removeItem: Task.async(function* (host, name) {
++  },
++
++  async removeItem(host, name) {
+     let [db, store, id] = JSON.parse(name);
+ 
+     let win = this.storageActor.getWindowFromHost(host);
+     if (!win) {
+       return;
+     }
+ 
+     let principal = win.document.nodePrincipal;
+     this.removeDBRecord(host, principal, db, store, id);
+-  }),
++  },
+ 
+   /**
+    * This method is overriden and left blank as for indexedDB, this operation
+    * cannot be performed synchronously. Thus, the preListStores method exists to
+    * do the same task asynchronously.
+    */
+   populateStoresForHosts() {},
+ 
+@@ -1727,43 +1726,43 @@ StorageActors.createActor({
+   },
+ 
+   /**
+    * Purpose of this method is same as populateStoresForHosts but this is async.
+    * This exact same operation cannot be performed in populateStoresForHosts
+    * method, as that method is called in initialize method of the actor, which
+    * cannot be asynchronous.
+    */
+-  preListStores: Task.async(function* () {
++  async preListStores() {
+     this.hostVsStores = new Map();
+ 
+     for (let host of this.hosts) {
+-      yield this.populateStoresForHost(host);
++      await this.populateStoresForHost(host);
+     }
+-  }),
+-
+-  populateStoresForHost: Task.async(function* (host) {
++  },
++
++  async populateStoresForHost(host) {
+     let storeMap = new Map();
+ 
+     let win = this.storageActor.getWindowFromHost(host);
+     if (win) {
+       let principal = win.document.nodePrincipal;
+-      let {names} = yield this.getDBNamesForHost(host, principal);
++      let {names} = await this.getDBNamesForHost(host, principal);
+ 
+       for (let {name, storage} of names) {
+-        let metadata = yield this.getDBMetaData(host, principal, name, storage);
++        let metadata = await this.getDBMetaData(host, principal, name, storage);
+ 
+         metadata = indexedDBHelpers.patchMetadataMapsAndProtos(metadata);
+ 
+         storeMap.set(`${name} (${storage})`, metadata);
+       }
+     }
+ 
+     this.hostVsStores.set(host, storeMap);
+-  }),
++  },
+ 
+   /**
+    * Returns the over-the-wire implementation of the indexed db entity.
+    */
+   toStoreObject(item) {
+     if (!item) {
+       return null;
+     }
+@@ -1900,17 +1899,17 @@ StorageActors.createActor({
+         method: methodName,
+         args: args
+       });
+ 
+       return deferred.promise;
+     }
+   },
+ 
+-  getFields: Task.async(function* (subType) {
++  async getFields(subType) {
+     switch (subType) {
+       // Detail of database
+       case "database":
+         return [
+           { name: "objectStore", editable: false },
+           { name: "keyPath", editable: false },
+           { name: "autoIncrement", editable: false },
+           { name: "indexes", editable: false },
+@@ -1929,17 +1928,17 @@ StorageActors.createActor({
+           { name: "uniqueKey", editable: false, private: true },
+           { name: "db", editable: false },
+           { name: "storage", editable: false },
+           { name: "origin", editable: false },
+           { name: "version", editable: false },
+           { name: "objectStores", editable: false },
+         ];
+     }
+-  })
++  }
+ });
+ 
+ var indexedDBHelpers = {
+   backToChild(...args) {
+     let mm = Cc["@mozilla.org/globalmessagemanager;1"]
+                .getService(Ci.nsIMessageListenerManager);
+ 
+     mm.broadcastAsyncMessage("debug:storage-indexedDB-request-child", {
+@@ -1958,34 +1957,34 @@ var indexedDBHelpers = {
+     });
+   },
+ 
+   /**
+    * Fetches and stores all the metadata information for the given database
+    * `name` for the given `host` with its `principal`. The stored metadata
+    * information is of `DatabaseMetadata` type.
+    */
+-  getDBMetaData: Task.async(function* (host, principal, name, storage) {
++  async getDBMetaData(host, principal, name, storage) {
+     let request = this.openWithPrincipal(principal, name, storage);
+     let success = defer();
+ 
+     request.onsuccess = event => {
+       let db = event.target.result;
+       let dbData = new DatabaseMetadata(host, db, storage);
+       db.close();
+ 
+       success.resolve(this.backToChild("getDBMetaData", dbData));
+     };
+     request.onerror = ({target}) => {
+       console.error(
+         `Error opening indexeddb database ${name} for host ${host}`, target.error);
+       success.resolve(this.backToChild("getDBMetaData", null));
+     };
+     return success.promise;
+-  }),
++  },
+ 
+   splitNameAndStorage: function (name) {
+     let lastOpenBracketIndex = name.lastIndexOf("(");
+     let lastCloseBracketIndex = name.lastIndexOf(")");
+     let delta = lastCloseBracketIndex - lastOpenBracketIndex - 1;
+ 
+     let storage = name.substr(lastOpenBracketIndex + 1, delta);
+ 
+@@ -1998,17 +1997,17 @@ var indexedDBHelpers = {
+    * Opens an indexed db connection for the given `principal` and
+    * database `name`.
+    */
+   openWithPrincipal: function (principal, name, storage) {
+     return indexedDBForStorage.openForPrincipal(principal, name,
+                                                 { storage: storage });
+   },
+ 
+-  removeDB: Task.async(function* (host, principal, dbName) {
++  async removeDB(host, principal, dbName) {
+     let result = new Promise(resolve => {
+       let {name, storage} = this.splitNameAndStorage(dbName);
+       let request =
+         indexedDBForStorage.deleteForPrincipal(principal, name,
+                                                { storage: storage });
+ 
+       request.onsuccess = () => {
+         resolve({});
+@@ -2028,89 +2027,89 @@ var indexedDBHelpers = {
+       };
+ 
+       // If the database is blocked repeatedly, the onblocked event will not
+       // be fired again. To avoid waiting forever, report as blocked if nothing
+       // else happens after 3 seconds.
+       setTimeout(() => resolve({ blocked: true }), 3000);
+     });
+ 
+-    return this.backToChild("removeDB", yield result);
+-  }),
+-
+-  removeDBRecord: Task.async(function* (host, principal, dbName, storeName, id) {
++    return this.backToChild("removeDB", await result);
++  },
++
++  async removeDBRecord(host, principal, dbName, storeName, id) {
+     let db;
+     let {name, storage} = this.splitNameAndStorage(dbName);
+ 
+     try {
+-      db = yield new Promise((resolve, reject) => {
++      db = await new Promise((resolve, reject) => {
+         let request = this.openWithPrincipal(principal, name, storage);
+         request.onsuccess = ev => resolve(ev.target.result);
+         request.onerror = ev => reject(ev.target.error);
+       });
+ 
+       let transaction = db.transaction(storeName, "readwrite");
+       let store = transaction.objectStore(storeName);
+ 
+-      yield new Promise((resolve, reject) => {
++      await new Promise((resolve, reject) => {
+         let request = store.delete(id);
+         request.onsuccess = () => resolve();
+         request.onerror = ev => reject(ev.target.error);
+       });
+ 
+       this.onItemUpdated("deleted", host, [dbName, storeName, id]);
+     } catch (error) {
+       let recordPath = [dbName, storeName, id].join("/");
+       console.error(`Failed to delete indexedDB record: ${recordPath}: ${error}`);
+     }
+ 
+     if (db) {
+       db.close();
+     }
+ 
+     return this.backToChild("removeDBRecord", null);
+-  }),
+-
+-  clearDBStore: Task.async(function* (host, principal, dbName, storeName) {
++  },
++
++  async clearDBStore(host, principal, dbName, storeName) {
+     let db;
+     let {name, storage} = this.splitNameAndStorage(dbName);
+ 
+     try {
+-      db = yield new Promise((resolve, reject) => {
++      db = await new Promise((resolve, reject) => {
+         let request = this.openWithPrincipal(principal, name, storage);
+         request.onsuccess = ev => resolve(ev.target.result);
+         request.onerror = ev => reject(ev.target.error);
+       });
+ 
+       let transaction = db.transaction(storeName, "readwrite");
+       let store = transaction.objectStore(storeName);
+ 
+-      yield new Promise((resolve, reject) => {
++      await new Promise((resolve, reject) => {
+         let request = store.clear();
+         request.onsuccess = () => resolve();
+         request.onerror = ev => reject(ev.target.error);
+       });
+ 
+       this.onItemUpdated("cleared", host, [dbName, storeName]);
+     } catch (error) {
+       let storePath = [dbName, storeName].join("/");
+       console.error(`Failed to clear indexedDB store: ${storePath}: ${error}`);
+     }
+ 
+     if (db) {
+       db.close();
+     }
+ 
+     return this.backToChild("clearDBStore", null);
+-  }),
++  },
+ 
+   /**
+    * Fetches all the databases and their metadata for the given `host`.
+    */
+-  getDBNamesForHost: Task.async(function* (host, principal) {
++  async getDBNamesForHost(host, principal) {
+     let sanitizedHost = this.getSanitizedHost(host) + principal.originSuffix;
+     let profileDir = OS.Constants.Path.profileDir;
+     let files = [];
+     let names = [];
+     let storagePath = OS.Path.join(profileDir, "storage");
+ 
+     // We expect sqlite DB paths to look something like this:
+     // - PathToProfileDir/storage/default/http+++www.example.com/
+@@ -2119,145 +2118,145 @@ var indexedDBHelpers = {
+     //   idb/1556056096MeysDaabta.sqlite
+     // - PathToProfileDir/storage/temporary/http+++www.example.com/
+     //   idb/1556056096MeysDaabta.sqlite
+     // The subdirectory inside the storage folder is determined by the storage
+     // type:
+     // - default:   { storage: "default" } or not specified.
+     // - permanent: { storage: "persistent" }.
+     // - temporary: { storage: "temporary" }.
+-    let sqliteFiles = yield this.findSqlitePathsForHost(storagePath, sanitizedHost);
++    let sqliteFiles = await this.findSqlitePathsForHost(storagePath, sanitizedHost);
+ 
+     for (let file of sqliteFiles) {
+       let splitPath = OS.Path.split(file).components;
+       let idbIndex = splitPath.indexOf("idb");
+       let storage = splitPath[idbIndex - 2];
+       let relative = file.substr(profileDir.length + 1);
+ 
+       files.push({
+         file: relative,
+         storage: storage === "permanent" ? "persistent" : storage
+       });
+     }
+ 
+     if (files.length > 0) {
+       for (let {file, storage} of files) {
+-        let name = yield this.getNameFromDatabaseFile(file);
++        let name = await this.getNameFromDatabaseFile(file);
+         if (name) {
+           names.push({
+             name,
+             storage
+           });
+         }
+       }
+     }
+ 
+     return this.backToChild("getDBNamesForHost", {names});
+-  }),
++  },
+ 
+   /**
+    * Find all SQLite files that hold IndexedDB data for a host, such as:
+    *   storage/temporary/http+++www.example.com/idb/1556056096MeysDaabta.sqlite
+    */
+-  findSqlitePathsForHost: Task.async(function* (storagePath, sanitizedHost) {
++  async findSqlitePathsForHost(storagePath, sanitizedHost) {
+     let sqlitePaths = [];
+-    let idbPaths = yield this.findIDBPathsForHost(storagePath, sanitizedHost);
++    let idbPaths = await this.findIDBPathsForHost(storagePath, sanitizedHost);
+     for (let idbPath of idbPaths) {
+       let iterator = new OS.File.DirectoryIterator(idbPath);
+-      yield iterator.forEach(entry => {
++      await iterator.forEach(entry => {
+         if (!entry.isDir && entry.path.endsWith(".sqlite")) {
+           sqlitePaths.push(entry.path);
+         }
+       });
+       iterator.close();
+     }
+     return sqlitePaths;
+-  }),
++  },
+ 
+   /**
+    * Find all paths that hold IndexedDB data for a host, such as:
+    *   storage/temporary/http+++www.example.com/idb
+    */
+-  findIDBPathsForHost: Task.async(function* (storagePath, sanitizedHost) {
++  async findIDBPathsForHost(storagePath, sanitizedHost) {
+     let idbPaths = [];
+-    let typePaths = yield this.findStorageTypePaths(storagePath);
++    let typePaths = await this.findStorageTypePaths(storagePath);
+     for (let typePath of typePaths) {
+       let idbPath = OS.Path.join(typePath, sanitizedHost, "idb");
+-      if (yield OS.File.exists(idbPath)) {
++      if (await OS.File.exists(idbPath)) {
+         idbPaths.push(idbPath);
+       }
+     }
+     return idbPaths;
+-  }),
++  },
+ 
+   /**
+    * Find all the storage types, such as "default", "permanent", or "temporary".
+    * These names have changed over time, so it seems simpler to look through all types
+    * that currently exist in the profile.
+    */
+-  findStorageTypePaths: Task.async(function* (storagePath) {
++  async findStorageTypePaths(storagePath) {
+     let iterator = new OS.File.DirectoryIterator(storagePath);
+     let typePaths = [];
+-    yield iterator.forEach(entry => {
++    await iterator.forEach(entry => {
+       if (entry.isDir) {
+         typePaths.push(entry.path);
+       }
+     });
+     iterator.close();
+     return typePaths;
+-  }),
++  },
+ 
+   /**
+    * Removes any illegal characters from the host name to make it a valid file
+    * name.
+    */
+   getSanitizedHost(host) {
+     if (host.startsWith("about:")) {
+       host = "moz-safe-" + host;
+     }
+     return host.replace(ILLEGAL_CHAR_REGEX, "+");
+   },
+ 
+   /**
+    * Retrieves the proper indexed db database name from the provided .sqlite
+    * file location.
+    */
+-  getNameFromDatabaseFile: Task.async(function* (path) {
++  async getNameFromDatabaseFile(path) {
+     let connection = null;
+     let retryCount = 0;
+ 
+     // Content pages might be having an open transaction for the same indexed db
+     // which this sqlite file belongs to. In that case, sqlite.openConnection
+     // will throw. Thus we retry for some time to see if lock is removed.
+     while (!connection && retryCount++ < 25) {
+       try {
+-        connection = yield Sqlite.openConnection({ path: path });
++        connection = await Sqlite.openConnection({ path: path });
+       } catch (ex) {
+         // Continuously retrying is overkill. Waiting for 100ms before next try
+-        yield sleep(100);
++        await sleep(100);
+       }
+     }
+ 
+     if (!connection) {
+       return null;
+     }
+ 
+-    let rows = yield connection.execute("SELECT name FROM database");
++    let rows = await connection.execute("SELECT name FROM database");
+     if (rows.length != 1) {
+       return null;
+     }
+ 
+     let name = rows[0].getResultByName("name");
+ 
+-    yield connection.close();
++    await connection.close();
+ 
+     return name;
+-  }),
+-
+-  getValuesForHost: Task.async(function* (host, name = "null", options,
++  },
++
++  async getValuesForHost(host, name = "null", options,
+                                           hostVsStores, principal) {
+     name = JSON.parse(name);
+     if (!name || !name.length) {
+       // This means that details about the db in this particular host are
+       // requested.
+       let dbs = [];
+       if (hostVsStores.has(host)) {
+         for (let [, db] of hostVsStores.get(host)) {
+@@ -2283,25 +2282,25 @@ var indexedDBHelpers = {
+         for (let objectStore2 of objectStores2) {
+           objectStores.push(objectStore2[1].toObject());
+         }
+       }
+       return this.backToChild("getValuesForHost", {objectStores: objectStores});
+     }
+     // Get either all entries from the object store, or a particular id
+     let storage = hostVsStores.get(host).get(db2).storage;
+-    let result = yield this.getObjectStoreData(host, principal, db2, storage, {
++    let result = await this.getObjectStoreData(host, principal, db2, storage, {
+       objectStore: objectStore,
+       id: id,
+       index: options.index,
+       offset: 0,
+       size: options.size
+     });
+     return this.backToChild("getValuesForHost", {result: result});
+-  }),
++  },
+ 
+   /**
+    * Returns all or requested entries from a particular objectStore from the db
+    * in the given host.
+    *
+    * @param {string} host
+    *        The given host.
+    * @param {nsIPrincipal} principal
+@@ -2698,28 +2697,28 @@ let StorageActor = protocol.ActorClassWi
+    * Lists the available hosts for all the registered storage types.
+    *
+    * @returns {object} An object containing with the following structure:
+    *  - <storageType> : [{
+    *      actor: <actorId>,
+    *      host: <hostname>
+    *    }]
+    */
+-  listStores: Task.async(function* () {
++  async listStores() {
+     let toReturn = {};
+ 
+     for (let [name, value] of this.childActorPool) {
+       if (value.preListStores) {
+-        yield value.preListStores();
++        await value.preListStores();
+       }
+       toReturn[name] = value;
+     }
+ 
+     return toReturn;
+-  }),
++  },
+ 
+   /**
+    * This method is called by the registered storage types so as to tell the
+    * Storage Actor that there are some changes in the stores. Storage Actor then
+    * notifies the client front about these changes at regular (BATCH_DELAY)
+    * interval.
+    *
+    * @param {string} action
+diff --git a/devtools/server/actors/styles.js b/devtools/server/actors/styles.js
+--- a/devtools/server/actors/styles.js
++++ b/devtools/server/actors/styles.js
+@@ -2,17 +2,16 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {Ci} = require("chrome");
+ const protocol = require("devtools/shared/protocol");
+ const {LongStringActor} = require("devtools/server/actors/string");
+-const {Task} = require("devtools/shared/task");
+ 
+ // This will also add the "stylesheet" actor type for protocol.js to recognize
+ 
+ const {pageStyleSpec, styleRuleSpec, ELEMENT_STYLE} = require("devtools/shared/specs/styles");
+ 
+ loader.lazyRequireGetter(this, "CssLogic", "devtools/server/css-logic", true);
+ loader.lazyRequireGetter(this, "SharedCssLogic", "devtools/shared/inspector/css-logic");
+ loader.lazyRequireGetter(this, "getDefinedGeometryProperties",
+@@ -440,54 +439,54 @@ var PageStyleActor = protocol.ActorClass
+    *     'user': Include properties from user style sheets.
+    *     'ua': Include properties from user and user-agent sheets.
+    *     Default value is 'ua'
+    *   `inherited`: Include styles inherited from parent nodes.
+    *   `matchedSelectors`: Include an array of specific selectors that
+    *     caused this rule to match its node.
+    *   `skipPseudo`: Exclude styles applied to pseudo elements of the provided node.
+    */
+-  getApplied: Task.async(function* (node, options) {
++  async getApplied(node, options) {
+     if (!node) {
+       return {entries: [], rules: [], sheets: []};
+     }
+ 
+     this.cssLogic.highlight(node.rawNode);
+     let entries = [];
+     entries = entries.concat(this._getAllElementRules(node, undefined,
+                                                       options));
+ 
+     let result = this.getAppliedProps(node, entries, options);
+     for (let rule of result.rules) {
+       // See the comment in |form| to understand this.
+-      yield rule.getAuthoredCssText();
++      await rule.getAuthoredCssText();
+     }
+     return result;
+-  }),
++  },
+ 
+   _hasInheritedProps: function (style) {
+     return Array.prototype.some.call(style, prop => {
+       return DOMUtils.isInheritedProperty(prop);
+     });
+   },
+ 
+-  isPositionEditable: Task.async(function* (node) {
++  async isPositionEditable(node) {
+     if (!node || node.rawNode.nodeType !== node.rawNode.ELEMENT_NODE) {
+       return false;
+     }
+ 
+     let props = getDefinedGeometryProperties(node.rawNode);
+ 
+     // Elements with only `width` and `height` are currently not considered
+     // editable.
+     return props.has("top") ||
+            props.has("right") ||
+            props.has("left") ||
+            props.has("bottom");
+-  }),
++  },
+ 
+   /**
+    * Helper function for getApplied, gets all the rules from a given
+    * element. See getApplied for documentation on parameters.
+    * @param NodeActor node
+    * @param bool inherited
+    * @param object options
+ 
+@@ -890,17 +889,17 @@ var PageStyleActor = protocol.ActorClass
+    * @param {String} pseudoClasses The list of pseudo classes to append to the
+    *        new selector.
+    * @param {Boolean} editAuthored
+    *        True if the selector should be updated by editing the
+    *        authored text; false if the selector should be updated via
+    *        CSSOM.
+    * @returns {StyleRuleActor} the new rule
+    */
+-  addNewRule: Task.async(function* (node, pseudoClasses, editAuthored = false) {
++  async addNewRule(node, pseudoClasses, editAuthored = false) {
+     let style = this.getStyleElement(node.rawNode.ownerDocument);
+     let sheet = style.sheet;
+     let cssRules = sheet.cssRules;
+     let rawNode = node.rawNode;
+     let classes = [...rawNode.classList];
+ 
+     let selector;
+     if (rawNode.id) {
+@@ -916,23 +915,23 @@ var PageStyleActor = protocol.ActorClass
+     }
+ 
+     let index = sheet.insertRule(selector + " {}", cssRules.length);
+ 
+     // If inserting the rule succeeded, go ahead and edit the source
+     // text if requested.
+     if (editAuthored) {
+       let sheetActor = this._sheetRef(sheet);
+-      let {str: authoredText} = yield sheetActor.getText();
++      let {str: authoredText} = await sheetActor.getText();
+       authoredText += "\n" + selector + " {\n" + "}";
+-      yield sheetActor.update(authoredText, false);
++      await sheetActor.update(authoredText, false);
+     }
+ 
+     return this.getNewAppliedProps(node, sheet.cssRules.item(index));
+-  })
++  }
+ });
+ exports.PageStyleActor = PageStyleActor;
+ 
+ /**
+  * An actor that represents a CSS style object on the protocol.
+  *
+  * We slightly flatten the CSSOM for this actor, it represents
+  * both the CSSRule and CSSStyle objects in one actor.  For nodes
+@@ -1252,40 +1251,40 @@ var StyleRuleActor = protocol.ActorClass
+ 
+   /**
+    * Set the contents of the rule.  This rewrites the rule in the
+    * stylesheet and causes it to be re-evaluated.
+    *
+    * @param {String} newText the new text of the rule
+    * @returns the rule with updated properties
+    */
+-  setRuleText: Task.async(function* (newText) {
++  async setRuleText(newText) {
+     if (!this.canSetRuleText) {
+       throw new Error("invalid call to setRuleText");
+     }
+ 
+     if (this.type === ELEMENT_STYLE) {
+       // For element style rules, set the node's style attribute.
+       this.rawNode.setAttribute("style", newText);
+     } else {
+       // For stylesheet rules, set the text in the stylesheet.
+       let parentStyleSheet = this.pageStyle._sheetRef(this._parentSheet);
+-      let {str: cssText} = yield parentStyleSheet.getText();
++      let {str: cssText} = await parentStyleSheet.getText();
+ 
+       let {offset, text} = getRuleText(cssText, this.line, this.column);
+       cssText = cssText.substring(0, offset) + newText +
+         cssText.substring(offset + text.length);
+ 
+-      yield parentStyleSheet.update(cssText, false, UPDATE_PRESERVING_RULES);
++      await parentStyleSheet.update(cssText, false, UPDATE_PRESERVING_RULES);
+     }
+ 
+     this.authoredText = newText;
+ 
+     return this;
+-  }),
++  },
+ 
+   /**
+    * Modify a rule's properties. Passed an array of modifications:
+    * {
+    *   type: "set",
+    *   name: <string>,
+    *   value: <string>,
+    *   priority: <optional string>
+@@ -1342,37 +1341,37 @@ var StyleRuleActor = protocol.ActorClass
+    * @param {Boolean} editAuthored
+    *        True if the selector should be updated by editing the
+    *        authored text; false if the selector should be updated via
+    *        CSSOM.
+    *
+    * @returns {CSSRule}
+    *        The new CSS rule added
+    */
+-  _addNewSelector: Task.async(function* (value, editAuthored) {
++  async _addNewSelector(value, editAuthored) {
+     let rule = this.rawRule;
+     let parentStyleSheet = this._parentSheet;
+ 
+     // We know the selector modification is ok, so if the client asked
+     // for the authored text to be edited, do it now.
+     if (editAuthored) {
+       let document = this.getDocument(this._parentSheet);
+       try {
+         document.querySelector(value);
+       } catch (e) {
+         return null;
+       }
+ 
+       let sheetActor = this.pageStyle._sheetRef(parentStyleSheet);
+-      let {str: authoredText} = yield sheetActor.getText();
++      let {str: authoredText} = await sheetActor.getText();
+       let [startOffset, endOffset] = getSelectorOffsets(authoredText, this.line,
+                                                         this.column);
+       authoredText = authoredText.substring(0, startOffset) + value +
+         authoredText.substring(endOffset);
+-      yield sheetActor.update(authoredText, false, UPDATE_PRESERVING_RULES);
++      await sheetActor.update(authoredText, false, UPDATE_PRESERVING_RULES);
+     } else {
+       let cssRules = parentStyleSheet.cssRules;
+       let cssText = rule.cssText;
+       let selectorText = rule.selectorText;
+ 
+       for (let i = 0; i < cssRules.length; i++) {
+         if (rule === cssRules.item(i)) {
+           try {
+@@ -1386,32 +1385,32 @@ var StyleRuleActor = protocol.ActorClass
+             // The selector could be invalid, or the rule could fail to insert.
+             return null;
+           }
+         }
+       }
+     }
+ 
+     return this._getRuleFromIndex(parentStyleSheet);
+-  }),
++  },
+ 
+   /**
+    * Modify the current rule's selector by inserting a new rule with the new
+    * selector value and removing the current rule.
+    *
+    * Note this method was kept for backward compatibility, but unmatched rules
+    * support was added in FF41.
+    *
+    * @param string value
+    *        The new selector value
+    * @returns boolean
+    *        Returns a boolean if the selector in the stylesheet was modified,
+    *        and false otherwise
+    */
+-  modifySelector: Task.async(function* (value) {
++  async modifySelector(value) {
+     if (this.type === ELEMENT_STYLE) {
+       return false;
+     }
+ 
+     let document = this.getDocument(this._parentSheet);
+     // Extract the selector, and pseudo elements and classes
+     let [selector] = value.split(/(:{1,2}.+$)/);
+     let selectorElement;
+@@ -1420,21 +1419,21 @@ var StyleRuleActor = protocol.ActorClass
+       selectorElement = document.querySelector(selector);
+     } catch (e) {
+       return false;
+     }
+ 
+     // Check if the selector is valid and not the same as the original
+     // selector
+     if (selectorElement && this.rawRule.selectorText !== value) {
+-      yield this._addNewSelector(value, false);
++      await this._addNewSelector(value, false);
+       return true;
+     }
+     return false;
+-  }),
++  },
+ 
+   /**
+    * Modify the current rule's selector by inserting a new rule with the new
+    * selector value and removing the current rule.
+    *
+    * In contrast with the modifySelector method which was used before FF41,
+    * this method also returns information about the new rule and applied style
+    * so that consumers can immediately display the new rule, whether or not the
+diff --git a/devtools/server/actors/stylesheets.js b/devtools/server/actors/stylesheets.js
+--- a/devtools/server/actors/stylesheets.js
++++ b/devtools/server/actors/stylesheets.js
+@@ -2,17 +2,16 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const {Ci} = require("chrome");
+ const Services = require("Services");
+ const defer = require("devtools/shared/defer");
+-const {Task} = require("devtools/shared/task");
+ const protocol = require("devtools/shared/protocol");
+ const {LongStringActor} = require("devtools/server/actors/string");
+ const {fetch} = require("devtools/shared/DevToolsUtils");
+ const {mediaRuleSpec, styleSheetSpec,
+        styleSheetsSpec} = require("devtools/shared/specs/stylesheets");
+ const {
+   addPseudoClassLock, removePseudoClassLock } = require("devtools/server/actors/highlighters/utils/markup");
+ 
+@@ -416,17 +415,17 @@ var StyleSheetActor = protocol.ActorClas
+    * @param  {String} href
+    *         The href of the stylesheet to retrieve.
+    * @return {Promise} a promise that resolves with an object with the following members
+    *         on success:
+    *           - content: the document at that URL, as a string,
+    *           - contentType: the content type of the document
+    *         If an error occurs, the promise is rejected with that error.
+    */
+-  fetchStylesheet: Task.async(function* (href) {
++  async fetchStylesheet(href) {
+     // Check if network monitor observed this load, and if so, use that.
+     let result = this.fetchStylesheetFromNetworkMonitor(href);
+     if (result) {
+       return result;
+     }
+ 
+     let options = {
+       loadFromCache: true,
+@@ -443,29 +442,29 @@ var StyleSheetActor = protocol.ActorClas
+     let excludedProtocolsRe = /^(chrome|file|resource|moz-extension):\/\//;
+     if (!excludedProtocolsRe.test(this.href)) {
+       // Stylesheets using other protocols should use the content principal.
+       options.window = this.ownerWindow;
+       options.principal = this.ownerDocument.nodePrincipal;
+     }
+ 
+     try {
+-      result = yield fetch(this.href, options);
++      result = await fetch(this.href, options);
+     } catch (e) {
+       // The list of excluded protocols can be missing some protocols, try to use the
+       // system principal if the first fetch failed.
+       console.error(`stylesheets actor: fetch failed for ${this.href},` +
+         ` using system principal instead.`);
+       options.window = undefined;
+       options.principal = undefined;
+-      result = yield fetch(this.href, options);
++      result = await fetch(this.href, options);
+     }
+ 
+     return result;
+-  }),
++  },
+ 
+   /**
+    * Try to locate the console actor if it exists via our parent actor (the tab).
+    */
+   get _consoleActor() {
+     if (this.parentActor.exited) {
+       return null;
+     }
+@@ -737,25 +736,25 @@ var StyleSheetsActor = protocol.ActorCla
+     this.emit("stylesheet-added", actor, this._nextStyleSheetIsNew);
+     this._nextStyleSheetIsNew = false;
+   },
+ 
+   /**
+    * Protocol method for getting a list of StyleSheetActors representing
+    * all the style sheets in this document.
+    */
+-  getStyleSheets: Task.async(function* () {
++  async getStyleSheets() {
+     let actors = [];
+ 
+     for (let win of this.parentActor.windows) {
+-      let sheets = yield this._addStyleSheets(win);
++      let sheets = await this._addStyleSheets(win);
+       actors = actors.concat(sheets);
+     }
+     return actors;
+-  }),
++  },
+ 
+   /**
+    * Check if we should be showing this stylesheet.
+    *
+    * @param {DOMCSSStyleSheet} sheet
+    *        Stylesheet we're interested in
+    *
+    * @return boolean
+@@ -794,17 +793,17 @@ var StyleSheetsActor = protocol.ActorCla
+    *
+    * @param {Window} win
+    *        Window for which to add stylesheets
+    *
+    * @return {Promise}
+    *         Promise that resolves to an array of StyleSheetActors
+    */
+   _addStyleSheets: function (win) {
+-    return Task.spawn(function* () {
++    return (async function () {
+       let doc = win.document;
+       // We have to set this flag in order to get the
+       // StyleSheetApplicableStateChanged events.  See Document.webidl.
+       doc.styleSheetChangeEventsEnabled = true;
+ 
+       let isChrome = Services.scriptSecurityManager.isSystemPrincipal(doc.nodePrincipal);
+       let styleSheets = isChrome ? DOMUtils.getAllStyleSheets(doc) : doc.styleSheets;
+       let actors = [];
+@@ -813,36 +812,36 @@ var StyleSheetsActor = protocol.ActorCla
+         if (!this._shouldListSheet(sheet)) {
+           continue;
+         }
+ 
+         let actor = this.parentActor.createStyleSheetActor(sheet);
+         actors.push(actor);
+ 
+         // Get all sheets, including imported ones
+-        let imports = yield this._getImported(doc, actor);
++        let imports = await this._getImported(doc, actor);
+         actors = actors.concat(imports);
+       }
+       return actors;
+-    }.bind(this));
++    }.bind(this))();
+   },
+ 
+   /**
+    * Get all the stylesheets @imported from a stylesheet.
+    *
+    * @param  {Document} doc
+    *         The document including the stylesheet
+    * @param  {DOMStyleSheet} styleSheet
+    *         Style sheet to search
+    * @return {Promise}
+    *         A promise that resolves with an array of StyleSheetActors
+    */
+   _getImported: function (doc, styleSheet) {
+-    return Task.spawn(function* () {
+-      let rules = yield styleSheet.getCSSRules();
++    return (async function () {
++      let rules = await styleSheet.getCSSRules();
+       let imported = [];
+ 
+       for (let i = 0; i < rules.length; i++) {
+         let rule = rules[i];
+         if (rule.type == Ci.nsIDOMCSSRule.IMPORT_RULE) {
+           // With the Gecko style system, the associated styleSheet may be null
+           // if it has already been seen because an import cycle for the same
+           // URL.  With Stylo, the styleSheet will exist (which is correct per
+@@ -852,26 +851,26 @@ var StyleSheetsActor = protocol.ActorCla
+           if (!sheet || this._haveAncestorWithSameURL(sheet) ||
+               !this._shouldListSheet(sheet)) {
+             continue;
+           }
+           let actor = this.parentActor.createStyleSheetActor(rule.styleSheet);
+           imported.push(actor);
+ 
+           // recurse imports in this stylesheet as well
+-          let children = yield this._getImported(doc, actor);
++          let children = await this._getImported(doc, actor);
+           imported = imported.concat(children);
+         } else if (rule.type != Ci.nsIDOMCSSRule.CHARSET_RULE) {
+           // @import rules must precede all others except @charset
+           break;
+         }
+       }
+ 
+       return imported;
+-    }.bind(this));
++    }.bind(this))();
+   },
+ 
+   /**
+    * Check all ancestors to see if this sheet's URL matches theirs as a way to
+    * detect an import cycle.
+    *
+    * @param {DOMStyleSheet} sheet
+    */
+diff --git a/devtools/server/performance/profiler.js b/devtools/server/performance/profiler.js
+--- a/devtools/server/performance/profiler.js
++++ b/devtools/server/performance/profiler.js
+@@ -4,17 +4,16 @@
+ "use strict";
+ 
+ const { Cc, Ci, Cu } = require("chrome");
+ const Services = require("Services");
+ 
+ loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
+ loader.lazyRequireGetter(this, "DevToolsUtils", "devtools/shared/DevToolsUtils");
+ loader.lazyRequireGetter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm", true);
+-loader.lazyRequireGetter(this, "Task", "devtools/shared/task", true);
+ 
+ // Events piped from system observers to Profiler instances.
+ const PROFILER_SYSTEM_EVENTS = [
+   "console-api-profiler",
+   "profiler-started",
+   "profiler-stopped"
+ ];
+ 
+diff --git a/devtools/server/performance/recorder.js b/devtools/server/performance/recorder.js
+--- a/devtools/server/performance/recorder.js
++++ b/devtools/server/performance/recorder.js
+@@ -1,15 +1,14 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ "use strict";
+ 
+ const { Cu } = require("chrome");
+-const { Task } = require("devtools/shared/task");
+ 
+ loader.lazyRequireGetter(this, "Services");
+ loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
+ 
+ loader.lazyRequireGetter(this, "Memory",
+   "devtools/server/performance/memory", true);
+ loader.lazyRequireGetter(this, "Timeline",
+   "devtools/server/performance/timeline", true);
+@@ -158,44 +157,44 @@ PerformanceRecorder.prototype = {
+    * Invoked whenever `console.profile` is called.
+    *
+    * @param string profileLabel
+    *        The provided string argument if available; undefined otherwise.
+    * @param number currentTime
+    *        The time (in milliseconds) when the call was made, relative to when
+    *        the nsIProfiler module was started.
+    */
+-  _onConsoleProfileStart: Task.async(function* ({ profileLabel, currentTime }) {
++  async _onConsoleProfileStart({ profileLabel, currentTime }) {
+     let recordings = this._recordings;
+ 
+     // Abort if a profile with this label already exists.
+     if (recordings.find(e => e.getLabel() === profileLabel)) {
+       return;
+     }
+ 
+     // Immediately emit this so the client can start setting things up,
+     // expecting a recording very soon.
+     this.emit("console-profile-start");
+ 
+-    yield this.startRecording(Object.assign({}, getPerformanceRecordingPrefs(), {
++    await this.startRecording(Object.assign({}, getPerformanceRecordingPrefs(), {
+       console: true,
+       label: profileLabel
+     }));
+-  }),
++  },
+ 
+   /**
+    * Invoked whenever `console.profileEnd` is called.
+    *
+    * @param string profileLabel
+    *        The provided string argument if available; undefined otherwise.
+    * @param number currentTime
+    *        The time (in milliseconds) when the call was made, relative to when
+    *        the nsIProfiler module was started.
+    */
+-  _onConsoleProfileEnd: Task.async(function* (data) {
++  async _onConsoleProfileEnd(data) {
+     // If no data, abort; can occur if profiler isn't running and we get a surprise
+     // call to console.profileEnd()
+     if (!data) {
+       return;
+     }
+     let { profileLabel } = data;
+ 
+     let pending = this._recordings.filter(r => r.isConsole() && r.isRecording());
+@@ -216,18 +215,18 @@ PerformanceRecorder.prototype = {
+     // If `profileEnd()` was called with a label, and there are no matching
+     // sessions, abort.
+     if (!model) {
+       Cu.reportError(
+         "console.profileEnd() called with label that does not match a recording.");
+       return;
+     }
+ 
+-    yield this.stopRecording(model);
+-  }),
++    await this.stopRecording(model);
++  },
+ 
+  /**
+   * TODO handle bug 1144438
+   */
+   _onProfilerUnexpectedlyStopped: function () {
+     Cu.reportError("Profiler unexpectedly stopped.", arguments);
+   },
+ 
+@@ -305,36 +304,36 @@ PerformanceRecorder.prototype = {
+    * @param boolean options.bufferSize
+    * @param boolean options.sampleFrequency
+    * @param boolean options.console
+    * @param string options.label
+    * @param boolean options.realtimeMarkers
+    * @return object
+    *         A promise that is resolved once recording has started.
+    */
+-  startRecording: Task.async(function* (options) {
++  async startRecording(options) {
+     let profilerStart, timelineStart, memoryStart;
+ 
+-    profilerStart = Task.spawn(function* () {
+-      let data = yield this._profiler.isActive();
++    profilerStart = (async function () {
++      let data = await this._profiler.isActive();
+       if (data.isActive) {
+         return data;
+       }
+-      let startData = yield this._profiler.start(
++      let startData = await this._profiler.start(
+         mapRecordingOptions("profiler", options)
+       );
+ 
+       // If no current time is exposed from starting, set it to 0 -- this is an
+       // older Gecko that does not return its starting time, and uses an epoch based
+       // on the profiler's start time.
+       if (startData.currentTime == null) {
+         startData.currentTime = 0;
+       }
+       return startData;
+-    }.bind(this));
++    }.bind(this))();
+ 
+     // Timeline will almost always be on if using the DevTools, but using component
+     // independently could result in no timeline.
+     if (options.withMarkers || options.withTicks || options.withMemory) {
+       timelineStart = this._timeline.start(mapRecordingOptions("timeline", options));
+     }
+ 
+     if (options.withAllocations) {
+@@ -342,17 +341,17 @@ PerformanceRecorder.prototype = {
+         this._memory.attach();
+       }
+       let recordingOptions = Object.assign(mapRecordingOptions("memory", options), {
+         drainAllocationsTimeout: DRAIN_ALLOCATIONS_TIMEOUT
+       });
+       memoryStart = this._memory.startRecordingAllocations(recordingOptions);
+     }
+ 
+-    let [profilerStartData, timelineStartData, memoryStartData] = yield Promise.all([
++    let [profilerStartData, timelineStartData, memoryStartData] = await Promise.all([
+       profilerStart, timelineStart, memoryStart
+     ]);
+ 
+     let data = Object.create(null);
+     // Filter out start times that are not actually used (0 or undefined), and
+     // find the earliest time since all sources use same epoch.
+     let startTimes = [
+       profilerStartData.currentTime,
+@@ -360,35 +359,35 @@ PerformanceRecorder.prototype = {
+       timelineStartData
+     ].filter(Boolean);
+     data.startTime = Math.min(...startTimes);
+     data.position = profilerStartData.position;
+     data.generation = profilerStartData.generation;
+     data.totalSize = profilerStartData.totalSize;
+ 
+     data.systemClient = this._systemClient;
+-    data.systemHost = yield getSystemInfo();
++    data.systemHost = await getSystemInfo();
+ 
+     let model = new PerformanceRecordingActor(this.conn, options, data);
+     this._recordings.push(model);
+ 
+     this.emit("recording-started", model);
+     return model;
+-  }),
++  },
+ 
+   /**
+    * Manually ends the recording session for the corresponding PerformanceRecording.
+    *
+    * @param PerformanceRecording model
+    *        The corresponding PerformanceRecording that belongs to the recording
+    *        session wished to stop.
+    * @return PerformanceRecording
+    *         Returns the same model, populated with the profiling data.
+    */
+-  stopRecording: Task.async(function* (model) {
++  async stopRecording(model) {
+     // If model isn't in the Recorder's internal store,
+     // then do nothing, like if this was a console.profileEnd
+     // from a different target.
+     if (!this._recordings.includes(model)) {
+       return model;
+     }
+ 
+     // Flag the recording as no longer recording, so that `model.isRecording()`
+@@ -426,17 +425,17 @@ PerformanceRecorder.prototype = {
+       // Data available only at the end of a recording.
+       profile: profilerData.profile,
+       // End times for all the actors.
+       duration: profilerData.currentTime - startTime,
+     };
+ 
+     this.emit("recording-stopped", model, recordingData);
+     return model;
+-  }),
++  },
+ 
+   /**
+    * Checks all currently stored recording handles and returns a boolean
+    * if there is a session currently being recorded.
+    *
+    * @return Boolean
+    */
+   isRecording: function () {
+diff --git a/devtools/server/performance/timeline.js b/devtools/server/performance/timeline.js
+--- a/devtools/server/performance/timeline.js
++++ b/devtools/server/performance/timeline.js
+@@ -19,17 +19,16 @@
+  * When markers are available, an event is emitted:
+  *   timeline.on("markers", function(markers) {...})
+  */
+ 
+ const { Ci, Cu } = require("chrome");
+ 
+ // Be aggressive about lazy loading, as this will run on every
+ // toolbox startup
+-loader.lazyRequireGetter(this, "Task", "devtools/shared/task", true);
+ loader.lazyRequireGetter(this, "Memory", "devtools/server/performance/memory", true);
+ loader.lazyRequireGetter(this, "Framerate", "devtools/server/performance/framerate", true);
+ loader.lazyRequireGetter(this, "StackFrameCache", "devtools/server/actors/utils/stack", true);
+ loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
+ 
+ // How often do we pull markers from the docShells, and therefore, how often do
+ // we send events to the front (knowing that when there are no markers in the
+ // docShell, no event is sent). In milliseconds.
+@@ -200,17 +199,17 @@ Timeline.prototype = {
+    *         from timeline markers.
+    * @option {boolean} withGCEvents
+    *         Boolean indicating whether or not GC markers should be emitted.
+    *         TODO: Remove these fake GC markers altogether in bug 1198127.
+    * @option {boolean} withDocLoadingEvents
+    *         Boolean indicating whether or not DOMContentLoaded and Load
+    *         marker events are emitted.
+    */
+-  start: Task.async(function* ({
++  async start({
+     withMarkers,
+     withTicks,
+     withMemory,
+     withFrames,
+     withGCEvents,
+     withDocLoadingEvents,
+   }) {
+     let docShells = this.docShells;
+@@ -252,22 +251,22 @@ Timeline.prototype = {
+ 
+     if (this._withFrames && this._withMarkers) {
+       this._stackFrames = new StackFrameCache();
+       this._stackFrames.initFrames();
+     }
+ 
+     this._pullTimelineData();
+     return startTime;
+-  }),
++  },
+ 
+   /**
+    * Stop recording profile markers.
+    */
+-  stop: Task.async(function* () {
++  async stop() {
+     let docShells = this.docShells;
+     if (!docShells.length) {
+       return -1;
+     }
+     let endTime = this._startTime = docShells[0].now();
+     if (!this._isRecording) {
+       return endTime;
+     }
+@@ -303,17 +302,17 @@ Timeline.prototype = {
+     this._withMemory = false;
+     this._withFrames = false;
+     this._withDocLoadingEvents = false;
+     this._withGCEvents = false;
+ 
+     clearTimeout(this._dataPullTimeout);
+ 
+     return endTime;
+-  }),
++  },
+ 
+   /**
+    * When a new window becomes available in the tabActor, start recording its
+    * markers if we were recording.
+    */
+   _onWindowReady: function ({ window }) {
+     if (this._isRecording) {
+       let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
+diff --git a/devtools/server/tests/browser/browser_accessibility_node.js b/devtools/server/tests/browser/browser_accessibility_node.js
+--- a/devtools/server/tests/browser/browser_accessibility_node.js
++++ b/devtools/server/tests/browser/browser_accessibility_node.js
+@@ -1,74 +1,74 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ // Checks for the AccessibleActor
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, accessibility} =
+-    yield initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
++    await initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
+ 
+-  let a11yWalker = yield accessibility.getWalker(walker);
+-  let buttonNode = yield walker.querySelector(walker.rootNode, "#button");
+-  let accessibleFront = yield a11yWalker.getAccessibleFor(buttonNode);
++  let a11yWalker = await accessibility.getWalker(walker);
++  let buttonNode = await walker.querySelector(walker.rootNode, "#button");
++  let accessibleFront = await a11yWalker.getAccessibleFor(buttonNode);
+ 
+   checkA11yFront(accessibleFront, {
+     name: "Accessible Button",
+     role: "pushbutton",
+     value: "",
+     description: "Accessibility Test",
+     help: "",
+     keyboardShortcut: "",
+     childCount: 1,
+     domNodeType: 1
+   });
+ 
+   info("Actions");
+-  let actions = yield accessibleFront.getActions();
++  let actions = await accessibleFront.getActions();
+   is(actions.length, 1, "Accessible Front has correct number of actions");
+   is(actions[0], "Press", "Accessible Front default action is correct");
+ 
+   info("Index in parent");
+-  let index = yield accessibleFront.getIndexInParent();
++  let index = await accessibleFront.getIndexInParent();
+   is(index, 1, "Accessible Front has correct index in parent");
+ 
+   info("State");
+-  let state = yield accessibleFront.getState();
++  let state = await accessibleFront.getState();
+   SimpleTest.isDeeply(state,
+     ["focusable", "selectable text", "opaque", "enabled", "sensitive"],
+     "Accessible Front has correct states");
+ 
+   info("Attributes");
+-  let attributes = yield accessibleFront.getAttributes();
++  let attributes = await accessibleFront.getAttributes();
+   SimpleTest.isDeeply(attributes, {
+     "margin-top": "0px",
+     display: "inline-block",
+     "text-align": "center",
+     "text-indent": "0px",
+     "margin-left": "0px",
+     tag: "button",
+     "margin-right": "0px",
+     id: "button",
+     "margin-bottom": "0px"
+   }, "Accessible Front has correct attributes");
+ 
+   info("Children");
+-  let children = yield accessibleFront.children();
++  let children = await accessibleFront.children();
+   is(children.length, 1, "Accessible Front has correct number of children");
+   checkA11yFront(children[0], {
+     name: "Accessible Button",
+     role: "text leaf"
+   });
+ 
+   info("DOM Node");
+-  let node = yield accessibleFront.getDOMNode(walker);
++  let node = await accessibleFront.getDOMNode(walker);
+   is(node, buttonNode, "Accessible Front has correct DOM node");
+ 
+   let a11yShutdown = waitForA11yShutdown();
+-  yield client.close();
++  await client.close();
+   forceCollections();
+-  yield a11yShutdown;
++  await a11yShutdown;
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_accessibility_node_events.js b/devtools/server/tests/browser/browser_accessibility_node_events.js
+--- a/devtools/server/tests/browser/browser_accessibility_node_events.js
++++ b/devtools/server/tests/browser/browser_accessibility_node_events.js
+@@ -1,93 +1,93 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ // Checks for the AccessibleActor events
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, accessibility} =
+-    yield initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
++    await initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
+ 
+-  let a11yWalker = yield accessibility.getWalker(walker);
+-  let a11yDoc = yield a11yWalker.getDocument();
+-  let buttonNode = yield walker.querySelector(walker.rootNode, "#button");
+-  let accessibleFront = yield a11yWalker.getAccessibleFor(buttonNode);
+-  let sliderNode = yield walker.querySelector(walker.rootNode, "#slider");
+-  let accessibleSliderFront = yield a11yWalker.getAccessibleFor(sliderNode);
++  let a11yWalker = await accessibility.getWalker(walker);
++  let a11yDoc = await a11yWalker.getDocument();
++  let buttonNode = await walker.querySelector(walker.rootNode, "#button");
++  let accessibleFront = await a11yWalker.getAccessibleFor(buttonNode);
++  let sliderNode = await walker.querySelector(walker.rootNode, "#slider");
++  let accessibleSliderFront = await a11yWalker.getAccessibleFor(sliderNode);
+   let browser = gBrowser.selectedBrowser;
+ 
+   checkA11yFront(accessibleFront, {
+     name: "Accessible Button",
+     role: "pushbutton",
+     value: "",
+     description: "Accessibility Test",
+     help: "",
+     keyboardShortcut: "",
+     childCount: 1,
+     domNodeType: 1
+   });
+ 
+   info("Name change event");
+-  yield emitA11yEvent(accessibleFront, "name-change",
++  await emitA11yEvent(accessibleFront, "name-change",
+     (name, parent) => {
+       checkA11yFront(accessibleFront, { name: "Renamed" });
+       checkA11yFront(parent, { }, a11yDoc);
+     }, () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("button").setAttribute(
+         "aria-label", "Renamed")));
+ 
+   info("Description change event");
+-  yield emitA11yEvent(accessibleFront, "description-change",
++  await emitA11yEvent(accessibleFront, "description-change",
+     () => checkA11yFront(accessibleFront, { description: "" }),
+     () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("button").removeAttribute("aria-describedby")));
+ 
+   info("State change event");
+-  let states = yield accessibleFront.getState();
++  let states = await accessibleFront.getState();
+   let expectedStates = ["unavailable", "selectable text", "opaque"];
+   SimpleTest.isDeeply(states, ["focusable", "selectable text", "opaque",
+                                "enabled", "sensitive"], "States are correct");
+-  yield emitA11yEvent(accessibleFront, "state-change",
++  await emitA11yEvent(accessibleFront, "state-change",
+     newStates => SimpleTest.isDeeply(newStates, expectedStates,
+                                      "States are updated"),
+     () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("button").setAttribute("disabled", true)));
+-  states = yield accessibleFront.getState();
++  states = await accessibleFront.getState();
+   SimpleTest.isDeeply(states, expectedStates, "States are updated");
+ 
+   info("Attributes change event");
+-  let attrs = yield accessibleFront.getAttributes();
++  let attrs = await accessibleFront.getAttributes();
+   ok(!attrs.live, "Attribute is not present");
+-  yield emitA11yEvent(accessibleFront, "attributes-change",
++  await emitA11yEvent(accessibleFront, "attributes-change",
+     newAttrs => is(newAttrs.live, "polite", "Attributes are updated"),
+     () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("button").setAttribute("aria-live", "polite")));
+-  attrs = yield accessibleFront.getAttributes();
++  attrs = await accessibleFront.getAttributes();
+   is(attrs.live, "polite", "Attributes are updated");
+ 
+   info("Value change event");
+   checkA11yFront(accessibleSliderFront, { value: "5" });
+-  yield emitA11yEvent(accessibleSliderFront, "value-change",
++  await emitA11yEvent(accessibleSliderFront, "value-change",
+     () => checkA11yFront(accessibleSliderFront, { value: "6" }),
+     () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("slider").setAttribute("aria-valuenow", "6")));
+ 
+   info("Reorder event");
+   is(accessibleSliderFront.childCount, 1, "Slider has only 1 child");
+-  yield emitA11yEvent(accessibleSliderFront, "reorder",
++  await emitA11yEvent(accessibleSliderFront, "reorder",
+     childCount => is(childCount, 2, "Child count is updated"),
+     () => ContentTask.spawn(browser, null, () => {
+       let button = content.document.createElement("button");
+       button.innerText = "Slider button";
+       content.document.getElementById("slider").appendChild(button);
+     }));
+   is(accessibleSliderFront.childCount, 2, "Child count is updated");
+ 
+   let a11yShutdown = waitForA11yShutdown();
+-  yield client.close();
++  await client.close();
+   forceCollections();
+-  yield a11yShutdown;
++  await a11yShutdown;
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_accessibility_simple.js b/devtools/server/tests/browser/browser_accessibility_simple.js
+--- a/devtools/server/tests/browser/browser_accessibility_simple.js
++++ b/devtools/server/tests/browser/browser_accessibility_simple.js
+@@ -1,21 +1,21 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ // Simple checks for the AccessibilityActor and AccessibleWalkerActor
+ 
+-add_task(function* () {
+-  let {client, accessibility} = yield initAccessibilityFrontForUrl(
++add_task(async function () {
++  let {client, accessibility} = await initAccessibilityFrontForUrl(
+     "data:text/html;charset=utf-8,<title>test</title><div></div>");
+ 
+   ok(accessibility, "The AccessibilityFront was created");
+   ok(accessibility.getWalker, "The getWalker method exists");
+ 
+-  let a11yWalker = yield accessibility.getWalker();
++  let a11yWalker = await accessibility.getWalker();
+   ok(a11yWalker, "The AccessibleWalkerFront was returned");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_accessibility_walker.js b/devtools/server/tests/browser/browser_accessibility_walker.js
+--- a/devtools/server/tests/browser/browser_accessibility_walker.js
++++ b/devtools/server/tests/browser/browser_accessibility_walker.js
+@@ -1,75 +1,75 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ // Checks for the AccessibleWalkerActor
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, accessibility} =
+-    yield initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
++    await initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
+ 
+-  let a11yWalker = yield accessibility.getWalker(walker);
++  let a11yWalker = await accessibility.getWalker(walker);
+   ok(a11yWalker, "The AccessibleWalkerFront was returned");
+ 
+-  let a11yDoc = yield a11yWalker.getDocument();
++  let a11yDoc = await a11yWalker.getDocument();
+   ok(a11yDoc, "The AccessibleFront for root doc is created");
+ 
+-  let children = yield a11yWalker.children();
++  let children = await a11yWalker.children();
+   is(children.length, 1,
+     "AccessibleWalker only has 1 child - root doc accessible");
+   is(a11yDoc, children[0],
+     "Root accessible must be AccessibleWalker's only child");
+ 
+-  let buttonNode = yield walker.querySelector(walker.rootNode, "#button");
+-  let accessibleFront = yield a11yWalker.getAccessibleFor(buttonNode);
++  let buttonNode = await walker.querySelector(walker.rootNode, "#button");
++  let accessibleFront = await a11yWalker.getAccessibleFor(buttonNode);
+ 
+   checkA11yFront(accessibleFront, {
+     name: "Accessible Button",
+     role: "pushbutton"
+   });
+ 
+   let browser = gBrowser.selectedBrowser;
+ 
+   // Ensure name-change event is emitted by walker when cached accessible's name
+   // gets updated (via DOM manipularion).
+-  yield emitA11yEvent(a11yWalker, "name-change",
++  await emitA11yEvent(a11yWalker, "name-change",
+     (front, parent) => {
+       checkA11yFront(front, { name: "Renamed" }, accessibleFront);
+       checkA11yFront(parent, { }, a11yDoc);
+     },
+     () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("button").setAttribute(
+       "aria-label", "Renamed")));
+ 
+   // Ensure reorder event is emitted by walker when DOM tree changes.
+-  let docChildren = yield a11yDoc.children();
++  let docChildren = await a11yDoc.children();
+   is(docChildren.length, 3, "Root doc should have correct number of children");
+ 
+-  yield emitA11yEvent(a11yWalker, "reorder",
++  await emitA11yEvent(a11yWalker, "reorder",
+     front => checkA11yFront(front, { }, a11yDoc),
+     () => ContentTask.spawn(browser, null, () => {
+       let input = content.document.createElement("input");
+       input.type = "text";
+       input.title = "This is a tooltip";
+       input.value = "New input";
+       content.document.body.appendChild(input);
+     }));
+ 
+-  docChildren = yield a11yDoc.children();
++  docChildren = await a11yDoc.children();
+   is(docChildren.length, 4, "Root doc should have correct number of children");
+ 
+   // Ensure destory event is emitted by walker when cached accessible's raw
+   // accessible gets destroyed.
+-  yield emitA11yEvent(a11yWalker, "accessible-destroy",
++  await emitA11yEvent(a11yWalker, "accessible-destroy",
+     destroyedFront => checkA11yFront(destroyedFront, { }, accessibleFront),
+     () => ContentTask.spawn(browser, null, () =>
+       content.document.getElementById("button").remove()));
+ 
+   let a11yShutdown = waitForA11yShutdown();
+-  yield client.close();
++  await client.close();
+   forceCollections();
+-  yield a11yShutdown;
++  await a11yShutdown;
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_emitMutations.js b/devtools/server/tests/browser/browser_animation_emitMutations.js
+--- a/devtools/server/tests/browser/browser_animation_emitMutations.js
++++ b/devtools/server/tests/browser/browser_animation_emitMutations.js
+@@ -2,35 +2,35 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // Test that the AnimationsActor emits events about changed animations on a
+ // node after getAnimationPlayersForNode was called on that node.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Retrieve a non-animated node");
+-  let node = yield walker.querySelector(walker.rootNode, ".not-animated");
++  let node = await walker.querySelector(walker.rootNode, ".not-animated");
+ 
+   info("Retrieve the animation player for the node");
+-  let players = yield animations.getAnimationPlayersForNode(node);
++  let players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 0, "The node has no animation players");
+ 
+   info("Listen for new animations");
+   let onMutations = once(animations, "mutations");
+ 
+   info("Add a couple of animation on the node");
+-  yield node.modifyAttributes([
++  await node.modifyAttributes([
+     {attributeName: "class", newValue: "multiple-animations"}
+   ]);
+-  let changes = yield onMutations;
++  let changes = await onMutations;
+ 
+   ok(true, "The mutations event was emitted");
+   is(changes.length, 2, "There are 2 changes in the mutation event");
+   ok(changes.every(({type}) => type === "added"), "Both changes are additions");
+ 
+   let names = changes.map(c => c.player.initialState.name).sort();
+   is(names[0], "glow", "The animation 'glow' was added");
+   is(names[1], "move", "The animation 'move' was added");
+@@ -38,25 +38,25 @@ add_task(function* () {
+   info("Store the 2 new players for comparing later");
+   let p1 = changes[0].player;
+   let p2 = changes[1].player;
+ 
+   info("Listen for removed animations");
+   onMutations = once(animations, "mutations");
+ 
+   info("Remove the animation css class on the node");
+-  yield node.modifyAttributes([
++  await node.modifyAttributes([
+     {attributeName: "class", newValue: "not-animated"}
+   ]);
+ 
+-  changes = yield onMutations;
++  changes = await onMutations;
+ 
+   ok(true, "The mutations event was emitted");
+   is(changes.length, 2, "There are 2 changes in the mutation event");
+   ok(changes.every(({type}) => type === "removed"), "Both are removals");
+   ok(changes[0].player === p1 || changes[0].player === p2,
+     "The first removed player was one of the previously added players");
+   ok(changes[1].player === p1 || changes[1].player === p2,
+     "The second removed player was one of the previously added players");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_getFrames.js b/devtools/server/tests/browser/browser_animation_getFrames.js
+--- a/devtools/server/tests/browser/browser_animation_getFrames.js
++++ b/devtools/server/tests/browser/browser_animation_getFrames.js
+@@ -2,29 +2,29 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // Check that the AnimationPlayerActor exposes a getFrames method that returns
+ // the list of keyframes in the animation.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Get the test node and its animation front");
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
++  let [player] = await animations.getAnimationPlayersForNode(node);
+ 
+   ok(player.getFrames, "The front has the getFrames method");
+ 
+-  let frames = yield player.getFrames();
++  let frames = await player.getFrames();
+   is(frames.length, 2, "The correct number of keyframes was retrieved");
+   ok(frames[0].transform, "Frame 0 has the transform property");
+   ok(frames[1].transform, "Frame 1 has the transform property");
+   // Note that we don't really test the content of the frame object here on
+   // purpose. This object comes straight out of the web animations API
+   // unmodified.
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_getMultipleStates.js b/devtools/server/tests/browser/browser_animation_getMultipleStates.js
+--- a/devtools/server/tests/browser/browser_animation_getMultipleStates.js
++++ b/devtools/server/tests/browser/browser_animation_getMultipleStates.js
+@@ -2,48 +2,48 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // Check that the duration, iterationCount and delay are retrieved correctly for
+ // multiple animations.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+-  yield playerHasAnInitialState(walker, animations);
++  await playerHasAnInitialState(walker, animations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* playerHasAnInitialState(walker, animations) {
+-  let state = yield getAnimationStateForNode(walker, animations,
++async function playerHasAnInitialState(walker, animations) {
++  let state = await getAnimationStateForNode(walker, animations,
+     ".delayed-multiple-animations", 0);
+ 
+   ok(state.duration, 50000,
+      "The duration of the first animation is correct");
+   ok(state.iterationCount, 10,
+      "The iterationCount of the first animation is correct");
+   ok(state.delay, 1000,
+      "The delay of the first animation is correct");
+ 
+-  state = yield getAnimationStateForNode(walker, animations,
++  state = await getAnimationStateForNode(walker, animations,
+     ".delayed-multiple-animations", 1);
+ 
+   ok(state.duration, 100000,
+      "The duration of the secon animation is correct");
+   ok(state.iterationCount, 30,
+      "The iterationCount of the secon animation is correct");
+   ok(state.delay, 750,
+      "The delay of the secon animation is correct");
+ }
+ 
+-function* getAnimationStateForNode(walker, animations, selector, playerIndex) {
+-  let node = yield walker.querySelector(walker.rootNode, selector);
+-  let players = yield animations.getAnimationPlayersForNode(node);
++async function getAnimationStateForNode(walker, animations, selector, playerIndex) {
++  let node = await walker.querySelector(walker.rootNode, selector);
++  let players = await animations.getAnimationPlayersForNode(node);
+   let player = players[playerIndex];
+-  yield player.ready();
+-  let state = yield player.getCurrentState();
++  await player.ready();
++  let state = await player.getCurrentState();
+   return state;
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_getPlayers.js b/devtools/server/tests/browser/browser_animation_getPlayers.js
+--- a/devtools/server/tests/browser/browser_animation_getPlayers.js
++++ b/devtools/server/tests/browser/browser_animation_getPlayers.js
+@@ -1,63 +1,63 @@
+ /* 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";
+ 
+ // Check the output of getAnimationPlayersForNode
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+-  yield theRightNumberOfPlayersIsReturned(walker, animations);
+-  yield playersCanBePausedAndResumed(walker, animations);
++  await theRightNumberOfPlayersIsReturned(walker, animations);
++  await playersCanBePausedAndResumed(walker, animations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* theRightNumberOfPlayersIsReturned(walker, animations) {
+-  let node = yield walker.querySelector(walker.rootNode, ".not-animated");
+-  let players = yield animations.getAnimationPlayersForNode(node);
++async function theRightNumberOfPlayersIsReturned(walker, animations) {
++  let node = await walker.querySelector(walker.rootNode, ".not-animated");
++  let players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 0,
+      "0 players were returned for the unanimated node");
+ 
+-  node = yield walker.querySelector(walker.rootNode, ".simple-animation");
+-  players = yield animations.getAnimationPlayersForNode(node);
++  node = await walker.querySelector(walker.rootNode, ".simple-animation");
++  players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 1,
+      "One animation player was returned");
+ 
+-  node = yield walker.querySelector(walker.rootNode, ".multiple-animations");
+-  players = yield animations.getAnimationPlayersForNode(node);
++  node = await walker.querySelector(walker.rootNode, ".multiple-animations");
++  players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 2,
+      "Two animation players were returned");
+ 
+-  node = yield walker.querySelector(walker.rootNode, ".transition");
+-  players = yield animations.getAnimationPlayersForNode(node);
++  node = await walker.querySelector(walker.rootNode, ".transition");
++  players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 1,
+      "One animation player was returned for the transitioned node");
+ }
+ 
+-function* playersCanBePausedAndResumed(walker, animations) {
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
+-  yield player.ready();
++async function playersCanBePausedAndResumed(walker, animations) {
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
++  let [player] = await animations.getAnimationPlayersForNode(node);
++  await player.ready();
+ 
+   ok(player.initialState,
+      "The player has an initialState");
+   ok(player.getCurrentState,
+      "The player has the getCurrentState method");
+   is(player.initialState.playState, "running",
+      "The animation is currently running");
+ 
+-  yield player.pause();
+-  let state = yield player.getCurrentState();
++  await player.pause();
++  let state = await player.getCurrentState();
+   is(state.playState, "paused",
+      "The animation is now paused");
+ 
+-  yield player.play();
+-  state = yield player.getCurrentState();
++  await player.play();
++  state = await player.getCurrentState();
+   is(state.playState, "running",
+      "The animation is now running again");
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_getProperties.js b/devtools/server/tests/browser/browser_animation_getProperties.js
+--- a/devtools/server/tests/browser/browser_animation_getProperties.js
++++ b/devtools/server/tests/browser/browser_animation_getProperties.js
+@@ -4,33 +4,33 @@
+ 
+ "use strict";
+ 
+ // Check that the AnimationPlayerActor exposes a getProperties method that
+ // returns the list of animated properties in the animation.
+ 
+ const URL = MAIN_DOMAIN + "animation.html";
+ 
+-add_task(function* () {
+-  let {client, walker, animations} = yield initAnimationsFrontForUrl(URL);
++add_task(async function () {
++  let {client, walker, animations} = await initAnimationsFrontForUrl(URL);
+ 
+   info("Get the test node and its animation front");
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
++  let [player] = await animations.getAnimationPlayersForNode(node);
+ 
+   ok(player.getProperties, "The front has the getProperties method");
+ 
+-  let properties = yield player.getProperties();
++  let properties = await player.getProperties();
+   is(properties.length, 1, "The correct number of properties was retrieved");
+ 
+   let propertyObject = properties[0];
+   is(propertyObject.name, "transform", "Property 0 is transform");
+ 
+   is(propertyObject.values.length, 2,
+     "The correct number of property values was retrieved");
+ 
+   // Note that we don't really test the content of the frame object here on
+   // purpose. This object comes straight out of the web animations API
+   // unmodified.
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_getStateAfterFinished.js b/devtools/server/tests/browser/browser_animation_getStateAfterFinished.js
+--- a/devtools/server/tests/browser/browser_animation_getStateAfterFinished.js
++++ b/devtools/server/tests/browser/browser_animation_getStateAfterFinished.js
+@@ -6,38 +6,38 @@
+ "use strict";
+ 
+ // Check that the right duration/iterationCount/delay are retrieved even when
+ // the node has multiple animations and one of them already ended before getting
+ // the player objects.
+ // See devtools/server/actors/animation.js |getPlayerIndex| for more
+ // information.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Retrieve a non animated node");
+-  let node = yield walker.querySelector(walker.rootNode, ".not-animated");
++  let node = await walker.querySelector(walker.rootNode, ".not-animated");
+ 
+   info("Apply the multiple-animations-2 class to start the animations");
+-  yield node.modifyAttributes([
++  await node.modifyAttributes([
+     {attributeName: "class", newValue: "multiple-animations-2"}
+   ]);
+ 
+   info("Get the list of players, by the time this executes, the first, " +
+        "short, animation should have ended.");
+-  let players = yield animations.getAnimationPlayersForNode(node);
++  let players = await animations.getAnimationPlayersForNode(node);
+   if (players.length === 3) {
+     info("The short animation hasn't ended yet, wait for a bit.");
+     // The animation lasts for 500ms, so 1000ms should do it.
+-    yield new Promise(resolve => setTimeout(resolve, 1000));
++    await new Promise(resolve => setTimeout(resolve, 1000));
+ 
+     info("And get the list again");
+-    players = yield animations.getAnimationPlayersForNode(node);
++    players = await animations.getAnimationPlayersForNode(node);
+   }
+ 
+   is(players.length, 2, "2 animations remain on the node");
+ 
+   is(players[0].state.duration, 100000,
+      "The duration of the first animation is correct");
+   is(players[0].state.delay, 2000,
+      "The delay of the first animation is correct");
+@@ -46,11 +46,11 @@ add_task(function* () {
+ 
+   is(players[1].state.duration, 300000,
+      "The duration of the second animation is correct");
+   is(players[1].state.delay, 1000,
+      "The delay of the second animation is correct");
+   is(players[1].state.iterationCount, 100,
+      "The iterationCount of the second animation is correct");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_getSubTreeAnimations.js b/devtools/server/tests/browser/browser_animation_getSubTreeAnimations.js
+--- a/devtools/server/tests/browser/browser_animation_getSubTreeAnimations.js
++++ b/devtools/server/tests/browser/browser_animation_getSubTreeAnimations.js
+@@ -4,35 +4,35 @@
+ 
+ "use strict";
+ 
+ // Check that the AnimationsActor can retrieve all animations inside a node's
+ // subtree (but not going into iframes).
+ 
+ const URL = MAIN_DOMAIN + "animation.html";
+ 
+-add_task(function* () {
++add_task(async function () {
+   info("Creating a test document with 2 iframes containing animated nodes");
+ 
+-  let {client, walker, animations} = yield initAnimationsFrontForUrl(
++  let {client, walker, animations} = await initAnimationsFrontForUrl(
+     "data:text/html;charset=utf-8," +
+     "<iframe id='iframe' src='" + URL + "'></iframe>");
+ 
+   info("Try retrieving all animations from the root doc's <body> node");
+-  let rootBody = yield walker.querySelector(walker.rootNode, "body");
+-  let players = yield animations.getAnimationPlayersForNode(rootBody);
++  let rootBody = await walker.querySelector(walker.rootNode, "body");
++  let players = await animations.getAnimationPlayersForNode(rootBody);
+   is(players.length, 0, "The node has no animation players");
+ 
+   info("Retrieve all animations from the iframe's <body> node");
+-  let iframe = yield walker.querySelector(walker.rootNode, "#iframe");
+-  let {nodes} = yield walker.children(iframe);
+-  let frameBody = yield walker.querySelector(nodes[0], "body");
+-  players = yield animations.getAnimationPlayersForNode(frameBody);
++  let iframe = await walker.querySelector(walker.rootNode, "#iframe");
++  let {nodes} = await walker.children(iframe);
++  let frameBody = await walker.querySelector(nodes[0], "body");
++  players = await animations.getAnimationPlayersForNode(frameBody);
+ 
+   // Testing for a hard-coded number of animations here would intermittently
+   // fail depending on how fast or slow the test is (indeed, the test page
+   // contains short transitions, and delayed animations). So just make sure we
+   // at least have the infinitely running animations.
+   ok(players.length >= 4, "All subtree animations were retrieved");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_keepFinished.js b/devtools/server/tests/browser/browser_animation_keepFinished.js
+--- a/devtools/server/tests/browser/browser_animation_keepFinished.js
++++ b/devtools/server/tests/browser/browser_animation_keepFinished.js
+@@ -5,51 +5,51 @@
+ 
+ "use strict";
+ 
+ // Test that the AnimationsActor doesn't report finished animations as removed.
+ // Indeed, animations that only have the "finished" playState can be modified
+ // still, so we want the AnimationsActor to preserve the corresponding
+ // AnimationPlayerActor.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Retrieve a non-animated node");
+-  let node = yield walker.querySelector(walker.rootNode, ".not-animated");
++  let node = await walker.querySelector(walker.rootNode, ".not-animated");
+ 
+   info("Retrieve the animation player for the node");
+-  let players = yield animations.getAnimationPlayersForNode(node);
++  let players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 0, "The node has no animation players");
+ 
+   info("Listen for new animations");
+   let reportedMutations = [];
+   function onMutations(mutations) {
+     reportedMutations = [...reportedMutations, ...mutations];
+   }
+   animations.on("mutations", onMutations);
+ 
+   info("Add a short animation on the node");
+-  yield node.modifyAttributes([
++  await node.modifyAttributes([
+     {attributeName: "class", newValue: "short-animation"}
+   ]);
+ 
+   info("Wait for longer than the animation's duration");
+-  yield wait(2000);
++  await wait(2000);
+ 
+-  players = yield animations.getAnimationPlayersForNode(node);
++  players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 0, "The added animation is surely finished");
+ 
+   is(reportedMutations.length, 1, "Only one mutation was reported");
+   is(reportedMutations[0].type, "added", "The mutation was an addition");
+ 
+   animations.off("mutations", onMutations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+ function wait(ms) {
+   return new Promise(resolve => {
+     setTimeout(resolve, ms);
+   });
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_playPauseIframe.js b/devtools/server/tests/browser/browser_animation_playPauseIframe.js
+--- a/devtools/server/tests/browser/browser_animation_playPauseIframe.js
++++ b/devtools/server/tests/browser/browser_animation_playPauseIframe.js
+@@ -4,48 +4,48 @@
+ 
+ "use strict";
+ 
+ // Check that the AnimationsActor can pause/play all animations even those
+ // within iframes.
+ 
+ const URL = MAIN_DOMAIN + "animation.html";
+ 
+-add_task(function* () {
++add_task(async function () {
+   info("Creating a test document with 2 iframes containing animated nodes");
+ 
+-  let {client, walker, animations} = yield initAnimationsFrontForUrl(
++  let {client, walker, animations} = await initAnimationsFrontForUrl(
+     "data:text/html;charset=utf-8," +
+     "<iframe id='i1' src='" + URL + "'></iframe>" +
+     "<iframe id='i2' src='" + URL + "'></iframe>");
+ 
+   info("Getting the 2 iframe container nodes and animated nodes in them");
+-  let nodeInFrame1 = yield getNodeInFrame(walker, "#i1", ".simple-animation");
+-  let nodeInFrame2 = yield getNodeInFrame(walker, "#i2", ".simple-animation");
++  let nodeInFrame1 = await getNodeInFrame(walker, "#i1", ".simple-animation");
++  let nodeInFrame2 = await getNodeInFrame(walker, "#i2", ".simple-animation");
+ 
+   info("Pause all animations in the test document");
+-  yield animations.pauseAll();
+-  yield checkState(animations, nodeInFrame1, "paused");
+-  yield checkState(animations, nodeInFrame2, "paused");
++  await animations.pauseAll();
++  await checkState(animations, nodeInFrame1, "paused");
++  await checkState(animations, nodeInFrame2, "paused");
+ 
+   info("Play all animations in the test document");
+-  yield animations.playAll();
+-  yield checkState(animations, nodeInFrame1, "running");
+-  yield checkState(animations, nodeInFrame2, "running");
++  await animations.playAll();
++  await checkState(animations, nodeInFrame1, "running");
++  await checkState(animations, nodeInFrame2, "running");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* checkState(animations, nodeFront, playState) {
++async function checkState(animations, nodeFront, playState) {
+   info("Getting the AnimationPlayerFront for the test node");
+-  let [player] = yield animations.getAnimationPlayersForNode(nodeFront);
+-  yield player.ready;
+-  let state = yield player.getCurrentState();
++  let [player] = await animations.getAnimationPlayersForNode(nodeFront);
++  await player.ready;
++  let state = await player.getCurrentState();
+   is(state.playState, playState,
+      "The playState of the test node is " + playState);
+ }
+ 
+-function* getNodeInFrame(walker, frameSelector, nodeSelector) {
+-  let iframe = yield walker.querySelector(walker.rootNode, frameSelector);
+-  let {nodes} = yield walker.children(iframe);
++async function getNodeInFrame(walker, frameSelector, nodeSelector) {
++  let iframe = await walker.querySelector(walker.rootNode, frameSelector);
++  let {nodes} = await walker.children(iframe);
+   return walker.querySelector(nodes[0], nodeSelector);
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_playPauseSeveral.js b/devtools/server/tests/browser/browser_animation_playPauseSeveral.js
+--- a/devtools/server/tests/browser/browser_animation_playPauseSeveral.js
++++ b/devtools/server/tests/browser/browser_animation_playPauseSeveral.js
+@@ -10,83 +10,83 @@
+ // List of selectors that match "all" animated nodes in the test page.
+ // This list misses a bunch of animated nodes on purpose. Only the ones that
+ // have infinite animations are listed. This is done to avoid intermittents
+ // caused when finite animations are already done playing by the time the test
+ // runs.
+ const ALL_ANIMATED_NODES = [".simple-animation", ".multiple-animations",
+                             ".delayed-animation"];
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Pause all animations in the test document");
+-  yield animations.pauseAll();
+-  yield checkStates(walker, animations, ALL_ANIMATED_NODES, "paused");
++  await animations.pauseAll();
++  await checkStates(walker, animations, ALL_ANIMATED_NODES, "paused");
+ 
+   info("Play all animations in the test document");
+-  yield animations.playAll();
+-  yield checkStates(walker, animations, ALL_ANIMATED_NODES, "running");
++  await animations.playAll();
++  await checkStates(walker, animations, ALL_ANIMATED_NODES, "running");
+ 
+   info("Pause all animations in the test document using toggleAll");
+-  yield animations.toggleAll();
+-  yield checkStates(walker, animations, ALL_ANIMATED_NODES, "paused");
++  await animations.toggleAll();
++  await checkStates(walker, animations, ALL_ANIMATED_NODES, "paused");
+ 
+   info("Play all animations in the test document using toggleAll");
+-  yield animations.toggleAll();
+-  yield checkStates(walker, animations, ALL_ANIMATED_NODES, "running");
++  await animations.toggleAll();
++  await checkStates(walker, animations, ALL_ANIMATED_NODES, "running");
+ 
+   info("Play all animations from multiple animated node using toggleSeveral");
+-  let players = yield getPlayersFor(walker, animations,
++  let players = await getPlayersFor(walker, animations,
+                                    [".multiple-animations"]);
+   is(players.length, 2, "Node has 2 animation players");
+-  yield animations.toggleSeveral(players, false);
+-  let state1 = yield players[0].getCurrentState();
++  await animations.toggleSeveral(players, false);
++  let state1 = await players[0].getCurrentState();
+   is(state1.playState, "running",
+     "The playState of the first player is running");
+-  let state2 = yield players[1].getCurrentState();
++  let state2 = await players[1].getCurrentState();
+   is(state2.playState, "running",
+     "The playState of the second player is running");
+ 
+   info("Pause one animation from a multiple animated node using toggleSeveral");
+-  yield animations.toggleSeveral([players[0]], true);
+-  state1 = yield players[0].getCurrentState();
++  await animations.toggleSeveral([players[0]], true);
++  state1 = await players[0].getCurrentState();
+   is(state1.playState, "paused", "The playState of the first player is paused");
+-  state2 = yield players[1].getCurrentState();
++  state2 = await players[1].getCurrentState();
+   is(state2.playState, "running",
+     "The playState of the second player is running");
+ 
+   info("Play the same animation");
+-  yield animations.toggleSeveral([players[0]], false);
+-  state1 = yield players[0].getCurrentState();
++  await animations.toggleSeveral([players[0]], false);
++  state1 = await players[0].getCurrentState();
+   is(state1.playState, "running",
+     "The playState of the first player is running");
+-  state2 = yield players[1].getCurrentState();
++  state2 = await players[1].getCurrentState();
+   is(state2.playState, "running",
+     "The playState of the second player is running");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* checkStates(walker, animations, selectors, playState) {
++async function checkStates(walker, animations, selectors, playState) {
+   info("Checking the playState of all the nodes that have infinite running " +
+        "animations");
+ 
+   for (let selector of selectors) {
+     info("Getting the AnimationPlayerFront for node " + selector);
+-    let [player] = yield getPlayersFor(walker, animations, selector);
+-    yield player.ready();
+-    yield checkPlayState(player, selector, playState);
++    let [player] = await getPlayersFor(walker, animations, selector);
++    await player.ready();
++    await checkPlayState(player, selector, playState);
+   }
+ }
+ 
+-function* getPlayersFor(walker, animations, selector) {
+-  let node = yield walker.querySelector(walker.rootNode, selector);
++async function getPlayersFor(walker, animations, selector) {
++  let node = await walker.querySelector(walker.rootNode, selector);
+   return animations.getAnimationPlayersForNode(node);
+ }
+ 
+-function* checkPlayState(player, selector, expectedState) {
+-  let state = yield player.getCurrentState();
++async function checkPlayState(player, selector, expectedState) {
++  let state = await player.getCurrentState();
+   is(state.playState, expectedState,
+     "The playState of node " + selector + " is " + expectedState);
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_playerState.js b/devtools/server/tests/browser/browser_animation_playerState.js
+--- a/devtools/server/tests/browser/browser_animation_playerState.js
++++ b/devtools/server/tests/browser/browser_animation_playerState.js
+@@ -1,30 +1,30 @@
+ /* 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";
+ 
+ // Check the animation player's initial state
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+-  yield playerHasAnInitialState(walker, animations);
+-  yield playerStateIsCorrect(walker, animations);
++  await playerHasAnInitialState(walker, animations);
++  await playerStateIsCorrect(walker, animations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* playerHasAnInitialState(walker, animations) {
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
++async function playerHasAnInitialState(walker, animations) {
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
++  let [player] = await animations.getAnimationPlayersForNode(node);
+ 
+   ok(player.initialState, "The player front has an initial state");
+   ok("startTime" in player.initialState, "Player's state has startTime");
+   ok("currentTime" in player.initialState, "Player's state has currentTime");
+   ok("playState" in player.initialState, "Player's state has playState");
+   ok("playbackRate" in player.initialState, "Player's state has playbackRate");
+   ok("name" in player.initialState, "Player's state has name");
+   ok("duration" in player.initialState, "Player's state has duration");
+@@ -36,88 +36,88 @@ function* playerHasAnInitialState(walker
+   ok("direction" in player.initialState, "Player's state has direction");
+   ok("isRunningOnCompositor" in player.initialState,
+      "Player's state has isRunningOnCompositor");
+   ok("type" in player.initialState, "Player's state has type");
+   ok("documentCurrentTime" in player.initialState,
+      "Player's state has documentCurrentTime");
+ }
+ 
+-function* playerStateIsCorrect(walker, animations) {
++async function playerStateIsCorrect(walker, animations) {
+   info("Checking the state of the simple animation");
+ 
+-  let player = yield getAnimationPlayerForNode(walker, animations,
++  let player = await getAnimationPlayerForNode(walker, animations,
+                                                ".simple-animation", 0);
+-  let state = yield player.getCurrentState();
++  let state = await player.getCurrentState();
+   is(state.name, "move", "Name is correct");
+   is(state.duration, 200000, "Duration is correct");
+   // null = infinite count
+   is(state.iterationCount, null, "Iteration count is correct");
+   is(state.fill, "none", "Fill is correct");
+   is(state.easing, "linear", "Easing is correct");
+   is(state.direction, "normal", "Direction is correct");
+   is(state.playState, "running", "PlayState is correct");
+   is(state.playbackRate, 1, "PlaybackRate is correct");
+   is(state.type, "cssanimation", "Type is correct");
+ 
+   info("Checking the state of the transition");
+ 
+   player =
+-    yield getAnimationPlayerForNode(walker, animations, ".transition", 0);
+-  state = yield player.getCurrentState();
++    await getAnimationPlayerForNode(walker, animations, ".transition", 0);
++  state = await player.getCurrentState();
+   is(state.name, "width", "Transition name matches transition property");
+   is(state.duration, 500000, "Transition duration is correct");
+   // transitions run only once
+   is(state.iterationCount, 1, "Transition iteration count is correct");
+   is(state.fill, "backwards", "Transition fill is correct");
+   is(state.easing, "linear", "Transition easing is correct");
+   is(state.direction, "normal", "Transition direction is correct");
+   is(state.playState, "running", "Transition playState is correct");
+   is(state.playbackRate, 1, "Transition playbackRate is correct");
+   is(state.type, "csstransition", "Transition type is correct");
+   // chech easing in keyframe
+-  let keyframes = yield player.getFrames();
++  let keyframes = await player.getFrames();
+   is(keyframes.length, 2, "Transition length of keyframe is correct");
+   is(keyframes[0].easing,
+      "ease-out", "Transition kerframes's easing is correct");
+ 
+   info("Checking the state of one of multiple animations on a node");
+ 
+   // Checking the 2nd player
+-  player = yield getAnimationPlayerForNode(walker, animations,
++  player = await getAnimationPlayerForNode(walker, animations,
+                                            ".multiple-animations", 1);
+-  state = yield player.getCurrentState();
++  state = await player.getCurrentState();
+   is(state.name, "glow", "The 2nd animation's name is correct");
+   is(state.duration, 100000, "The 2nd animation's duration is correct");
+   is(state.iterationCount, 5, "The 2nd animation's iteration count is correct");
+   is(state.fill, "both", "The 2nd animation's fill is correct");
+   is(state.easing, "linear", "The 2nd animation's easing is correct");
+   is(state.direction, "reverse", "The 2nd animation's direction is correct");
+   is(state.playState, "running", "The 2nd animation's playState is correct");
+   is(state.playbackRate, 1, "The 2nd animation's playbackRate is correct");
+   // chech easing in keyframe
+-  keyframes = yield player.getFrames();
++  keyframes = await player.getFrames();
+   is(keyframes.length, 2, "The 2nd animation's length of keyframe is correct");
+   is(keyframes[0].easing,
+      "ease-out", "The 2nd animation's easing of kerframes is correct");
+ 
+   info("Checking the state of an animation with delay");
+ 
+-  player = yield getAnimationPlayerForNode(walker, animations,
++  player = await getAnimationPlayerForNode(walker, animations,
+                                            ".delayed-animation", 0);
+-  state = yield player.getCurrentState();
++  state = await player.getCurrentState();
+   is(state.delay, 5000, "The animation delay is correct");
+ 
+   info("Checking the state of an transition with delay");
+ 
+-  player = yield getAnimationPlayerForNode(walker, animations,
++  player = await getAnimationPlayerForNode(walker, animations,
+                                            ".delayed-transition", 0);
+-  state = yield player.getCurrentState();
++  state = await player.getCurrentState();
+   is(state.delay, 3000, "The transition delay is correct");
+ }
+ 
+-function* getAnimationPlayerForNode(walker, animations, nodeSelector, index) {
+-  let node = yield walker.querySelector(walker.rootNode, nodeSelector);
+-  let players = yield animations.getAnimationPlayersForNode(node);
++async function getAnimationPlayerForNode(walker, animations, nodeSelector, index) {
++  let node = await walker.querySelector(walker.rootNode, nodeSelector);
++  let players = await animations.getAnimationPlayersForNode(node);
+   let player = players[index];
+-  yield player.ready();
++  await player.ready();
+   return player;
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_reconstructState.js b/devtools/server/tests/browser/browser_animation_reconstructState.js
+--- a/devtools/server/tests/browser/browser_animation_reconstructState.js
++++ b/devtools/server/tests/browser/browser_animation_reconstructState.js
+@@ -2,37 +2,37 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // Check that, even though the AnimationPlayerActor only sends the bits of its
+ // state that change, the front reconstructs the whole state everytime.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+-  yield playerHasCompleteStateAtAllTimes(walker, animations);
++  await playerHasCompleteStateAtAllTimes(walker, animations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* playerHasCompleteStateAtAllTimes(walker, animations) {
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
+-  yield player.ready();
++async function playerHasCompleteStateAtAllTimes(walker, animations) {
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
++  let [player] = await animations.getAnimationPlayersForNode(node);
++  await player.ready();
+ 
+   // Get the list of state key names from the initialstate.
+   let keys = Object.keys(player.initialState);
+ 
+   // Get the state over and over again and check that the object returned
+   // contains all keys.
+   // Normally, only the currentTime will have changed in between 2 calls.
+   for (let i = 0; i < 10; i++) {
+-    yield player.refreshState();
++    await player.refreshState();
+     keys.forEach(key => {
+       ok(typeof player.state[key] !== "undefined",
+          "The state retrieved has key " + key);
+     });
+   }
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_refreshTransitions.js b/devtools/server/tests/browser/browser_animation_refreshTransitions.js
+--- a/devtools/server/tests/browser/browser_animation_refreshTransitions.js
++++ b/devtools/server/tests/browser/browser_animation_refreshTransitions.js
+@@ -3,58 +3,58 @@
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // When a transition finishes, no "removed" event is sent because it may still
+ // be used, but when it restarts again (transitions back), then a new
+ // AnimationPlayerFront should be sent, and the old one should be removed.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Retrieve the test node");
+-  let node = yield walker.querySelector(walker.rootNode, ".all-transitions");
++  let node = await walker.querySelector(walker.rootNode, ".all-transitions");
+ 
+   info("Retrieve the animation players for the node");
+-  let players = yield animations.getAnimationPlayersForNode(node);
++  let players = await animations.getAnimationPlayersForNode(node);
+   is(players.length, 0, "The node has no animation players yet");
+ 
+   info("Play a transition by adding the expand class, wait for mutations");
+   let onMutations = expectMutationEvents(animations, 2);
+-  yield ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
++  await ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+     let el = content.document.querySelector(".all-transitions");
+     el.classList.add("expand");
+   });
+-  let reportedMutations = yield onMutations;
++  let reportedMutations = await onMutations;
+ 
+   is(reportedMutations.length, 2, "2 mutation events were received");
+   is(reportedMutations[0].type, "added", "The first event was 'added'");
+   is(reportedMutations[1].type, "added", "The second event was 'added'");
+ 
+   info("Wait for the transitions to be finished");
+-  yield waitForEnd(reportedMutations[0].player);
+-  yield waitForEnd(reportedMutations[1].player);
++  await waitForEnd(reportedMutations[0].player);
++  await waitForEnd(reportedMutations[1].player);
+ 
+   info("Play the transition back by removing the class, wait for mutations");
+   onMutations = expectMutationEvents(animations, 4);
+-  yield ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
++  await ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+     let el = content.document.querySelector(".all-transitions");
+     el.classList.remove("expand");
+   });
+-  reportedMutations = yield onMutations;
++  reportedMutations = await onMutations;
+ 
+   is(reportedMutations.length, 4, "4 new mutation events were received");
+   is(reportedMutations.filter(m => m.type === "removed").length, 2,
+     "2 'removed' events were sent (for the old transitions)");
+   is(reportedMutations.filter(m => m.type === "added").length, 2,
+     "2 'added' events were sent (for the new transitions)");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+ function expectMutationEvents(animationsFront, nbOfEvents) {
+   return new Promise(resolve => {
+     let reportedMutations = [];
+     function onMutations(mutations) {
+       reportedMutations = [...reportedMutations, ...mutations];
+@@ -66,17 +66,17 @@ function expectMutationEvents(animations
+       }
+     }
+ 
+     info("Start listening for mutation events from the AnimationsFront");
+     animationsFront.on("mutations", onMutations);
+   });
+ }
+ 
+-function* waitForEnd(animationFront) {
++async function waitForEnd(animationFront) {
+   let playState;
+   while (playState !== "finished") {
+-    let state = yield animationFront.getCurrentState();
++    let state = await animationFront.getCurrentState();
+     playState = state.playState;
+     info("Wait for transition " + animationFront.state.name +
+          " to finish, playState=" + playState);
+   }
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_setCurrentTime.js b/devtools/server/tests/browser/browser_animation_setCurrentTime.js
+--- a/devtools/server/tests/browser/browser_animation_setCurrentTime.js
++++ b/devtools/server/tests/browser/browser_animation_setCurrentTime.js
+@@ -2,73 +2,73 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // Check that a player's currentTime can be changed and that the AnimationsActor
+ // allows changing many players' currentTimes at once.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+-  yield testSetCurrentTime(walker, animations);
+-  yield testSetCurrentTimes(walker, animations);
++  await testSetCurrentTime(walker, animations);
++  await testSetCurrentTimes(walker, animations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* testSetCurrentTime(walker, animations) {
++async function testSetCurrentTime(walker, animations) {
+   info("Retrieve an animated node");
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
+ 
+   info("Retrieve the animation player for the node");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
++  let [player] = await animations.getAnimationPlayersForNode(node);
+ 
+   ok(player.setCurrentTime, "Player has the setCurrentTime method");
+ 
+   info("Check that the setCurrentTime method can be called");
+   // Note that we don't check that it sets the animation to the right time here,
+   // this is too prone to intermittent failures, we'll do this later after
+   // pausing the animation. Here we merely test that the method doesn't fail.
+-  yield player.setCurrentTime(player.initialState.currentTime + 1000);
++  await player.setCurrentTime(player.initialState.currentTime + 1000);
+ 
+   info("Pause the animation so we can really test if setCurrentTime works");
+-  yield player.pause();
+-  let pausedState = yield player.getCurrentState();
++  await player.pause();
++  let pausedState = await player.getCurrentState();
+ 
+   info("Set the current time to currentTime + 5s");
+-  yield player.setCurrentTime(pausedState.currentTime + 5000);
++  await player.setCurrentTime(pausedState.currentTime + 5000);
+ 
+-  let updatedState1 = yield player.getCurrentState();
++  let updatedState1 = await player.getCurrentState();
+   is(Math.round(updatedState1.currentTime - pausedState.currentTime), 5000,
+     "The currentTime was updated to +5s");
+ 
+   info("Set the current time to currentTime - 2s");
+-  yield player.setCurrentTime(updatedState1.currentTime - 2000);
+-  let updatedState2 = yield player.getCurrentState();
++  await player.setCurrentTime(updatedState1.currentTime - 2000);
++  let updatedState2 = await player.getCurrentState();
+   is(Math.round(updatedState2.currentTime - updatedState1.currentTime), -2000,
+     "The currentTime was updated to -2s");
+ }
+ 
+-function* testSetCurrentTimes(walker, animations) {
++async function testSetCurrentTimes(walker, animations) {
+   ok(animations.setCurrentTimes, "The AnimationsActor has the right method");
+ 
+   info("Retrieve multiple animated node and its animation players");
+ 
+-  let nodeMulti = yield walker.querySelector(walker.rootNode,
++  let nodeMulti = await walker.querySelector(walker.rootNode,
+     ".multiple-animations");
+-  let players = (yield animations.getAnimationPlayersForNode(nodeMulti));
++  let players = (await animations.getAnimationPlayersForNode(nodeMulti));
+ 
+   ok(players.length > 1, "Node has more than 1 animation player");
+ 
+   info("Try to set multiple current times at once");
+-  yield animations.setCurrentTimes(players, 500, true);
++  await animations.setCurrentTimes(players, 500, true);
+ 
+   info("Get the states of players and verify their correctness");
+   for (let i = 0; i < players.length; i++) {
+-    let state = yield players[i].getCurrentState();
++    let state = await players[i].getCurrentState();
+     is(state.playState, "paused", `Player ${i + 1} is paused`);
+     is(state.currentTime, 500, `Player ${i + 1} has the right currentTime`);
+   }
+ }
+diff --git a/devtools/server/tests/browser/browser_animation_setPlaybackRate.js b/devtools/server/tests/browser/browser_animation_setPlaybackRate.js
+--- a/devtools/server/tests/browser/browser_animation_setPlaybackRate.js
++++ b/devtools/server/tests/browser/browser_animation_setPlaybackRate.js
+@@ -2,50 +2,50 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
+ "use strict";
+ 
+ // Check that a player's playbackRate can be changed, and that multiple players
+ // can have their rates changed at the same time.
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+   info("Retrieve an animated node");
+-  let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
++  let node = await walker.querySelector(walker.rootNode, ".simple-animation");
+ 
+   info("Retrieve the animation player for the node");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
++  let [player] = await animations.getAnimationPlayersForNode(node);
+ 
+   ok(player.setPlaybackRate, "Player has the setPlaybackRate method");
+ 
+   info("Change the rate to 10");
+-  yield player.setPlaybackRate(10);
++  await player.setPlaybackRate(10);
+ 
+   info("Query the state again");
+-  let state = yield player.getCurrentState();
++  let state = await player.getCurrentState();
+   is(state.playbackRate, 10, "The playbackRate was updated");
+ 
+   info("Change the rate back to 1");
+-  yield player.setPlaybackRate(1);
++  await player.setPlaybackRate(1);
+ 
+   info("Query the state again");
+-  state = yield player.getCurrentState();
++  state = await player.getCurrentState();
+   is(state.playbackRate, 1, "The playbackRate was changed back");
+ 
+   info("Retrieve several animation players and set their rates");
+-  node = yield walker.querySelector(walker.rootNode, "body");
+-  let players = yield animations.getAnimationPlayersForNode(node);
++  node = await walker.querySelector(walker.rootNode, "body");
++  let players = await animations.getAnimationPlayersForNode(node);
+ 
+   info("Change all animations in <body> to .5 rate");
+-  yield animations.setPlaybackRates(players, .5);
++  await animations.setPlaybackRates(players, .5);
+ 
+   info("Query their states and check they are correct");
+   for (let animPlayer of players) {
+-    let animPlayerState = yield animPlayer.getCurrentState();
++    let animPlayerState = await animPlayer.getCurrentState();
+     is(animPlayerState.playbackRate, .5, "The playbackRate was updated");
+   }
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_simple.js b/devtools/server/tests/browser/browser_animation_simple.js
+--- a/devtools/server/tests/browser/browser_animation_simple.js
++++ b/devtools/server/tests/browser/browser_animation_simple.js
+@@ -1,35 +1,35 @@
+ /* 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";
+ 
+ // Simple checks for the AnimationsActor
+ 
+-add_task(function* () {
+-  let {client, walker, animations} = yield initAnimationsFrontForUrl(
++add_task(async function () {
++  let {client, walker, animations} = await initAnimationsFrontForUrl(
+     "data:text/html;charset=utf-8,<title>test</title><div></div>");
+ 
+   ok(animations, "The AnimationsFront was created");
+   ok(animations.getAnimationPlayersForNode,
+      "The getAnimationPlayersForNode method exists");
+   ok(animations.toggleAll, "The toggleAll method exists");
+   ok(animations.playAll, "The playAll method exists");
+   ok(animations.pauseAll, "The pauseAll method exists");
+ 
+   let didThrow = false;
+   try {
+-    yield animations.getAnimationPlayersForNode(null);
++    await animations.getAnimationPlayersForNode(null);
+   } catch (e) {
+     didThrow = true;
+   }
+   ok(didThrow, "An exception was thrown for a missing NodeActor");
+ 
+-  let invalidNode = yield walker.querySelector(walker.rootNode, "title");
+-  let players = yield animations.getAnimationPlayersForNode(invalidNode);
++  let invalidNode = await walker.querySelector(walker.rootNode, "title");
++  let players = await animations.getAnimationPlayersForNode(invalidNode);
+   ok(Array.isArray(players), "An array of players was returned");
+   is(players.length, 0, "0 players have been returned for the invalid node");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_animation_updatedState.js b/devtools/server/tests/browser/browser_animation_updatedState.js
+--- a/devtools/server/tests/browser/browser_animation_updatedState.js
++++ b/devtools/server/tests/browser/browser_animation_updatedState.js
+@@ -2,55 +2,55 @@
+ /* Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/publicdomain/zero/1.0/ */
+ /* eslint-disable mozilla/no-arbitrary-setTimeout */
+ 
+ "use strict";
+ 
+ // Check the animation player's updated state
+ 
+-add_task(function* () {
++add_task(async function () {
+   let {client, walker, animations} =
+-    yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
++    await initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
+ 
+-  yield playStateIsUpdatedDynamically(walker, animations);
++  await playStateIsUpdatedDynamically(walker, animations);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+-function* playStateIsUpdatedDynamically(walker, animations) {
++async function playStateIsUpdatedDynamically(walker, animations) {
+   info("Getting the test node (which runs a very long animation)");
+   // The animation lasts for 100s, to avoid intermittents.
+-  let node = yield walker.querySelector(walker.rootNode, ".long-animation");
++  let node = await walker.querySelector(walker.rootNode, ".long-animation");
+ 
+   info("Getting the animation player front for this node");
+-  let [player] = yield animations.getAnimationPlayersForNode(node);
+-  yield player.ready();
++  let [player] = await animations.getAnimationPlayersForNode(node);
++  await player.ready();
+ 
+-  let state = yield player.getCurrentState();
++  let state = await player.getCurrentState();
+   is(state.playState, "running",
+     "The playState is running while the animation is running");
+ 
+   info("Change the animation's currentTime to be near the end and wait for " +
+        "it to finish");
+   let onFinished = waitForAnimationPlayState(player, "finished");
+   // Set the currentTime to 98s, knowing that the animation lasts for 100s.
+-  yield player.setCurrentTime(98 * 1000);
+-  state = yield onFinished;
++  await player.setCurrentTime(98 * 1000);
++  state = await onFinished;
+   is(state.playState, "finished",
+     "The animation has ended and the state has been updated");
+   ok(state.currentTime > player.initialState.currentTime,
+     "The currentTime has been updated");
+ }
+ 
+-function* waitForAnimationPlayState(player, playState) {
++async function waitForAnimationPlayState(player, playState) {
+   let state = {};
+   while (state.playState !== playState) {
+-    state = yield player.getCurrentState();
+-    yield wait(500);
++    state = await player.getCurrentState();
++    await wait(500);
+   }
+   return state;
+ }
+ 
+ function wait(ms) {
+   return new Promise(r => setTimeout(r, ms));
+ }
+diff --git a/devtools/server/tests/browser/browser_layout_getGrids.js b/devtools/server/tests/browser/browser_layout_getGrids.js
+--- a/devtools/server/tests/browser/browser_layout_getGrids.js
++++ b/devtools/server/tests/browser/browser_layout_getGrids.js
+@@ -102,32 +102,32 @@ const GRID_FRAGMENT_DATA = {
+         start: 100,
+         state: "static",
+         type: "explicit"
+       }
+     ]
+   }
+ };
+ 
+-add_task(function* () {
+-  let { client, walker, layout } = yield initLayoutFrontForUrl(MAIN_DOMAIN + "grid.html");
+-  let grids = yield layout.getGrids(walker.rootNode);
++add_task(async function () {
++  let { client, walker, layout } = await initLayoutFrontForUrl(MAIN_DOMAIN + "grid.html");
++  let grids = await layout.getGrids(walker.rootNode);
+   let grid = grids[0];
+   let { gridFragments } = grid;
+ 
+   is(grids.length, 1, "One grid was returned.");
+   is(gridFragments.length, 1, "One grid fragment was returned.");
+   ok(Array.isArray(gridFragments), "An array of grid fragments was returned.");
+   Assert.deepEqual(gridFragments[0], GRID_FRAGMENT_DATA,
+     "Got the correct grid fragment data.");
+ 
+   info("Get the grid container node front.");
+ 
+   try {
+-    let nodeFront = yield walker.getNodeFromActor(grids[0].actorID, ["containerEl"]);
++    let nodeFront = await walker.getNodeFromActor(grids[0].actorID, ["containerEl"]);
+     ok(nodeFront, "Got the grid container node front.");
+   } catch (e) {
+     ok(false, "Did not get grid container node front.");
+   }
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_layout_simple.js b/devtools/server/tests/browser/browser_layout_simple.js
+--- a/devtools/server/tests/browser/browser_layout_simple.js
++++ b/devtools/server/tests/browser/browser_layout_simple.js
+@@ -1,31 +1,31 @@
+ /* 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";
+ 
+ // Simple checks for the LayoutActor and GridActor
+ 
+-add_task(function* () {
+-  let {client, walker, layout} = yield initLayoutFrontForUrl(
++add_task(async function () {
++  let {client, walker, layout} = await initLayoutFrontForUrl(
+     "data:text/html;charset=utf-8,<title>test</title><div></div>");
+ 
+   ok(layout, "The LayoutFront was created");
+   ok(layout.getGrids, "The getGrids method exists");
+ 
+   let didThrow = false;
+   try {
+-    yield layout.getGrids(null);
++    await layout.getGrids(null);
+   } catch (e) {
+     didThrow = true;
+   }
+   ok(didThrow, "An exception was thrown for a missing NodeActor in getGrids");
+ 
+-  let invalidNode = yield walker.querySelector(walker.rootNode, "title");
+-  let grids = yield layout.getGrids(invalidNode);
++  let invalidNode = await walker.querySelector(walker.rootNode, "title");
++  let grids = await layout.getGrids(invalidNode);
+   ok(Array.isArray(grids), "An array of grids was returned");
+   is(grids.length, 0, "0 grids have been returned for the invalid node");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-cycle-collection.js b/devtools/server/tests/browser/browser_markers-cycle-collection.js
+--- a/devtools/server/tests/browser/browser_markers-cycle-collection.js
++++ b/devtools/server/tests/browser/browser_markers-cycle-collection.js
+@@ -4,33 +4,33 @@
+ /**
+  * Test that we get "nsCycleCollector::Collect" and
+  * "nsCycleCollector::ForgetSkippable" markers when we force cycle collection.
+  */
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
++add_task(async function () {
+   // This test runs very slowly on linux32 debug EC2 instances.
+   requestLongerTimeout(2);
+ 
+-  yield addTab(MAIN_DOMAIN + "doc_force_cc.html");
++  await addTab(MAIN_DOMAIN + "doc_force_cc.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
+-  let rec = yield front.startRecording({ withMarkers: true });
++  await front.connect();
++  let rec = await front.startRecording({ withMarkers: true });
+ 
+-  let markers = yield waitForMarkerType(front,
++  let markers = await waitForMarkerType(front,
+     ["nsCycleCollector::Collect", "nsCycleCollector::ForgetSkippable"]);
+-  yield front.stopRecording(rec);
++  await front.stopRecording(rec);
+ 
+   ok(markers.some(m => m.name === "nsCycleCollector::Collect"),
+     "got some nsCycleCollector::Collect markers");
+   ok(markers.some(m => m.name === "nsCycleCollector::ForgetSkippable"),
+     "got some nsCycleCollector::Collect markers");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-docloading-01.js b/devtools/server/tests/browser/browser_markers-docloading-01.js
+--- a/devtools/server/tests/browser/browser_markers-docloading-01.js
++++ b/devtools/server/tests/browser/browser_markers-docloading-01.js
+@@ -4,36 +4,36 @@
+ /**
+  * Test that we get DOMContentLoaded and Load markers
+  */
+ "use strict";
+ 
+ const { TimelineFront } = require("devtools/shared/fronts/timeline");
+ const MARKER_NAMES = ["document::DOMContentLoaded", "document::Load"];
+ 
+-add_task(function* () {
+-  let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
++add_task(async function () {
++  let browser = await addTab(MAIN_DOMAIN + "doc_innerHTML.html");
+   // eslint-disable-next-line mozilla/no-cpows-in-tests
+   let doc = browser.contentDocument;
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = TimelineFront(client, form);
+-  let rec = yield front.start({ withMarkers: true });
++  let rec = await front.start({ withMarkers: true });
+ 
+   front.once("doc-loading", e => {
+     ok(false, "Should not be emitting doc-loading events.");
+   });
+ 
+   executeSoon(() => doc.location.reload());
+ 
+-  yield waitForMarkerType(front, MARKER_NAMES, () => true, e => e, "markers");
+-  yield front.stop(rec);
++  await waitForMarkerType(front, MARKER_NAMES, () => true, e => e, "markers");
++  await front.stop(rec);
+ 
+   ok(true, "Found the required marker names.");
+ 
+   // Wait some more time to make sure the 'doc-loading' events never get fired.
+-  yield DevToolsUtils.waitForTime(1000);
++  await DevToolsUtils.waitForTime(1000);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-docloading-02.js b/devtools/server/tests/browser/browser_markers-docloading-02.js
+--- a/devtools/server/tests/browser/browser_markers-docloading-02.js
++++ b/devtools/server/tests/browser/browser_markers-docloading-02.js
+@@ -4,34 +4,34 @@
+ /**
+  * Test that we get DOMContentLoaded and Load markers
+  */
+ "use strict";
+ 
+ const { TimelineFront } = require("devtools/shared/fronts/timeline");
+ const MARKER_NAMES = ["document::DOMContentLoaded", "document::Load"];
+ 
+-add_task(function* () {
+-  let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
++add_task(async function () {
++  let browser = await addTab(MAIN_DOMAIN + "doc_innerHTML.html");
+   // eslint-disable-next-line mozilla/no-cpows-in-tests
+   let doc = browser.contentDocument;
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = TimelineFront(client, form);
+-  let rec = yield front.start({ withMarkers: true, withDocLoadingEvents: true });
++  let rec = await front.start({ withMarkers: true, withDocLoadingEvents: true });
+ 
+-  yield new Promise(resolve => {
++  await new Promise(resolve => {
+     front.once("doc-loading", resolve);
+     doc.location.reload();
+   });
+ 
+   ok(true, "At least one doc-loading event got fired.");
+ 
+-  yield waitForMarkerType(front, MARKER_NAMES, () => true, e => e, "markers");
+-  yield front.stop(rec);
++  await waitForMarkerType(front, MARKER_NAMES, () => true, e => e, "markers");
++  await front.stop(rec);
+ 
+   ok(true, "Found the required marker names.");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-docloading-03.js b/devtools/server/tests/browser/browser_markers-docloading-03.js
+--- a/devtools/server/tests/browser/browser_markers-docloading-03.js
++++ b/devtools/server/tests/browser/browser_markers-docloading-03.js
+@@ -4,38 +4,38 @@
+ /**
+  * Test that we get DOMContentLoaded and Load markers
+  */
+ "use strict";
+ 
+ const { TimelineFront } = require("devtools/shared/fronts/timeline");
+ const MARKER_NAMES = ["document::DOMContentLoaded", "document::Load"];
+ 
+-add_task(function* () {
+-  let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
++add_task(async function () {
++  let browser = await addTab(MAIN_DOMAIN + "doc_innerHTML.html");
+   // eslint-disable-next-line mozilla/no-cpows-in-tests
+   let doc = browser.contentDocument;
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = TimelineFront(client, form);
+-  let rec = yield front.start({ withDocLoadingEvents: true });
++  let rec = await front.start({ withDocLoadingEvents: true });
+ 
+   waitForMarkerType(front, MARKER_NAMES, () => true, e => e, "markers").then(e => {
+     ok(false, "Should not be emitting doc-loading markers.");
+   });
+ 
+-  yield new Promise(resolve => {
++  await new Promise(resolve => {
+     front.once("doc-loading", resolve);
+     doc.location.reload();
+   });
+ 
+   ok(true, "At least one doc-loading event got fired.");
+ 
+-  yield front.stop(rec);
++  await front.stop(rec);
+ 
+   // Wait some more time to make sure the 'doc-loading' markers never get fired.
+-  yield DevToolsUtils.waitForTime(1000);
++  await DevToolsUtils.waitForTime(1000);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-gc.js b/devtools/server/tests/browser/browser_markers-gc.js
+--- a/devtools/server/tests/browser/browser_markers-gc.js
++++ b/devtools/server/tests/browser/browser_markers-gc.js
+@@ -4,28 +4,28 @@
+ /**
+  * Test that we get "GarbageCollection" markers.
+  */
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const MARKER_NAME = "GarbageCollection";
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_force_gc.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_force_gc.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
+-  let rec = yield front.startRecording({ withMarkers: true });
++  await front.connect();
++  let rec = await front.startRecording({ withMarkers: true });
+ 
+-  let markers = yield waitForMarkerType(front, MARKER_NAME);
+-  yield front.stopRecording(rec);
++  let markers = await waitForMarkerType(front, MARKER_NAME);
++  await front.stopRecording(rec);
+ 
+   ok(markers.some(m => m.name === MARKER_NAME), `got some ${MARKER_NAME} markers`);
+   ok(markers.every(({causeName}) => typeof causeName === "string"),
+     "All markers have a causeName.");
+   ok(markers.every(({cycle}) => typeof cycle === "number"),
+     "All markers have a `cycle` ID.");
+ 
+   markers = rec.getMarkers();
+@@ -41,11 +41,11 @@ add_task(function* () {
+         start time (${current.start}) thanprevious: ${previousStart}`);
+       ordered = false;
+     }
+     return current.start;
+   });
+ 
+   is(ordered, true, "All GC and non-GC markers are in order by start time.");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-minor-gc.js b/devtools/server/tests/browser/browser_markers-minor-gc.js
+--- a/devtools/server/tests/browser/browser_markers-minor-gc.js
++++ b/devtools/server/tests/browser/browser_markers-minor-gc.js
+@@ -4,30 +4,30 @@
+ /**
+  * Test that we get "MinorGC" markers when we continue to steadily allocate
+  * objects.
+  */
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
++add_task(async function () {
+   // This test runs very slowly on linux32 debug EC2 instances.
+   requestLongerTimeout(2);
+ 
+-  yield addTab(MAIN_DOMAIN + "doc_allocations.html");
++  await addTab(MAIN_DOMAIN + "doc_allocations.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
+-  let rec = yield front.startRecording({ withMarkers: true });
++  await front.connect();
++  let rec = await front.startRecording({ withMarkers: true });
+ 
+-  let markers = yield waitForMarkerType(front, ["MinorGC"]);
+-  yield front.stopRecording(rec);
++  let markers = await waitForMarkerType(front, ["MinorGC"]);
++  await front.stopRecording(rec);
+ 
+   ok(markers.some(m => m.name === "MinorGC" && m.causeName),
+      "got some MinorGC markers");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-parse-html.js b/devtools/server/tests/browser/browser_markers-parse-html.js
+--- a/devtools/server/tests/browser/browser_markers-parse-html.js
++++ b/devtools/server/tests/browser/browser_markers-parse-html.js
+@@ -4,26 +4,26 @@
+ /**
+  * Test that we get "Parse HTML" markers.
+  */
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const MARKER_NAME = "Parse HTML";
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_innerHTML.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
+-  let rec = yield front.startRecording({ withMarkers: true });
++  await front.connect();
++  let rec = await front.startRecording({ withMarkers: true });
+ 
+-  let markers = yield waitForMarkerType(front, MARKER_NAME);
+-  yield front.stopRecording(rec);
++  let markers = await waitForMarkerType(front, MARKER_NAME);
++  await front.stopRecording(rec);
+ 
+   ok(markers.some(m => m.name === MARKER_NAME), `got some ${MARKER_NAME} markers`);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-styles.js b/devtools/server/tests/browser/browser_markers-styles.js
+--- a/devtools/server/tests/browser/browser_markers-styles.js
++++ b/devtools/server/tests/browser/browser_markers-styles.js
+@@ -4,27 +4,27 @@
+ /**
+  * Test that we get "Styles" markers with correct meta.
+  */
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const MARKER_NAME = "Styles";
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
+-  let rec = yield front.startRecording({ withMarkers: true });
++  await front.connect();
++  let rec = await front.startRecording({ withMarkers: true });
+ 
+-  let markers = yield waitForMarkerType(front, MARKER_NAME);
++  let markers = await waitForMarkerType(front, MARKER_NAME);
+ 
+-  yield front.stopRecording(rec);
++  await front.stopRecording(rec);
+ 
+   ok(markers.some(m => m.name === MARKER_NAME), `got some ${MARKER_NAME} markers`);
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_markers-timestamp.js b/devtools/server/tests/browser/browser_markers-timestamp.js
+--- a/devtools/server/tests/browser/browser_markers-timestamp.js
++++ b/devtools/server/tests/browser/browser_markers-timestamp.js
+@@ -6,41 +6,41 @@
+  */
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const { pmmConsoleMethod, pmmLoadFrameScripts, pmmClearFrameScripts }
+   = require("devtools/client/performance/test/helpers/profiler-mm-utils");
+ const MARKER_NAME = "TimeStamp";
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
+-  let rec = yield front.startRecording({ withMarkers: true });
++  await front.connect();
++  let rec = await front.startRecording({ withMarkers: true });
+ 
+   pmmLoadFrameScripts(gBrowser);
+   pmmConsoleMethod("timeStamp");
+   pmmConsoleMethod("timeStamp", "myLabel");
+ 
+-  let markers = yield waitForMarkerType(front, MARKER_NAME, m => m.length >= 2);
++  let markers = await waitForMarkerType(front, MARKER_NAME, m => m.length >= 2);
+ 
+-  yield front.stopRecording(rec);
++  await front.stopRecording(rec);
+ 
+   ok(markers.every(({stack}) => typeof stack === "number"),
+     "All markers have stack references.");
+   ok(markers.every(({name}) => name === "TimeStamp"),
+     "All markers found are TimeStamp markers");
+   ok(markers.length === 2, "found 2 TimeStamp markers");
+   ok(markers.every(({start, end}) => typeof start === "number" && start === end),
+     "All markers have equal start and end times");
+   is(markers[0].causeName, void 0, "Unlabeled timestamps have an empty causeName");
+   is(markers[1].causeName, "myLabel", "Labeled timestamps have correct causeName");
+ 
+   pmmClearFrameScripts();
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-allocation-data.js b/devtools/server/tests/browser/browser_perf-allocation-data.js
+--- a/devtools/server/tests/browser/browser_perf-allocation-data.js
++++ b/devtools/server/tests/browser/browser_perf-allocation-data.js
+@@ -4,38 +4,38 @@
+ /**
+  * Test that we have allocation data coming from the front.
+  */
+ 
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_allocations.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_allocations.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+-  let rec = yield front.startRecording(
++  let rec = await front.startRecording(
+     { withMarkers: true, withAllocations: true, withTicks: true });
+ 
+-  yield waitUntil(() => rec.getAllocations().frames.length);
+-  yield waitUntil(() => rec.getAllocations().timestamps.length);
+-  yield waitUntil(() => rec.getAllocations().sizes.length);
+-  yield waitUntil(() => rec.getAllocations().sites.length);
++  await waitUntil(() => rec.getAllocations().frames.length);
++  await waitUntil(() => rec.getAllocations().timestamps.length);
++  await waitUntil(() => rec.getAllocations().sizes.length);
++  await waitUntil(() => rec.getAllocations().sites.length);
+ 
+-  yield front.stopRecording(rec);
++  await front.stopRecording(rec);
+ 
+   let { timestamps, sizes } = rec.getAllocations();
+ 
+   is(timestamps.length, sizes.length, "we have the same amount of timestamps and sizes");
+   ok(timestamps.every(time => time > 0 && typeof time === "number"),
+     "all timestamps have numeric values");
+   ok(sizes.every(n => n > 0 && typeof n === "number"), "all sizes are positive numbers");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-profiler-01.js b/devtools/server/tests/browser/browser_perf-profiler-01.js
+--- a/devtools/server/tests/browser/browser_perf-profiler-01.js
++++ b/devtools/server/tests/browser/browser_perf-profiler-01.js
+@@ -7,40 +7,40 @@
+  * a recording is stopped.
+  */
+ 
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const { pmmIsProfilerActive, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+   pmmLoadFrameScripts(gBrowser);
+ 
+-  ok(!(yield pmmIsProfilerActive()),
++  ok(!(await pmmIsProfilerActive()),
+     "The built-in profiler module should not have been automatically started.");
+ 
+-  let rec = yield front.startRecording();
+-  yield front.stopRecording(rec);
+-  ok((yield pmmIsProfilerActive()),
++  let rec = await front.startRecording();
++  await front.stopRecording(rec);
++  ok((await pmmIsProfilerActive()),
+     "The built-in profiler module should still be active (1).");
+ 
+-  rec = yield front.startRecording();
+-  yield front.stopRecording(rec);
+-  ok((yield pmmIsProfilerActive()),
++  rec = await front.startRecording();
++  await front.stopRecording(rec);
++  ok((await pmmIsProfilerActive()),
+     "The built-in profiler module should still be active (2).");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+ 
+-  ok(!(yield pmmIsProfilerActive()),
++  ok(!(await pmmIsProfilerActive()),
+     "The built-in profiler module should no longer be active.");
+ 
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-profiler-02.js b/devtools/server/tests/browser/browser_perf-profiler-02.js
+--- a/devtools/server/tests/browser/browser_perf-profiler-02.js
++++ b/devtools/server/tests/browser/browser_perf-profiler-02.js
+@@ -6,43 +6,43 @@
+  * is destroyed if there are other consumers using it.
+  */
+ 
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const { pmmIsProfilerActive, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let firstFront = PerformanceFront(client, form);
+-  yield firstFront.connect();
++  await firstFront.connect();
+ 
+   pmmLoadFrameScripts(gBrowser);
+ 
+-  yield firstFront.startRecording();
++  await firstFront.startRecording();
+ 
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+   let client2 = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form2 = yield connectDebuggerClient(client2);
++  let form2 = await connectDebuggerClient(client2);
+   let secondFront = PerformanceFront(client2, form2);
+-  yield secondFront.connect();
++  await secondFront.connect();
+   pmmLoadFrameScripts(gBrowser);
+ 
+-  yield secondFront.startRecording();
++  await secondFront.startRecording();
+ 
+   // Manually teardown the tabs so we can check profiler status
+-  yield secondFront.destroy();
+-  yield client2.close();
+-  ok((yield pmmIsProfilerActive()),
++  await secondFront.destroy();
++  await client2.close();
++  ok((await pmmIsProfilerActive()),
+     "The built-in profiler module should still be active.");
+ 
+-  yield firstFront.destroy();
+-  yield client.close();
+-  ok(!(yield pmmIsProfilerActive()),
++  await firstFront.destroy();
++  await client.close();
++  ok(!(await pmmIsProfilerActive()),
+     "The built-in profiler module should no longer be active.");
+ 
+   gBrowser.removeCurrentTab();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-profiler-03.js b/devtools/server/tests/browser/browser_perf-profiler-03.js
+--- a/devtools/server/tests/browser/browser_perf-profiler-03.js
++++ b/devtools/server/tests/browser/browser_perf-profiler-03.js
+@@ -8,49 +8,49 @@
+  * addon was installed and automatically activated the profiler module).
+  */
+ 
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ const { pmmIsProfilerActive, pmmStartProfiler, pmmLoadFrameScripts, pmmClearFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
+ 
+-add_task(function* () {
++add_task(async function () {
+   // Ensure the profiler is already running when the test starts.
+   pmmLoadFrameScripts(gBrowser);
+   let entries = 1000000;
+   let interval = 1;
+   let features = ["js"];
+-  yield pmmStartProfiler({ entries, interval, features });
++  await pmmStartProfiler({ entries, interval, features });
+ 
+-  ok((yield pmmIsProfilerActive()),
++  ok((await pmmIsProfilerActive()),
+     "The built-in profiler module should still be active.");
+ 
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let firstFront = PerformanceFront(client, form);
+-  yield firstFront.connect();
++  await firstFront.connect();
+ 
+-  yield firstFront.startRecording();
++  await firstFront.startRecording();
+ 
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+   let client2 = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form2 = yield connectDebuggerClient(client2);
++  let form2 = await connectDebuggerClient(client2);
+   let secondFront = PerformanceFront(client2, form2);
+-  yield secondFront.connect();
++  await secondFront.connect();
+ 
+-  yield secondFront.destroy();
+-  yield client2.close();
+-  ok((yield pmmIsProfilerActive()),
++  await secondFront.destroy();
++  await client2.close();
++  ok((await pmmIsProfilerActive()),
+     "The built-in profiler module should still be active.");
+ 
+-  yield firstFront.destroy();
+-  yield client.close();
+-  ok(!(yield pmmIsProfilerActive()),
++  await firstFront.destroy();
++  await client.close();
++  ok(!(await pmmIsProfilerActive()),
+     "The built-in profiler module should have been automatically stopped.");
+ 
+   pmmClearFrameScripts();
+ 
+   gBrowser.removeCurrentTab();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-realtime-markers.js b/devtools/server/tests/browser/browser_perf-realtime-markers.js
+--- a/devtools/server/tests/browser/browser_perf-realtime-markers.js
++++ b/devtools/server/tests/browser/browser_perf-realtime-markers.js
+@@ -4,24 +4,24 @@
+ /**
+  * Test functionality of real time markers.
+  */
+ 
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+   let lastMemoryDelta = 0;
+   let lastTickDelta = 0;
+ 
+   let counters = {
+     markers: [],
+     memory: [],
+     ticks: []
+@@ -30,28 +30,28 @@ add_task(function* () {
+   let deferreds = {
+     markers: defer(),
+     memory: defer(),
+     ticks: defer()
+   };
+ 
+   front.on("timeline-data", handler);
+ 
+-  let rec = yield front.startRecording(
++  let rec = await front.startRecording(
+     { withMarkers: true, withMemory: true, withTicks: true });
+-  yield Promise.all(Object.keys(deferreds).map(type => deferreds[type].promise));
+-  yield front.stopRecording(rec);
++  await Promise.all(Object.keys(deferreds).map(type => deferreds[type].promise));
++  await front.stopRecording(rec);
+   front.off("timeline-data", handler);
+ 
+   is(counters.markers.length, 1, "one marker event fired.");
+   is(counters.memory.length, 3, "three memory events fired.");
+   is(counters.ticks.length, 3, "three ticks events fired.");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ 
+   function handler(name, data) {
+     if (name === "markers") {
+       if (counters.markers.length >= 1) {
+         return;
+       }
+       ok(data.markers[0].start, "received atleast one marker with `start`");
+diff --git a/devtools/server/tests/browser/browser_perf-recording-actor-01.js b/devtools/server/tests/browser/browser_perf-recording-actor-01.js
+--- a/devtools/server/tests/browser/browser_perf-recording-actor-01.js
++++ b/devtools/server/tests/browser/browser_perf-recording-actor-01.js
+@@ -5,78 +5,78 @@
+  * Tests the state of a recording rec from start to finish for recording,
+  * completed, and rec data.
+  */
+ 
+ "use strict";
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+-  let rec = yield front.startRecording(
++  let rec = await front.startRecording(
+     { withMarkers: true, withTicks: true, withMemory: true });
+   ok(rec.isRecording(), "RecordingModel is recording when created");
+-  yield busyWait(100);
+-  yield waitUntil(() => rec.getMemory().length);
++  await busyWait(100);
++  await waitUntil(() => rec.getMemory().length);
+   ok(true, "RecordingModel populates memory while recording");
+-  yield waitUntil(() => rec.getTicks().length);
++  await waitUntil(() => rec.getTicks().length);
+   ok(true, "RecordingModel populates ticks while recording");
+-  yield waitUntil(() => rec.getMarkers().length);
++  await waitUntil(() => rec.getMarkers().length);
+   ok(true, "RecordingModel populates markers while recording");
+ 
+   ok(!rec.isCompleted(), "RecordingModel is not completed when still recording");
+ 
+   let stopping = once(front, "recording-stopping");
+   let stopped = once(front, "recording-stopped");
+   front.stopRecording(rec);
+ 
+-  yield stopping;
++  await stopping;
+   ok(!rec.isRecording(), "on 'recording-stopping', model is no longer recording");
+   // This handler should be called BEFORE "recording-stopped" is called, as
+   // there is some delay, but in the event where "recording-stopped" finishes
+   // before we check here, ensure that we're atleast in the right state
+   if (rec.getProfile()) {
+     ok(rec.isCompleted(), "recording is completed once it has profile data");
+   } else {
+     ok(!rec.isCompleted(), "recording is not yet completed on 'recording-stopping'");
+     ok(rec.isFinalizing(),
+       "recording is finalized between 'recording-stopping' and 'recording-stopped'");
+   }
+ 
+-  yield stopped;
++  await stopped;
+   ok(!rec.isRecording(), "on 'recording-stopped', model is still no longer recording");
+   ok(rec.isCompleted(), "on 'recording-stopped', model is considered 'complete'");
+ 
+   checkSystemInfo(rec, "Host");
+   checkSystemInfo(rec, "Client");
+ 
+   // Export and import a rec, and ensure it has the correct state.
+   let file = FileUtils.getFile("TmpD", ["tmpprofile.json"]);
+   file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
+-  yield rec.exportRecording(file);
++  await rec.exportRecording(file);
+ 
+-  let importedModel = yield front.importRecording(file);
++  let importedModel = await front.importRecording(file);
+ 
+   ok(importedModel.isCompleted(), "All imported recordings should be completed");
+   ok(!importedModel.isRecording(), "All imported recordings should not be recording");
+   ok(importedModel.isImported(), "All imported recordings should be considerd imported");
+ 
+   checkSystemInfo(importedModel, "Host");
+   checkSystemInfo(importedModel, "Client");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+ function checkSystemInfo(recording, type) {
+   let data = recording[`get${type}SystemInfo`]();
+   for (let field of ["appid", "apptype", "vendor", "name", "version"]) {
+     ok(data[field], `get${type}SystemInfo() has ${field} property`);
+   }
+diff --git a/devtools/server/tests/browser/browser_perf-recording-actor-02.js b/devtools/server/tests/browser/browser_perf-recording-actor-02.js
+--- a/devtools/server/tests/browser/browser_perf-recording-actor-02.js
++++ b/devtools/server/tests/browser/browser_perf-recording-actor-02.js
+@@ -7,53 +7,53 @@
+ 
+ "use strict";
+ 
+ var BUFFER_SIZE = 20000;
+ var config = { bufferSize: BUFFER_SIZE };
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+-  yield front.setProfilerStatusInterval(10);
+-  let model = yield front.startRecording(config);
+-  let stats = yield once(front, "profiler-status");
++  await front.setProfilerStatusInterval(10);
++  let model = await front.startRecording(config);
++  let stats = await once(front, "profiler-status");
+   is(stats.totalSize, BUFFER_SIZE,
+     `profiler-status event has totalSize: ${stats.totalSize}`);
+   ok(stats.position < BUFFER_SIZE,
+     `profiler-status event has position: ${stats.position}`);
+   ok(stats.generation >= 0, `profiler-status event has generation: ${stats.generation}`);
+   ok(stats.isActive, "profiler-status event is isActive");
+   is(typeof stats.currentTime, "number", "profiler-status event has currentTime");
+ 
+   // Halt once more for a buffer status to ensure we're beyond 0
+-  yield once(front, "profiler-status");
++  await once(front, "profiler-status");
+ 
+   let lastBufferStatus = 0;
+   let checkCount = 0;
+   while (lastBufferStatus < 1) {
+     let currentBufferStatus = front.getBufferUsageForRecording(model);
+     ok(currentBufferStatus > lastBufferStatus,
+       `buffer is more filled than before: ${currentBufferStatus} > ${lastBufferStatus}`);
+     lastBufferStatus = currentBufferStatus;
+     checkCount++;
+-    yield once(front, "profiler-status");
++    await once(front, "profiler-status");
+   }
+ 
+   ok(checkCount >= 1, "atleast 1 event were fired until the buffer was filled");
+   is(lastBufferStatus, 1, "buffer usage cannot surpass 100%");
+-  yield front.stopRecording(model);
++  await front.stopRecording(model);
+ 
+   is(front.getBufferUsageForRecording(model), null,
+     "buffer usage should be null when no longer recording.");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-samples-01.js b/devtools/server/tests/browser/browser_perf-samples-01.js
+--- a/devtools/server/tests/browser/browser_perf-samples-01.js
++++ b/devtools/server/tests/browser/browser_perf-samples-01.js
+@@ -8,50 +8,50 @@
+ 
+ "use strict";
+ 
+ // time in ms
+ const WAIT_TIME = 1000;
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
+-  yield SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+   // Perform the first recording...
+ 
+-  let firstRecording = yield front.startRecording();
++  let firstRecording = await front.startRecording();
+   let firstRecordingStartTime = firstRecording._startTime;
+   info("Started profiling at: " + firstRecordingStartTime);
+ 
+   // allow the profiler module to sample some cpu activity
+   busyWait(WAIT_TIME);
+ 
+-  yield front.stopRecording(firstRecording);
++  await front.stopRecording(firstRecording);
+ 
+   ok(firstRecording.getDuration() >= WAIT_TIME,
+     "The first recording duration is correct.");
+ 
+   // Perform the second recording...
+ 
+-  let secondRecording = yield front.startRecording();
++  let secondRecording = await front.startRecording();
+   let secondRecordingStartTime = secondRecording._startTime;
+   info("Started profiling at: " + secondRecordingStartTime);
+ 
+   // allow the profiler module to sample more cpu activity
+   busyWait(WAIT_TIME);
+ 
+-  yield front.stopRecording(secondRecording);
++  await front.stopRecording(secondRecording);
+   let secondRecordingProfile = secondRecording.getProfile();
+   let secondRecordingSamples = secondRecordingProfile.threads[0].samples.data;
+ 
+   ok(secondRecording.getDuration() >= WAIT_TIME,
+     "The second recording duration is correct.");
+ 
+   const TIME_SLOT = secondRecordingProfile.threads[0].samples.schema.time;
+   ok(secondRecordingSamples[0][TIME_SLOT] < secondRecordingStartTime,
+@@ -59,12 +59,12 @@ add_task(function* () {
+   ok(secondRecordingSamples[0][TIME_SLOT] > 0,
+     "The second recorded sample times were normalized correctly.");
+   ok(!secondRecordingSamples.find(
+         e => e[TIME_SLOT] + secondRecordingStartTime <= firstRecording.getDuration()
+     ),
+     "There should be no samples from the first recording in the second one, " +
+     "even though the total number of frames did not overflow.");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_perf-samples-02.js b/devtools/server/tests/browser/browser_perf-samples-02.js
+--- a/devtools/server/tests/browser/browser_perf-samples-02.js
++++ b/devtools/server/tests/browser/browser_perf-samples-02.js
+@@ -9,30 +9,30 @@
+ 
+ "use strict";
+ 
+ // Time in ms
+ const WAIT_TIME = 1000;
+ 
+ const { PerformanceFront } = require("devtools/shared/fronts/performance");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "doc_perf.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "doc_perf.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = PerformanceFront(client, form);
+-  yield front.connect();
++  await front.connect();
+ 
+-  let rec = yield front.startRecording();
++  let rec = await front.startRecording();
+   // allow the profiler module to sample some cpu activity
+   busyWait(WAIT_TIME);
+ 
+-  yield front.stopRecording(rec);
++  await front.stopRecording(rec);
+   let profile = rec.getProfile();
+   let sampleCount = 0;
+ 
+   for (let thread of profile.threads) {
+     info("Checking thread: " + thread.name);
+ 
+     for (let sample of thread.samples.data) {
+       sampleCount++;
+@@ -42,18 +42,18 @@ add_task(function* () {
+         ok(false, "The sample " + stack.toSource() + " doesn't have a root node.");
+       }
+     }
+   }
+ 
+   ok(sampleCount > 0,
+     "At least some samples have been iterated over, checking for root nodes.");
+ 
+-  yield front.destroy();
+-  yield client.close();
++  await front.destroy();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+ /**
+  * Inflate a particular sample's stack and return an array of strings.
+  */
+ function getInflatedStackLocations(thread, sample) {
+   let stackTable = thread.stackTable;
+diff --git a/devtools/server/tests/browser/browser_register_actor.js b/devtools/server/tests/browser/browser_register_actor.js
+--- a/devtools/server/tests/browser/browser_register_actor.js
++++ b/devtools/server/tests/browser/browser_register_actor.js
+@@ -46,27 +46,27 @@ function cleanupActor(actorFront) {
+ 
+ function getCount(actor, callback) {
+   return gClient.request({
+     to: actor,
+     type: "count"
+   }, callback);
+ }
+ 
+-var checkActorState = Task.async(function* (helloActor, callback) {
+-  let response = yield getCount(helloActor);
++var checkActorState = async function (helloActor, callback) {
++  let response = await getCount(helloActor);
+   ok(!response.error, "No error");
+   is(response.count, 1, "The counter must be valid");
+ 
+-  response = yield getCount(helloActor);
++  response = await getCount(helloActor);
+   ok(!response.error, "No error");
+   is(response.count, 2, "The counter must be valid");
+ 
+-  let {tabs, selected} = yield gClient.listTabs();
++  let {tabs, selected} = await gClient.listTabs();
+   let tab = tabs[selected];
+   is(tab.helloActor, helloActor, "Hello actor must be valid");
+ 
+-  response = yield getCount(helloActor);
++  response = await getCount(helloActor);
+   ok(!response.error, "No error");
+   is(response.count, 3, "The counter must be valid");
+ 
+   callback();
+-});
++};
+diff --git a/devtools/server/tests/browser/browser_storage_cookies-duplicate-names.js b/devtools/server/tests/browser/browser_storage_cookies-duplicate-names.js
+--- a/devtools/server/tests/browser/browser_storage_cookies-duplicate-names.js
++++ b/devtools/server/tests/browser/browser_storage_cookies-duplicate-names.js
+@@ -37,45 +37,45 @@ const TESTDATA = {
+       path: "/path3/",
+       host: "test1.example.org",
+       isDomain: false,
+       isSecure: false,
+     }
+   ]
+ };
+ 
+-add_task(function* () {
+-  yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-cookies-same-name.html");
++add_task(async function () {
++  await openTabAndSetupStorage(MAIN_DOMAIN + "storage-cookies-same-name.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = StorageFront(client, form);
+-  let data = yield front.listStores();
++  let data = await front.listStores();
+ 
+   ok(data.cookies, "Cookies storage actor is present");
+ 
+-  yield testCookies(data.cookies);
+-  yield clearStorage();
++  await testCookies(data.cookies);
++  await clearStorage();
+ 
+   // Forcing GC/CC to get rid of docshells and windows created by this test.
+   forceCollections();
+-  yield client.close();
++  await client.close();
+   forceCollections();
+   DebuggerServer.destroy();
+   forceCollections();
+ });
+ 
+ function testCookies(cookiesActor) {
+   let numHosts = Object.keys(cookiesActor.hosts).length;
+   is(numHosts, 1, "Correct number of host entries for cookies");
+   return testCookiesObjects(0, cookiesActor.hosts, cookiesActor);
+ }
+ 
+-var testCookiesObjects = Task.async(function* (index, hosts, cookiesActor) {
++var testCookiesObjects = async function (index, hosts, cookiesActor) {
+   let host = Object.keys(hosts)[index];
+   let matchItems = data => {
+     is(data.total, TESTDATA[host].length,
+        "Number of cookies in host " + host + " matches");
+     for (let item of data.data) {
+       let found = false;
+       for (let toMatch of TESTDATA[host]) {
+         if (item.name === toMatch.name &&
+@@ -92,14 +92,14 @@ var testCookiesObjects = Task.async(func
+           break;
+         }
+       }
+       ok(found, "cookie " + item.name + " should exist in response");
+     }
+   };
+ 
+   ok(!!TESTDATA[host], "Host is present in the list : " + host);
+-  matchItems(yield cookiesActor.getStoreObjects(host));
++  matchItems(await cookiesActor.getStoreObjects(host));
+   if (index == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testCookiesObjects(++index, hosts, cookiesActor);
+-});
++  await testCookiesObjects(++index, hosts, cookiesActor);
++};
+diff --git a/devtools/server/tests/browser/browser_storage_dynamic_windows.js b/devtools/server/tests/browser/browser_storage_dynamic_windows.js
+--- a/devtools/server/tests/browser/browser_storage_dynamic_windows.js
++++ b/devtools/server/tests/browser/browser_storage_dynamic_windows.js
+@@ -25,24 +25,24 @@ const beforeReload = {
+       JSON.stringify(["idb1", "obj1"]),
+       JSON.stringify(["idb1", "obj2"]),
+       JSON.stringify(["idb2", "obj3"]),
+     ],
+     "http://sectest1.example.org": []
+   }
+ };
+ 
+-function* testStores(data, front) {
++async function testStores(data, front) {
+   testWindowsBeforeReload(data);
+ 
+   // FIXME: Bug 1183581 - browser_storage_dynamic_windows.js IsSafeToRunScript
+   //                      errors when testing reload in E10S mode
+   // yield testReload(front);
+-  yield testAddIframe(front);
+-  yield testRemoveIframe(front);
++  await testAddIframe(front);
++  await testRemoveIframe(front);
+ }
+ 
+ function testWindowsBeforeReload(data) {
+   for (let storageType in beforeReload) {
+     ok(data[storageType], storageType + " storage actor is present");
+     is(Object.keys(data[storageType].hosts).length,
+        Object.keys(beforeReload[storageType]).length,
+        "Number of hosts for " + storageType + "match");
+@@ -237,27 +237,27 @@ function testRemoveIframe(front) {
+           iframe.remove();
+           break;
+         }
+       }
+     });
+   });
+ }
+ 
+-add_task(function* () {
+-  yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-dynamic-windows.html");
++add_task(async function () {
++  await openTabAndSetupStorage(MAIN_DOMAIN + "storage-dynamic-windows.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = StorageFront(client, form);
+-  let data = yield front.listStores();
+-  yield testStores(data, front);
++  let data = await front.listStores();
++  await testStores(data, front);
+ 
+-  yield clearStorage();
++  await clearStorage();
+ 
+   // Forcing GC/CC to get rid of docshells and windows created by this test.
+   forceCollections();
+-  yield client.close();
++  await client.close();
+   forceCollections();
+   DebuggerServer.destroy();
+   forceCollections();
+ });
+diff --git a/devtools/server/tests/browser/browser_storage_listings.js b/devtools/server/tests/browser/browser_storage_listings.js
+--- a/devtools/server/tests/browser/browser_storage_listings.js
++++ b/devtools/server/tests/browser/browser_storage_listings.js
+@@ -326,34 +326,34 @@ const IDBValues = {
+             email: "foo@bar.com",
+           }
+         }
+       ]
+     }
+   }
+ };
+ 
+-function* testStores(data) {
++async function testStores(data) {
+   ok(data.cookies, "Cookies storage actor is present");
+   ok(data.localStorage, "Local Storage storage actor is present");
+   ok(data.sessionStorage, "Session Storage storage actor is present");
+   ok(data.indexedDB, "Indexed DB storage actor is present");
+-  yield testCookies(data.cookies);
+-  yield testLocalStorage(data.localStorage);
+-  yield testSessionStorage(data.sessionStorage);
+-  yield testIndexedDB(data.indexedDB);
++  await testCookies(data.cookies);
++  await testLocalStorage(data.localStorage);
++  await testSessionStorage(data.sessionStorage);
++  await testIndexedDB(data.indexedDB);
+ }
+ 
+ function testCookies(cookiesActor) {
+   is(Object.keys(cookiesActor.hosts).length, 3,
+                  "Correct number of host entries for cookies");
+   return testCookiesObjects(0, cookiesActor.hosts, cookiesActor);
+ }
+ 
+-var testCookiesObjects = Task.async(function* (index, hosts, cookiesActor) {
++var testCookiesObjects = async function (index, hosts, cookiesActor) {
+   let host = Object.keys(hosts)[index];
+   let matchItems = data => {
+     let cookiesLength = 0;
+     for (let secureCookie of storeMap.cookies[host]) {
+       if (secureCookie.isSecure) {
+         ++cookiesLength;
+       }
+     }
+@@ -375,30 +375,30 @@ var testCookiesObjects = Task.async(func
+           break;
+         }
+       }
+       ok(found, "cookie " + item.name + " should exist in response");
+     }
+   };
+ 
+   ok(!!storeMap.cookies[host], "Host is present in the list : " + host);
+-  matchItems(yield cookiesActor.getStoreObjects(host));
++  matchItems(await cookiesActor.getStoreObjects(host));
+   if (index == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testCookiesObjects(++index, hosts, cookiesActor);
+-});
++  await testCookiesObjects(++index, hosts, cookiesActor);
++};
+ 
+ function testLocalStorage(localStorageActor) {
+   is(Object.keys(localStorageActor.hosts).length, 3,
+      "Correct number of host entries for local storage");
+   return testLocalStorageObjects(0, localStorageActor.hosts, localStorageActor);
+ }
+ 
+-var testLocalStorageObjects = Task.async(function* (index, hosts, localStorageActor) {
++var testLocalStorageObjects = async function (index, hosts, localStorageActor) {
+   let host = Object.keys(hosts)[index];
+   let matchItems = data => {
+     is(data.total, storeMap.localStorage[host].length,
+        "Number of local storage items in host " + host + " matches");
+     for (let item of data.data) {
+       let found = false;
+       for (let toMatch of storeMap.localStorage[host]) {
+         if (item.name == toMatch.name) {
+@@ -408,31 +408,31 @@ var testLocalStorageObjects = Task.async
+           break;
+         }
+       }
+       ok(found, "local storage item " + item.name + " should exist in response");
+     }
+   };
+ 
+   ok(!!storeMap.localStorage[host], "Host is present in the list : " + host);
+-  matchItems(yield localStorageActor.getStoreObjects(host));
++  matchItems(await localStorageActor.getStoreObjects(host));
+   if (index == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testLocalStorageObjects(++index, hosts, localStorageActor);
+-});
++  await testLocalStorageObjects(++index, hosts, localStorageActor);
++};
+ 
+ function testSessionStorage(sessionStorageActor) {
+   is(Object.keys(sessionStorageActor.hosts).length, 3,
+      "Correct number of host entries for session storage");
+   return testSessionStorageObjects(0, sessionStorageActor.hosts,
+                                    sessionStorageActor);
+ }
+ 
+-var testSessionStorageObjects = Task.async(function* (index, hosts, sessionStorageActor) {
++var testSessionStorageObjects = async function (index, hosts, sessionStorageActor) {
+   let host = Object.keys(hosts)[index];
+   let matchItems = data => {
+     is(data.total, storeMap.sessionStorage[host].length,
+        "Number of session storage items in host " + host + " matches");
+     for (let item of data.data) {
+       let found = false;
+       for (let toMatch of storeMap.sessionStorage[host]) {
+         if (item.name == toMatch.name) {
+@@ -442,24 +442,24 @@ var testSessionStorageObjects = Task.asy
+           break;
+         }
+       }
+       ok(found, "session storage item " + item.name + " should exist in response");
+     }
+   };
+ 
+   ok(!!storeMap.sessionStorage[host], "Host is present in the list : " + host);
+-  matchItems(yield sessionStorageActor.getStoreObjects(host));
++  matchItems(await sessionStorageActor.getStoreObjects(host));
+   if (index == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testSessionStorageObjects(++index, hosts, sessionStorageActor);
+-});
++  await testSessionStorageObjects(++index, hosts, sessionStorageActor);
++};
+ 
+-var testIndexedDB = Task.async(function* (indexedDBActor) {
++var testIndexedDB = async function (indexedDBActor) {
+   is(Object.keys(indexedDBActor.hosts).length, 3,
+      "Correct number of host entries for indexed db");
+ 
+   for (let host in indexedDBActor.hosts) {
+     for (let item of indexedDBActor.hosts[host]) {
+       let parsedItem = JSON.parse(item);
+       let found = false;
+       for (let toMatch of IDBValues.listStoresResponse[host]) {
+@@ -467,22 +467,22 @@ var testIndexedDB = Task.async(function*
+           found = true;
+           break;
+         }
+       }
+       ok(found, item + " should exist in list stores response");
+     }
+   }
+ 
+-  yield testIndexedDBs(0, indexedDBActor.hosts, indexedDBActor);
+-  yield testObjectStores(0, indexedDBActor.hosts, indexedDBActor);
+-  yield testIDBEntries(0, indexedDBActor.hosts, indexedDBActor);
+-});
++  await testIndexedDBs(0, indexedDBActor.hosts, indexedDBActor);
++  await testObjectStores(0, indexedDBActor.hosts, indexedDBActor);
++  await testIDBEntries(0, indexedDBActor.hosts, indexedDBActor);
++};
+ 
+-var testIndexedDBs = Task.async(function* (index, hosts, indexedDBActor) {
++var testIndexedDBs = async function (index, hosts, indexedDBActor) {
+   let host = Object.keys(hosts)[index];
+   let matchItems = data => {
+     is(data.total, IDBValues.dbDetails[host].length,
+        "Number of indexed db in host " + host + " matches");
+     for (let item of data.data) {
+       let found = false;
+       for (let toMatch of IDBValues.dbDetails[host]) {
+         if (item.uniqueKey == toMatch.db) {
+@@ -495,24 +495,24 @@ var testIndexedDBs = Task.async(function
+           break;
+         }
+       }
+       ok(found, "indexed db " + item.uniqueKey + " should exist in response");
+     }
+   };
+ 
+   ok(!!IDBValues.dbDetails[host], "Host is present in the list : " + host);
+-  matchItems(yield indexedDBActor.getStoreObjects(host));
++  matchItems(await indexedDBActor.getStoreObjects(host));
+   if (index == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testIndexedDBs(++index, hosts, indexedDBActor);
+-});
++  await testIndexedDBs(++index, hosts, indexedDBActor);
++};
+ 
+-var testObjectStores = Task.async(function* (ix, hosts, indexedDBActor) {
++var testObjectStores = async function (ix, hosts, indexedDBActor) {
+   let host = Object.keys(hosts)[ix];
+   let matchItems = (data, db) => {
+     is(data.total, IDBValues.objectStoreDetails[host][db].length,
+        "Number of object stores in host " + host + " matches");
+     for (let item of data.data) {
+       let found = false;
+       for (let toMatch of IDBValues.objectStoreDetails[host][db]) {
+         if (item.objectStore == toMatch.objectStore) {
+@@ -544,26 +544,26 @@ var testObjectStores = Task.async(functi
+       ok(found, "indexed db " + item.name + " should exist in response");
+     }
+   };
+ 
+   ok(!!IDBValues.objectStoreDetails[host], "Host is present in the list : " + host);
+   for (let name of hosts[host]) {
+     let objName = JSON.parse(name).slice(0, 1);
+     matchItems((
+-      yield indexedDBActor.getStoreObjects(host, [JSON.stringify(objName)])
++      await indexedDBActor.getStoreObjects(host, [JSON.stringify(objName)])
+     ), objName[0]);
+   }
+   if (ix == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testObjectStores(++ix, hosts, indexedDBActor);
+-});
++  await testObjectStores(++ix, hosts, indexedDBActor);
++};
+ 
+-var testIDBEntries = Task.async(function* (index, hosts, indexedDBActor) {
++var testIDBEntries = async function (index, hosts, indexedDBActor) {
+   let host = Object.keys(hosts)[index];
+   let matchItems = (data, obj) => {
+     is(data.total, IDBValues.entries[host][obj].length,
+        "Number of items in object store " + obj + " matches");
+     for (let item of data.data) {
+       let found = false;
+       for (let toMatch of IDBValues.entries[host][obj]) {
+         if (item.name == toMatch.name) {
+@@ -582,36 +582,36 @@ var testIDBEntries = Task.async(function
+       ok(found, "indexed db item " + item.name + " should exist in response");
+     }
+   };
+ 
+   ok(!!IDBValues.entries[host], "Host is present in the list : " + host);
+   for (let name of hosts[host]) {
+     let parsed = JSON.parse(name);
+     matchItems((
+-      yield indexedDBActor.getStoreObjects(host, [name])
++      await indexedDBActor.getStoreObjects(host, [name])
+     ), parsed[0] + "#" + parsed[1]);
+   }
+   if (index == Object.keys(hosts).length - 1) {
+     return;
+   }
+-  yield testObjectStores(++index, hosts, indexedDBActor);
+-});
++  await testObjectStores(++index, hosts, indexedDBActor);
++};
+ 
+-add_task(function* () {
+-  yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html");
++add_task(async function () {
++  await openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = StorageFront(client, form);
+-  let data = yield front.listStores();
+-  yield testStores(data);
++  let data = await front.listStores();
++  await testStores(data);
+ 
+-  yield clearStorage();
++  await clearStorage();
+ 
+   // Forcing GC/CC to get rid of docshells and windows created by this test.
+   forceCollections();
+-  yield client.close();
++  await client.close();
+   forceCollections();
+   DebuggerServer.destroy();
+   forceCollections();
+ });
+diff --git a/devtools/server/tests/browser/browser_storage_updates.js b/devtools/server/tests/browser/browser_storage_updates.js
+--- a/devtools/server/tests/browser/browser_storage_updates.js
++++ b/devtools/server/tests/browser/browser_storage_updates.js
+@@ -247,17 +247,17 @@ function runTest({action, expected}, fro
+       resolve();
+     });
+ 
+     info("Running test at index " + index);
+     action(win);
+   });
+ }
+ 
+-function* testClearLocalAndSessionStores(front, win) {
++function testClearLocalAndSessionStores(front, win) {
+   return new Promise(resolve => {
+     // We need to wait until we have received stores-cleared for both local and
+     // session storage.
+     let localStorage = false;
+     let sessionStorage = false;
+ 
+     front.on("stores-cleared", function onStoresCleared(data) {
+       storesCleared(data);
+@@ -285,36 +285,36 @@ function storesCleared(data) {
+     is(hosts.length, 1, "number of hosts is 1");
+     is(hosts[0], "http://test1.example.org",
+        "host matches for " + Object.keys(data)[0]);
+   } else {
+     ok(false, "Stores cleared should only be for local and session storage");
+   }
+ }
+ 
+-function* finishTests(client) {
+-  yield client.close();
++async function finishTests(client) {
++  await client.close();
+   DebuggerServer.destroy();
+   finish();
+ }
+ 
+-add_task(function* () {
+-  let browser = yield addTab(MAIN_DOMAIN + "storage-updates.html");
++add_task(async function () {
++  let browser = await addTab(MAIN_DOMAIN + "storage-updates.html");
+   // eslint-disable-next-line mozilla/no-cpows-in-tests
+   let doc = browser.contentDocument;
+ 
+   initDebuggerServer();
+ 
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = StorageFront(client, form);
+   let win = doc.defaultView.wrappedJSObject;
+ 
+-  yield front.listStores();
++  await front.listStores();
+ 
+   for (let i = 0; i < TESTS.length; i++) {
+     let test = TESTS[i];
+-    yield runTest(test, front, win, i);
++    await runTest(test, front, win, i);
+   }
+ 
+-  yield testClearLocalAndSessionStores(front, win);
+-  yield finishTests(client);
++  await testClearLocalAndSessionStores(front, win);
++  await finishTests(client);
+ });
+diff --git a/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js b/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js
+--- a/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js
++++ b/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js
+@@ -6,35 +6,35 @@
+ 
+ // Test that StyleSheetActor.getText handles empty text correctly.
+ 
+ const {StyleSheetsFront} = require("devtools/shared/fronts/stylesheets");
+ 
+ const CONTENT = "<style>body { background-color: #f06; }</style>";
+ const TEST_URI = "data:text/html;charset=utf-8," + encodeURIComponent(CONTENT);
+ 
+-add_task(function* () {
+-  yield addTab(TEST_URI);
++add_task(async function () {
++  await addTab(TEST_URI);
+ 
+   info("Initialising the debugger server and client.");
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+ 
+   info("Attaching to the active tab.");
+-  yield client.attachTab(form.actor);
++  await client.attachTab(form.actor);
+ 
+   let front = StyleSheetsFront(client, form);
+   ok(front, "The StyleSheetsFront was created.");
+ 
+-  let sheets = yield front.getStyleSheets();
++  let sheets = await front.getStyleSheets();
+   ok(sheets, "getStyleSheets() succeeded");
+   is(sheets.length, 1,
+      "getStyleSheets() returned the correct number of sheets");
+ 
+   let sheet = sheets[0];
+-  yield sheet.update("", false);
+-  let longStr = yield sheet.getText();
+-  let source = yield longStr.string();
++  await sheet.update("", false);
++  let longStr = await sheet.getText();
++  let source = await longStr.string();
+   is(source, "", "text is empty");
+ 
+-  yield client.close();
++  await client.close();
+ });
+diff --git a/devtools/server/tests/browser/browser_stylesheets_nested-iframes.js b/devtools/server/tests/browser/browser_stylesheets_nested-iframes.js
+--- a/devtools/server/tests/browser/browser_stylesheets_nested-iframes.js
++++ b/devtools/server/tests/browser/browser_stylesheets_nested-iframes.js
+@@ -4,34 +4,34 @@
+ 
+ "use strict";
+ 
+ // Test that StyleSheetsActor.getStyleSheets() works if an iframe does not have
+ // a content document.
+ 
+ const {StyleSheetsFront} = require("devtools/shared/fronts/stylesheets");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "stylesheets-nested-iframes.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "stylesheets-nested-iframes.html");
+ 
+   info("Initialising the debugger server and client.");
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+ 
+   info("Attaching to the active tab.");
+-  yield client.attachTab(form.actor);
++  await client.attachTab(form.actor);
+ 
+   let front = StyleSheetsFront(client, form);
+   ok(front, "The StyleSheetsFront was created.");
+ 
+-  let sheets = yield front.getStyleSheets();
++  let sheets = await front.getStyleSheets();
+   ok(sheets, "getStyleSheets() succeeded even with documentless iframes.");
+ 
+   // Bug 285395 limits the number of nested iframes to 10. There's one sheet per
+   // frame so we should get 10 sheets. However, the limit might change in the
+   // future so it's better not to rely on the limit. Asserting > 2 ensures that
+   // the test page is actually loading nested iframes and this test is doing
+   // something sensible (if we got this far, the test has served its purpose).
+   ok(sheets.length > 2, sheets.length + " sheets found (expected 3 or more).");
+ 
+-  yield client.close();
++  await client.close();
+ });
+diff --git a/devtools/server/tests/browser/browser_timeline.js b/devtools/server/tests/browser/browser_timeline.js
+--- a/devtools/server/tests/browser/browser_timeline.js
++++ b/devtools/server/tests/browser/browser_timeline.js
+@@ -7,66 +7,66 @@
+ // Test that the timeline front's start/stop/isRecording methods work in a
+ // simple use case, and that markers events are sent when operations occur.
+ // Note that this test isn't concerned with which markers are actually recorded,
+ // just that markers are recorded at all.
+ // Trying to check marker types here may lead to intermittents, see bug 1066474.
+ 
+ const {TimelineFront} = require("devtools/shared/fronts/timeline");
+ 
+-add_task(function* () {
+-  yield addTab("data:text/html;charset=utf-8,mop");
++add_task(async function () {
++  await addTab("data:text/html;charset=utf-8,mop");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = TimelineFront(client, form);
+ 
+   ok(front, "The TimelineFront was created");
+ 
+-  let isActive = yield front.isRecording();
++  let isActive = await front.isRecording();
+   ok(!isActive, "The TimelineFront is not initially recording");
+ 
+   info("Flush any pending reflows");
+   ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+     // forceSyncReflow
+     content.document.body.innerHeight;
+   });
+ 
+   info("Start recording");
+-  yield front.start({ withMarkers: true });
++  await front.start({ withMarkers: true });
+ 
+-  isActive = yield front.isRecording();
++  isActive = await front.isRecording();
+   ok(isActive, "The TimelineFront is now recording");
+ 
+   info("Change some style on the page to cause style/reflow/paint");
+   let onMarkers = once(front, "markers");
+   ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+     content.document.body.style.padding = "10px";
+   });
+-  let markers = yield onMarkers;
++  let markers = await onMarkers;
+ 
+   ok(true, "The markers event was fired");
+   ok(markers.length > 0, "Markers were returned");
+ 
+   info("Flush pending reflows again");
+   ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+     // forceSyncReflow
+     content.document.body.innerHeight;
+   });
+ 
+   info("Change some style on the page to cause style/paint");
+   onMarkers = once(front, "markers");
+   ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+     content.document.body.style.backgroundColor = "red";
+   });
+-  markers = yield onMarkers;
++  markers = await onMarkers;
+ 
+   ok(markers.length > 0, "markers were returned");
+ 
+-  yield front.stop();
++  await front.stop();
+ 
+-  isActive = yield front.isRecording();
++  isActive = await front.isRecording();
+   ok(!isActive, "Not recording after stop()");
+ 
+-  yield client.close();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+diff --git a/devtools/server/tests/browser/browser_timeline_actors.js b/devtools/server/tests/browser/browser_timeline_actors.js
+--- a/devtools/server/tests/browser/browser_timeline_actors.js
++++ b/devtools/server/tests/browser/browser_timeline_actors.js
+@@ -5,26 +5,26 @@
+ 
+ "use strict";
+ 
+ // Test that the timeline can also record data from the memory and framerate
+ // actors, emitted as events in tadem with the markers.
+ 
+ const {TimelineFront} = require("devtools/shared/fronts/timeline");
+ 
+-add_task(function* () {
+-  yield addTab("data:text/html;charset=utf-8,mop");
++add_task(async function () {
++  await addTab("data:text/html;charset=utf-8,mop");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = TimelineFront(client, form);
+ 
+   info("Start timeline marker recording");
+-  yield front.start({ withMemory: true, withTicks: true });
++  await front.start({ withMemory: true, withTicks: true });
+ 
+   let updatedMemory = 0;
+   let updatedTicks = 0;
+ 
+   front.on("memory", (delta, measurement) => {
+     ok(delta > 0, "The delta should be a timestamp.");
+     ok(measurement, "The measurement should not be null.");
+     ok(measurement.total > 0, "There should be a 'total' value in the measurement.");
+@@ -34,24 +34,24 @@ add_task(function* () {
+ 
+   front.on("ticks", (delta, ticks) => {
+     ok(delta > 0, "The delta should be a timestamp.");
+     ok(ticks, "The ticks should not be null.");
+     info("Received 'ticks' event with " + ticks.toSource());
+     updatedTicks++;
+   });
+ 
+-  ok((yield waitUntil(() => updatedMemory > 1)),
++  ok((await waitUntil(() => updatedMemory > 1)),
+     "Some memory measurements were emitted.");
+-  ok((yield waitUntil(() => updatedTicks > 1)),
++  ok((await waitUntil(() => updatedTicks > 1)),
+     "Some refresh driver ticks were emitted.");
+ 
+   info("Stop timeline marker recording");
+-  yield front.stop();
+-  yield client.close();
++  await front.stop();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+ /**
+  * Waits until a predicate returns true.
+  *
+  * @param function predicate
+  *        Invoked once in a while until it returns true.
+diff --git a/devtools/server/tests/browser/browser_timeline_iframes.js b/devtools/server/tests/browser/browser_timeline_iframes.js
+--- a/devtools/server/tests/browser/browser_timeline_iframes.js
++++ b/devtools/server/tests/browser/browser_timeline_iframes.js
+@@ -5,38 +5,38 @@
+ 
+ "use strict";
+ 
+ // Test the timeline front receives markers events for operations that occur in
+ // iframes.
+ 
+ const {TimelineFront} = require("devtools/shared/fronts/timeline");
+ 
+-add_task(function* () {
+-  yield addTab(MAIN_DOMAIN + "timeline-iframe-parent.html");
++add_task(async function () {
++  await addTab(MAIN_DOMAIN + "timeline-iframe-parent.html");
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let front = TimelineFront(client, form);
+ 
+   info("Start timeline marker recording");
+-  yield front.start({ withMarkers: true });
++  await front.start({ withMarkers: true });
+ 
+   // Check that we get markers for a few iterations of the timer that runs in
+   // the child frame.
+   for (let i = 0; i < 3; i++) {
+     // That's the time the child frame waits before changing styles.
+-    yield wait(300);
+-    let markers = yield once(front, "markers");
++    await wait(300);
++    let markers = await once(front, "markers");
+     ok(markers.length, "Markers were received for operations in the child frame");
+   }
+ 
+   info("Stop timeline marker recording");
+-  yield front.stop();
+-  yield client.close();
++  await front.stop();
++  await client.close();
+   gBrowser.removeCurrentTab();
+ });
+ 
+ function wait(ms) {
+   return new Promise(resolve =>
+     setTimeout(resolve, ms));
+ }
+diff --git a/devtools/server/tests/browser/browser_webextension_inspected_window.js b/devtools/server/tests/browser/browser_webextension_inspected_window.js
+--- a/devtools/server/tests/browser/browser_webextension_inspected_window.js
++++ b/devtools/server/tests/browser/browser_webextension_inspected_window.js
+@@ -11,38 +11,38 @@ const {
+ const TEST_RELOAD_URL = `${MAIN_DOMAIN}/inspectedwindow-reload-target.sjs`;
+ 
+ const FAKE_CALLER_INFO = {
+   url: "moz-extension://fake-webextension-uuid/fake-caller-script.js",
+   lineNumber: 1,
+   addonId: "fake-webextension-uuid",
+ };
+ 
+-function* setup(pageUrl) {
+-  yield addTab(pageUrl);
++async function setup(pageUrl) {
++  await addTab(pageUrl);
+   initDebuggerServer();
+ 
+   const client = new DebuggerClient(DebuggerServer.connectPipe());
+-  const form = yield connectDebuggerClient(client);
++  const form = await connectDebuggerClient(client);
+ 
+-  const [, tabClient] = yield client.attachTab(form.actor);
++  const [, tabClient] = await client.attachTab(form.actor);
+ 
+-  const [, consoleClient] = yield client.attachConsole(form.consoleActor, []);
++  const [, consoleClient] = await client.attachConsole(form.consoleActor, []);
+ 
+   const inspectedWindowFront = new WebExtensionInspectedWindowFront(client, form);
+ 
+   return {
+     client, form,
+     tabClient, consoleClient,
+     inspectedWindowFront,
+   };
+ }
+ 
+-function* teardown({client}) {
+-  yield client.close();
++async function teardown({client}) {
++  await client.close();
+   DebuggerServer.destroy();
+   gBrowser.removeCurrentTab();
+ }
+ 
+ function waitForNextTabNavigated(client) {
+   return new Promise(resolve => {
+     client.addListener("tabNavigated", function tabNavigatedListener(evt, pkt) {
+       if (pkt.state == "stop" && !pkt.isFrameSwitching) {
+@@ -81,71 +81,71 @@ function collectEvalResults() {
+       results.push(iframeDoc.querySelector("pre").textContent);
+     }
+     const iframe = iframeDoc.querySelector("iframe");
+     iframeDoc = iframe ? iframe.contentDocument : null;
+   }
+   return JSON.stringify(results);
+ }
+ 
+-add_task(function* test_successfull_inspectedWindowEval_result() {
+-  const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
+-  const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window.location", {});
++add_task(async function test_successfull_inspectedWindowEval_result() {
++  const {client, inspectedWindowFront} = await setup(MAIN_DOMAIN);
++  const result = await inspectedWindowFront.eval(FAKE_CALLER_INFO, "window.location", {});
+ 
+   ok(result.value, "Got a result from inspectedWindow eval");
+   is(result.value.href, MAIN_DOMAIN,
+      "Got the expected window.location.href property value");
+   is(result.value.protocol, "http:",
+      "Got the expected window.location.protocol property value");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_error_inspectedWindowEval_result() {
+-  const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
+-  const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
++add_task(async function test_error_inspectedWindowEval_result() {
++  const {client, inspectedWindowFront} = await setup(MAIN_DOMAIN);
++  const result = await inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
+ 
+   ok(!result.value, "Got a null result from inspectedWindow eval");
+   ok(result.exceptionInfo.isError, "Got an API Error result from inspectedWindow eval");
+   ok(!result.exceptionInfo.isException, "An error isException is false as expected");
+   is(result.exceptionInfo.code, "E_PROTOCOLERROR",
+      "Got the expected 'code' property in the error result");
+   is(result.exceptionInfo.description, "Inspector protocol error: %s",
+      "Got the expected 'description' property in the error result");
+   is(result.exceptionInfo.details.length, 1,
+      "The 'details' array property should contains 1 element");
+   ok(result.exceptionInfo.details[0].includes("cyclic object value"),
+      "Got the expected content in the error results's details");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_system_principal_denied_error_inspectedWindowEval_result() {
+-  const {client, inspectedWindowFront} = yield setup("about:addons");
+-  const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
++add_task(async function test_system_principal_denied_error_inspectedWindowEval_result() {
++  const {client, inspectedWindowFront} = await setup("about:addons");
++  const result = await inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
+ 
+   ok(!result.value, "Got a null result from inspectedWindow eval");
+   ok(result.exceptionInfo.isError,
+      "Got an API Error result from inspectedWindow eval on a system principal page");
+   is(result.exceptionInfo.code, "E_PROTOCOLERROR",
+      "Got the expected 'code' property in the error result");
+   is(result.exceptionInfo.description, "Inspector protocol error: %s",
+      "Got the expected 'description' property in the error result");
+   is(result.exceptionInfo.details.length, 1,
+      "The 'details' array property should contains 1 element");
+   is(result.exceptionInfo.details[0],
+      "This target has a system principal. inspectedWindow.eval denied.",
+      "Got the expected content in the error results's details");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_exception_inspectedWindowEval_result() {
+-  const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
+-  const result = yield inspectedWindowFront.eval(
++add_task(async function test_exception_inspectedWindowEval_result() {
++  const {client, inspectedWindowFront} = await setup(MAIN_DOMAIN);
++  const result = await inspectedWindowFront.eval(
+     FAKE_CALLER_INFO, "throw Error('fake eval error');", {});
+ 
+   ok(result.exceptionInfo.isException, "Got an exception as expected");
+   ok(!result.value, "Got an undefined eval value");
+   ok(!result.exceptionInfo.isError, "An exception should not be isError=true");
+   ok(result.exceptionInfo.value.includes("Error: fake eval error"),
+      "Got the expected exception message");
+ 
+@@ -153,211 +153,211 @@ add_task(function* test_exception_inspec
+     `called from ${FAKE_CALLER_INFO.url}:${FAKE_CALLER_INFO.lineNumber}`;
+   ok(result.exceptionInfo.value.includes(expectedCallerInfo),
+      "Got the expected caller info in the exception message");
+ 
+   const expectedStack = `eval code:1:7`;
+   ok(result.exceptionInfo.value.includes(expectedStack),
+      "Got the expected stack trace in the exception message");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_exception_inspectedWindowReload() {
++add_task(async function test_exception_inspectedWindowReload() {
+   const {
+     client, consoleClient, inspectedWindowFront,
+-  } = yield setup(`${TEST_RELOAD_URL}?test=cache`);
++  } = await setup(`${TEST_RELOAD_URL}?test=cache`);
+ 
+   // Test reload with bypassCache=false.
+ 
+   const waitForNoBypassCacheReload = waitForNextTabNavigated(client);
+-  const reloadResult = yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
++  const reloadResult = await inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                                          {ignoreCache: false});
+ 
+   ok(!reloadResult, "Got the expected undefined result from inspectedWindow reload");
+ 
+-  yield waitForNoBypassCacheReload;
++  await waitForNoBypassCacheReload;
+ 
+-  const noBypassCacheEval = yield consoleEvalJS(consoleClient,
++  const noBypassCacheEval = await consoleEvalJS(consoleClient,
+                                                 "document.body.textContent");
+ 
+   is(noBypassCacheEval.result, "empty cache headers",
+      "Got the expected result with reload forceBypassCache=false");
+ 
+   // Test reload with bypassCache=true.
+ 
+   const waitForForceBypassCacheReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {ignoreCache: true});
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO, {ignoreCache: true});
+ 
+-  yield waitForForceBypassCacheReload;
++  await waitForForceBypassCacheReload;
+ 
+-  const forceBypassCacheEval = yield consoleEvalJS(consoleClient,
++  const forceBypassCacheEval = await consoleEvalJS(consoleClient,
+                                                    "document.body.textContent");
+ 
+   is(forceBypassCacheEval.result, "no-cache:no-cache",
+      "Got the expected result with reload forceBypassCache=true");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_exception_inspectedWindowReload_customUserAgent() {
++add_task(async function test_exception_inspectedWindowReload_customUserAgent() {
+   const {
+     client, consoleClient, inspectedWindowFront,
+-  } = yield setup(`${TEST_RELOAD_URL}?test=user-agent`);
++  } = await setup(`${TEST_RELOAD_URL}?test=user-agent`);
+ 
+   // Test reload with custom userAgent.
+ 
+   const waitForCustomUserAgentReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                     {userAgent: "Customized User Agent"});
+ 
+-  yield waitForCustomUserAgentReload;
++  await waitForCustomUserAgentReload;
+ 
+-  const customUserAgentEval = yield consoleEvalJS(consoleClient,
++  const customUserAgentEval = await consoleEvalJS(consoleClient,
+                                                   "document.body.textContent");
+ 
+   is(customUserAgentEval.result, "Customized User Agent",
+      "Got the expected result on reload with a customized userAgent");
+ 
+   // Test reload with no custom userAgent.
+ 
+   const waitForNoCustomUserAgentReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+ 
+-  yield waitForNoCustomUserAgentReload;
++  await waitForNoCustomUserAgentReload;
+ 
+-  const noCustomUserAgentEval = yield consoleEvalJS(consoleClient,
++  const noCustomUserAgentEval = await consoleEvalJS(consoleClient,
+                                                     "document.body.textContent");
+ 
+   is(noCustomUserAgentEval.result, window.navigator.userAgent,
+      "Got the expected result with reload without a customized userAgent");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_exception_inspectedWindowReload_injectedScript() {
++add_task(async function test_exception_inspectedWindowReload_injectedScript() {
+   const {
+     client, consoleClient, inspectedWindowFront,
+-  } = yield setup(`${TEST_RELOAD_URL}?test=injected-script&frames=3`);
++  } = await setup(`${TEST_RELOAD_URL}?test=injected-script&frames=3`);
+ 
+   // Test reload with an injectedScript.
+ 
+   const waitForInjectedScriptReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                     {injectedScript: `new ${injectedScript}`});
+-  yield waitForInjectedScriptReload;
++  await waitForInjectedScriptReload;
+ 
+-  const injectedScriptEval = yield consoleEvalJS(consoleClient,
++  const injectedScriptEval = await consoleEvalJS(consoleClient,
+                                                  `(${collectEvalResults})()`);
+ 
+   const expectedResult = (new Array(4)).fill("injected script executed first");
+ 
+   SimpleTest.isDeeply(JSON.parse(injectedScriptEval.result), expectedResult,
+      "Got the expected result on reload with an injected script");
+ 
+   // Test reload without an injectedScript.
+ 
+   const waitForNoInjectedScriptReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+-  yield waitForNoInjectedScriptReload;
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
++  await waitForNoInjectedScriptReload;
+ 
+-  const noInjectedScriptEval = yield consoleEvalJS(consoleClient,
++  const noInjectedScriptEval = await consoleEvalJS(consoleClient,
+                                                    `(${collectEvalResults})()`);
+ 
+   const newExpectedResult = (new Array(4)).fill("injected script NOT executed");
+ 
+   SimpleTest.isDeeply(JSON.parse(noInjectedScriptEval.result), newExpectedResult,
+                       "Got the expected result on reload with no injected script");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_exception_inspectedWindowReload_multiple_calls() {
++add_task(async function test_exception_inspectedWindowReload_multiple_calls() {
+   const {
+     client, consoleClient, inspectedWindowFront,
+-  } = yield setup(`${TEST_RELOAD_URL}?test=user-agent`);
++  } = await setup(`${TEST_RELOAD_URL}?test=user-agent`);
+ 
+   // Test reload with custom userAgent three times (and then
+   // check that only the first one has affected the page reload.
+ 
+   const waitForCustomUserAgentReload = waitForNextTabNavigated(client);
+ 
+   inspectedWindowFront.reload(FAKE_CALLER_INFO, {userAgent: "Customized User Agent 1"});
+   inspectedWindowFront.reload(FAKE_CALLER_INFO, {userAgent: "Customized User Agent 2"});
+ 
+-  yield waitForCustomUserAgentReload;
++  await waitForCustomUserAgentReload;
+ 
+-  const customUserAgentEval = yield consoleEvalJS(consoleClient,
++  const customUserAgentEval = await consoleEvalJS(consoleClient,
+                                                   "document.body.textContent");
+ 
+   is(customUserAgentEval.result, "Customized User Agent 1",
+      "Got the expected result on reload with a customized userAgent");
+ 
+   // Test reload with no custom userAgent.
+ 
+   const waitForNoCustomUserAgentReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+ 
+-  yield waitForNoCustomUserAgentReload;
++  await waitForNoCustomUserAgentReload;
+ 
+-  const noCustomUserAgentEval = yield consoleEvalJS(consoleClient,
++  const noCustomUserAgentEval = await consoleEvalJS(consoleClient,
+                                                     "document.body.textContent");
+ 
+   is(noCustomUserAgentEval.result, window.navigator.userAgent,
+      "Got the expected result with reload without a customized userAgent");
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+-add_task(function* test_exception_inspectedWindowReload_stopped() {
++add_task(async function test_exception_inspectedWindowReload_stopped() {
+   const {
+     client, consoleClient, inspectedWindowFront,
+-  } = yield setup(`${TEST_RELOAD_URL}?test=injected-script&frames=3`);
++  } = await setup(`${TEST_RELOAD_URL}?test=injected-script&frames=3`);
+ 
+   // Test reload on a page that calls window.stop() immediately during the page loading
+ 
+   const waitForPageLoad = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.eval(FAKE_CALLER_INFO,
++  await inspectedWindowFront.eval(FAKE_CALLER_INFO,
+                                   "window.location += '&stop=windowStop'");
+ 
+   info("Load a webpage that calls 'window.stop()' while is still loading");
+-  yield waitForPageLoad;
++  await waitForPageLoad;
+ 
+   info("Starting a reload with an injectedScript");
+   const waitForInjectedScriptReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                     {injectedScript: `new ${injectedScript}`});
+-  yield waitForInjectedScriptReload;
++  await waitForInjectedScriptReload;
+ 
+-  const injectedScriptEval = yield consoleEvalJS(consoleClient,
++  const injectedScriptEval = await consoleEvalJS(consoleClient,
+                                                  `(${collectEvalResults})()`);
+ 
+   // The page should have stopped during the reload and only one injected script
+   // is expected.
+   const expectedResult = (new Array(1)).fill("injected script executed first");
+ 
+   SimpleTest.isDeeply(JSON.parse(injectedScriptEval.result), expectedResult,
+      "The injected script has been executed on the 'stopped' page reload");
+ 
+   // Reload again with no options.
+ 
+   info("Reload the tab again without any reload options");
+   const waitForNoInjectedScriptReload = waitForNextTabNavigated(client);
+-  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+-  yield waitForNoInjectedScriptReload;
++  await inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
++  await waitForNoInjectedScriptReload;
+ 
+-  const noInjectedScriptEval = yield consoleEvalJS(consoleClient,
++  const noInjectedScriptEval = await consoleEvalJS(consoleClient,
+                                                    `(${collectEvalResults})()`);
+ 
+   // The page should have stopped during the reload and no injected script should
+   // have been executed during this second reload (or it would mean that the previous
+   // customized reload was still pending and has wrongly affected the second reload)
+   const newExpectedResult = (new Array(1)).fill("injected script NOT executed");
+ 
+   SimpleTest.isDeeply(
+     JSON.parse(noInjectedScriptEval.result), newExpectedResult,
+     "No injectedScript should have been evaluated during the second reload"
+   );
+ 
+-  yield teardown({client});
++  await teardown({client});
+ });
+ 
+ // TODO: check eval with $0 binding once implemented (Bug 1300590)
+diff --git a/devtools/server/tests/browser/head.js b/devtools/server/tests/browser/head.js
+--- a/devtools/server/tests/browser/head.js
++++ b/devtools/server/tests/browser/head.js
+@@ -30,68 +30,68 @@ waitForExplicitFinish();
+ /**
+  * Add a new test tab in the browser and load the given url.
+  * @param {String} url The url to be loaded in the new tab
+  * @return a promise that resolves to the new browser that the document
+  *         is loaded in. Note that we cannot return the document
+  *         directly, since this would be a CPOW in the e10s case,
+  *         and Promises cannot be resolved with CPOWs (see bug 1233497).
+  */
+-var addTab = Task.async(function* (url) {
++var addTab = async function (url) {
+   info(`Adding a new tab with URL: ${url}`);
+   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, url);
+-  yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
++  await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ 
+   info(`Tab added and URL ${url} loaded`);
+ 
+   return tab.linkedBrowser;
+-});
++};
+ 
+-function* initAnimationsFrontForUrl(url) {
++async function initAnimationsFrontForUrl(url) {
+   const {AnimationsFront} = require("devtools/shared/fronts/animation");
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+-  yield addTab(url);
++  await addTab(url);
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let inspector = InspectorFront(client, form);
+-  let walker = yield inspector.getWalker();
++  let walker = await inspector.getWalker();
+   let animations = AnimationsFront(client, form);
+ 
+   return {inspector, walker, animations, client};
+ }
+ 
+-function* initLayoutFrontForUrl(url) {
++async function initLayoutFrontForUrl(url) {
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+-  yield addTab(url);
++  await addTab(url);
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let inspector = InspectorFront(client, form);
+-  let walker = yield inspector.getWalker();
+-  let layout = yield walker.getLayoutInspector();
++  let walker = await inspector.getWalker();
++  let layout = await walker.getLayoutInspector();
+ 
+   return {inspector, walker, layout, client};
+ }
+ 
+-function* initAccessibilityFrontForUrl(url) {
++async function initAccessibilityFrontForUrl(url) {
+   const {AccessibilityFront} = require("devtools/shared/fronts/accessibility");
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+-  yield addTab(url);
++  await addTab(url);
+ 
+   initDebuggerServer();
+   let client = new DebuggerClient(DebuggerServer.connectPipe());
+-  let form = yield connectDebuggerClient(client);
++  let form = await connectDebuggerClient(client);
+   let inspector = InspectorFront(client, form);
+-  let walker = yield inspector.getWalker();
++  let walker = await inspector.getWalker();
+   let accessibility = AccessibilityFront(client, form);
+ 
+   return {inspector, walker, accessibility, client};
+ }
+ 
+ function initDebuggerServer() {
+   try {
+     // Sometimes debugger server does not get destroyed correctly by previous
+diff --git a/devtools/server/tests/browser/storage-dynamic-windows.html b/devtools/server/tests/browser/storage-dynamic-windows.html
+--- a/devtools/server/tests/browser/storage-dynamic-windows.html
++++ b/devtools/server/tests/browser/storage-dynamic-windows.html
+@@ -1,9 +1,9 @@
+-<!DOCTYPE HTML>
++<!DOCTYPE HTML>
+ <html>
+ <!--
+ Bug 965872 - Storage inspector actor with cookies, local storage and session storage.
+ -->
+ <head>
+   <meta charset="utf-8">
+   <title>Storage inspector test for listing hosts and storages</title>
+ </head>
+@@ -21,97 +21,97 @@ document.cookie = "cs2=sessionCookie; pa
+ document.cookie = "c3=foobar-2; expires=" +
+   new Date(cookieExpiresTime2).toGMTString() + "; path=/";
+ // ... and some local storage items ..
+ localStorage.setItem("ls1", "foobar");
+ localStorage.setItem("ls2", "foobar-2");
+ // ... and finally some session storage items too
+ sessionStorage.setItem("ss1", "foobar-3");
+ 
+-let idbGenerator = function*() {
++let idbGenerator = async function () {
+   let request = indexedDB.open("idb1", 1);
+   request.onerror = function() {
+     throw new Error("error opening db connection");
+   };
+-  let db = yield new Promise(done => {
++  let db = await new Promise(done => {
+     request.onupgradeneeded = event => {
+       let db = event.target.result;
+       let store1 = db.createObjectStore("obj1", { keyPath: "id" });
+       store1.createIndex("name", "name", { unique: false });
+       store1.createIndex("email", "email", { unique: true });
+       let store2 = db.createObjectStore("obj2", { keyPath: "id2" });
+       store1.transaction.oncomplete = () => {
+         done(db);
+       };
+     };
+   });
+ 
+   // Prevents AbortError
+-  yield new Promise(done => {
++  await new Promise(done => {
+     request.onsuccess = done;
+   });
+ 
+   let transaction = db.transaction(["obj1", "obj2"], "readwrite");
+   let store1 = transaction.objectStore("obj1");
+   let store2 = transaction.objectStore("obj2");
+   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
+   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
+   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
+   store2.add({
+     id2: 1,
+     name: "foo",
+     email: "foo@bar.com",
+     extra: "baz"
+   });
+   // Prevents AbortError during close()
+-  yield new Promise(success => {
++  await new Promise(success => {
+     transaction.oncomplete = success;
+   });
+ 
+   db.close();
+ 
+   request = indexedDB.open("idb2", 1);
+-  let db2 = yield new Promise(done => {
++  let db2 = await new Promise(done => {
+     request.onupgradeneeded = event => {
+       let db2 = event.target.result;
+       let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
+       store3.createIndex("name2", "name2", { unique: true });
+       store3.transaction.oncomplete = () => {
+         done(db2);
+       }
+     };
+   });
+   // Prevents AbortError during close()
+-  yield new Promise(done => {
++  await new Promise(done => {
+     request.onsuccess = done;
+   });
+   db2.close();
+ 
+   console.log("added cookies and stuff from main page");
+ };
+ 
+ function deleteDB(dbName) {
+   return new Promise(resolve => {
+     dump("removing database " + dbName + " from " + document.location + "\n");
+     indexedDB.deleteDatabase(dbName).onsuccess = resolve;
+   });
+ }
+ 
+-window.setup = function*() {
+-  yield idbGenerator();
++window.setup = async function () {
++  await idbGenerator();
+ };
+ 
+-window.clear = function*() {
++window.clear = async function () {
+   document.cookie = "c1=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
+   document.cookie = "c3=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
+   document.cookie = "cs2=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
+ 
+   localStorage.clear();
+ 
+-  yield deleteDB("idb1");
+-  yield deleteDB("idb2");
++  await deleteDB("idb1");
++  await deleteDB("idb2");
+ 
+   dump("removed cookies, localStorage and indexedDB data from " +
+        document.location + "\n");
+ };
+ </script>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/browser/storage-helpers.js b/devtools/server/tests/browser/storage-helpers.js
+--- a/devtools/server/tests/browser/storage-helpers.js
++++ b/devtools/server/tests/browser/storage-helpers.js
+@@ -8,21 +8,21 @@
+ /**
+  * This generator function opens the given url in a new tab, then sets up the
+  * page by waiting for all cookies, indexedDB items etc. to be created.
+  *
+  * @param url {String} The url to be opened in the new tab
+  *
+  * @return {Promise} A promise that resolves after storage inspector is ready
+  */
+-function* openTabAndSetupStorage(url) {
+-  let content = yield addTab(url);
++async function openTabAndSetupStorage(url) {
++  let content = await addTab(url);
+ 
+   // Setup the async storages in main window and for all its iframes
+-  yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
++  await ContentTask.spawn(gBrowser.selectedBrowser, null, async function () {
+     /**
+      * Get all windows including frames recursively.
+      *
+      * @param {Window} [baseWindow]
+      *        The base window at which to start looking for child windows
+      *        (optional).
+      * @return {Set}
+      *         A set of windows.
+@@ -40,24 +40,24 @@ function* openTabAndSetupStorage(url) {
+       _getAllWindows(baseWindow);
+ 
+       return windows;
+     }
+ 
+     let windows = getAllWindows(content);
+     for (let win of windows) {
+       if (win.setup) {
+-        yield win.setup();
++        await win.setup();
+       }
+     }
+   });
+ }
+ 
+-function* clearStorage() {
+-  yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
++async function clearStorage() {
++  await ContentTask.spawn(gBrowser.selectedBrowser, null, async function () {
+     /**
+      * Get all windows including frames recursively.
+      *
+      * @param {Window} [baseWindow]
+      *        The base window at which to start looking for child windows
+      *        (optional).
+      * @return {Set}
+      *         A set of windows.
+@@ -75,13 +75,13 @@ function* clearStorage() {
+       _getAllWindows(baseWindow);
+ 
+       return windows;
+     }
+ 
+     let windows = getAllWindows(content);
+     for (let win of windows) {
+       if (win.clear) {
+-        yield win.clear();
++        await win.clear();
+       }
+     }
+   });
+ }
+diff --git a/devtools/server/tests/browser/storage-listings.html b/devtools/server/tests/browser/storage-listings.html
+--- a/devtools/server/tests/browser/storage-listings.html
++++ b/devtools/server/tests/browser/storage-listings.html
+@@ -1,9 +1,9 @@
+-<!DOCTYPE HTML>
++<!DOCTYPE HTML>
+ <html>
+ <!--
+ Bug 965872 - Storage inspector actor with cookies, local storage and session storage.
+ -->
+ <head>
+   <meta charset="utf-8">
+   <title>Storage inspector test for listing hosts and storages</title>
+ </head>
+@@ -23,101 +23,101 @@ document.cookie = "c3=foobar-2; secure=t
+   new Date(cookieExpiresTime2).toGMTString() + "; path=/";
+ // ... and some local storage items ..
+ localStorage.setItem("ls1", "foobar");
+ localStorage.setItem("ls2", "foobar-2");
+ // ... and finally some session storage items too
+ sessionStorage.setItem("ss1", "foobar-3");
+ console.log("added cookies and stuff from main page");
+ 
+-let idbGenerator = function*() {
++let idbGenerator = async function () {
+   let request = indexedDB.open("idb1", 1);
+   request.onerror = function() {
+     throw new Error("error opening db connection");
+   };
+-  let db = yield new Promise(done => {
++  let db = await new Promise(done => {
+     request.onupgradeneeded = event => {
+       let db = event.target.result;
+       let store1 = db.createObjectStore("obj1", { keyPath: "id" });
+       store1.createIndex("name", "name", { unique: false });
+       store1.createIndex("email", "email", { unique: true });
+       let store2 = db.createObjectStore("obj2", { keyPath: "id2" });
+       store1.transaction.oncomplete = () => {
+         done(db);
+       };
+     };
+   });
+ 
+   // Prevents AbortError
+-  yield new Promise(done => {
++  await new Promise(done => {
+     request.onsuccess = done;
+   });
+ 
+   let transaction = db.transaction(["obj1", "obj2"], "readwrite");
+   let store1 = transaction.objectStore("obj1");
+   let store2 = transaction.objectStore("obj2");
+   store1.add({id: 1, name: "foo", email: "foo@bar.com"});
+   store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
+   store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
+   store2.add({
+     id2: 1,
+     name: "foo",
+     email: "foo@bar.com",
+     extra: "baz"
+   });
+   // Prevents AbortError during close()
+-  yield new Promise(success => {
++  await new Promise(success => {
+     transaction.oncomplete = success;
+   });
+ 
+   db.close();
+ 
+   request = indexedDB.open("idb2", 1);
+-  let db2 = yield new Promise(done => {
++  let db2 = await new Promise(done => {
+     request.onupgradeneeded = event => {
+       let db2 = event.target.result;
+       let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
+       store3.createIndex("name2", "name2", { unique: true });
+       store3.transaction.oncomplete = () => {
+         done(db2);
+       }
+     };
+   });
+   // Prevents AbortError during close()
+-  yield new Promise(done => {
++  await new Promise(done => {
+     request.onsuccess = done;
+   });
+   db2.close();
+ 
+   dump("added cookies and stuff from main page\n");
+ };
+ 
+ function deleteDB(dbName) {
+   return new Promise(resolve => {
+     dump("removing database " + dbName + " from " + document.location + "\n");
+     indexedDB.deleteDatabase(dbName).onsuccess = resolve;
+   });
+ }
+ 
+-window.setup = function*() {
+-  yield idbGenerator();
++window.setup = async function () {
++  await idbGenerator();
+ };
+ 
+-window.clear = function*() {
++window.clear = async function () {
+   document.cookie = "c1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/browser";
+   document.cookie =
+     "c3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; secure=true";
+   document.cookie =
+     "cs2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=" +
+     partialHostname;
+ 
+   localStorage.clear();
+   sessionStorage.clear();
+ 
+-  yield deleteDB("idb1");
+-  yield deleteDB("idb2");
++  await deleteDB("idb1");
++  await deleteDB("idb2");
+ 
+   dump("removed cookies, localStorage, sessionStorage and indexedDB data " +
+        "from " + document.location + "\n");
+ };
+ </script>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/browser/storage-secured-iframe.html b/devtools/server/tests/browser/storage-secured-iframe.html
+--- a/devtools/server/tests/browser/storage-secured-iframe.html
++++ b/devtools/server/tests/browser/storage-secured-iframe.html
+@@ -1,94 +1,94 @@
+-<!DOCTYPE HTML>
++<!DOCTYPE HTML>
+ <html>
+ <!--
+ Iframe for testing multiple host detetion in storage actor
+ -->
+ <head>
+   <meta charset="utf-8">
+ </head>
+ <body>
+ <script type="application/javascript">
+ 
+ document.cookie = "sc1=foobar;";
+ localStorage.setItem("iframe-s-ls1", "foobar");
+ sessionStorage.setItem("iframe-s-ss1", "foobar-2");
+ 
+-let idbGenerator = function*() {
++let idbGenerator = async function () {
+   let request = indexedDB.open("idb-s1", 1);
+   request.onerror = function() {
+     throw new Error("error opening db connection");
+   };
+-  let db = yield new Promise(done => {
++  let db = await new Promise(done => {
+     request.onupgradeneeded = event => {
+       let db = event.target.result;
+       let store1 = db.createObjectStore("obj-s1", { keyPath: "id" });
+       store1.transaction.oncomplete = () => {
+         done(db);
+       };
+     };
+   });
+-  yield new Promise(done => {
++  await new Promise(done => {
+     request.onsuccess = done;
+   });
+ 
+   let transaction = db.transaction(["obj-s1"], "readwrite");
+   let store1 = transaction.objectStore("obj-s1");
+   store1.add({id: 6, name: "foo", email: "foo@bar.com"});
+   store1.add({id: 7, name: "foo2", email: "foo2@bar.com"});
+-  yield new Promise(success => {
++  await new Promise(success => {
+     transaction.oncomplete = success;
+   });
+ 
+   db.close();
+ 
+   request = indexedDB.open("idb-s2", 1);
+-  let db2 = yield new Promise(done => {
++  let db2 = await new Promise(done => {
+     request.onupgradeneeded = event => {
+       let db2 = event.target.result;
+       let store3 =
+         db2.createObjectStore("obj-s2", { keyPath: "id3", autoIncrement: true });
+       store3.createIndex("name2", "name2", { unique: true });
+       store3.transaction.oncomplete = () => {
+         done(db2);
+       };
+     };
+   });
+-  yield new Promise(done => {
++  await new Promise(done => {
+     request.onsuccess = done;
+   });
+ 
+   transaction = db2.transaction(["obj-s2"], "readwrite");
+   let store3 = transaction.objectStore("obj-s2");
+   store3.add({id3: 16, name2: "foo", email: "foo@bar.com"});
+-  yield new Promise(success => {
++  await new Promise(success => {
+     transaction.oncomplete = success;
+   });
+ 
+   db2.close();
+   dump("added cookies and stuff from secured iframe\n");
+ }
+ 
+ function deleteDB(dbName) {
+   return new Promise(resolve => {
+     dump("removing database " + dbName + " from " + document.location + "\n");
+     indexedDB.deleteDatabase(dbName).onsuccess = resolve;
+   });
+ }
+ 
+-window.setup = function*() {
+-  yield idbGenerator();
++window.setup = async function () {
++  await idbGenerator();
+ };
+ 
+-window.clear = function*() {
++window.clear = async function () {
+   document.cookie = "sc1=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
+ 
+   localStorage.clear();
+ 
+-  yield deleteDB("idb-s1");
+-  yield deleteDB("idb-s2");
++  await deleteDB("idb-s1");
++  await deleteDB("idb-s2");
+ 
+   console.log("removed cookies and stuff from secured iframe");
+ }
+ </script>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/inspector-helpers.js b/devtools/server/tests/mochitest/inspector-helpers.js
+--- a/devtools/server/tests/mochitest/inspector-helpers.js
++++ b/devtools/server/tests/mochitest/inspector-helpers.js
+@@ -2,17 +2,16 @@
+    promiseOnce, isSrcChange, isUnretained, isNewRoot, assertSrcChange, assertUnload,
+    assertFrameLoad, assertChildList, waitForMutation, addTest, addAsyncTest,
+    runNextTest */
+ "use strict";
+ 
+ const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+ const {DebuggerClient} = require("devtools/shared/client/debugger-client");
+ const {DebuggerServer} = require("devtools/server/main");
+-const { Task } = require("devtools/shared/task");
+ 
+ const Services = require("Services");
+ // promise is still used in tests using this helper
+ const defer = require("devtools/shared/defer");
+ const {DocumentWalker: _documentWalker} = require("devtools/server/actors/inspector/document-walker");
+ 
+ // Always log packets when running tests.
+ Services.prefs.setBoolPref("devtools.debugger.log", true);
+@@ -293,17 +292,17 @@ function waitForMutation(walker, test, m
+ }
+ 
+ var _tests = [];
+ function addTest(test) {
+   _tests.push(test);
+ }
+ 
+ function addAsyncTest(generator) {
+-  _tests.push(() => Task.spawn(generator).catch(ok.bind(null, false)));
++  _tests.push(() => (generator)().catch(ok.bind(null, false)));
+ }
+ 
+ function runNextTest() {
+   if (_tests.length == 0) {
+     SimpleTest.finish();
+     return;
+   }
+   let fn = _tests.shift();
+diff --git a/devtools/server/tests/mochitest/memory-helpers.js b/devtools/server/tests/mochitest/memory-helpers.js
+--- a/devtools/server/tests/mochitest/memory-helpers.js
++++ b/devtools/server/tests/mochitest/memory-helpers.js
+@@ -1,15 +1,14 @@
+ /* exported Task, startServerAndGetSelectedTabMemory, destroyServerAndFinish,
+    waitForTime, waitUntil */
+ "use strict";
+ 
+ const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+ const Services = require("Services");
+-const { Task } = require("devtools/shared/task");
+ const { DebuggerClient } = require("devtools/shared/client/debugger-client");
+ const { DebuggerServer } = require("devtools/server/main");
+ 
+ const { MemoryFront } = require("devtools/shared/fronts/memory");
+ 
+ // Always log packets when running tests.
+ Services.prefs.setBoolPref("devtools.debugger.log", true);
+ var gReduceTimePrecision = Services.prefs.getBoolPref("privacy.reduceTimerPrecision");
+diff --git a/devtools/server/tests/mochitest/test_animation_actor-lifetime.html b/devtools/server/tests/mochitest/test_animation_actor-lifetime.html
+--- a/devtools/server/tests/mochitest/test_animation_actor-lifetime.html
++++ b/devtools/server/tests/mochitest/test_animation_actor-lifetime.html
+@@ -33,49 +33,49 @@ window.onload = function () {
+ 
+       promiseDone(inspector.getWalker().then(walker => {
+         ok(walker, "getWalker() should return an actor.");
+         gWalker = walker;
+       }).then(runNextTest));
+     });
+   });
+ 
+-  addAsyncTest(function* testActorLifetime() {
++  addAsyncTest(async function testActorLifetime() {
+     info("Testing animated node actor");
+-    let animatedNodeActor = yield gWalker.querySelector(gWalker.rootNode,
++    let animatedNodeActor = await gWalker.querySelector(gWalker.rootNode,
+       ".animated");
+-    yield animationsFront.getAnimationPlayersForNode(animatedNodeActor);
++    await animationsFront.getAnimationPlayersForNode(animatedNodeActor);
+ 
+     let animationsActor = DebuggerServer
+                           .searchAllConnectionsForActor(animationsFront.actorID);
+ 
+     is(animationsActor.actors.length, 1,
+       "AnimationActor have 1 AnimationPlayerActors");
+ 
+     info("Testing AnimationPlayerActors release");
+-    let stillNodeActor = yield gWalker.querySelector(gWalker.rootNode,
++    let stillNodeActor = await gWalker.querySelector(gWalker.rootNode,
+       ".still");
+-    yield animationsFront.getAnimationPlayersForNode(stillNodeActor);
++    await animationsFront.getAnimationPlayersForNode(stillNodeActor);
+     is(animationsActor.actors.length, 0,
+       "AnimationActor does not have any AnimationPlayerActors anymore");
+ 
+     info("Testing multi animated node actor");
+-    let multiNodeActor = yield gWalker.querySelector(gWalker.rootNode,
++    let multiNodeActor = await gWalker.querySelector(gWalker.rootNode,
+       ".multi");
+-    yield animationsFront.getAnimationPlayersForNode(multiNodeActor);
++    await animationsFront.getAnimationPlayersForNode(multiNodeActor);
+     is(animationsActor.actors.length, 2,
+       "AnimationActor has now 2 AnimationPlayerActors");
+ 
+     info("Testing single animated node actor");
+-    yield animationsFront.getAnimationPlayersForNode(animatedNodeActor);
++    await animationsFront.getAnimationPlayersForNode(animatedNodeActor);
+     is(animationsActor.actors.length, 1,
+       "AnimationActor has only one AnimationPlayerActors");
+ 
+     info("Testing AnimationPlayerActors release again");
+-    yield animationsFront.getAnimationPlayersForNode(stillNodeActor);
++    await animationsFront.getAnimationPlayersForNode(stillNodeActor);
+     is(animationsActor.actors.length, 0,
+       "AnimationActor does not have any AnimationPlayerActors anymore");
+ 
+     runNextTest();
+   });
+ 
+   runNextTest();
+ };
+diff --git a/devtools/server/tests/mochitest/test_css-properties.html b/devtools/server/tests/mochitest/test_css-properties.html
+--- a/devtools/server/tests/mochitest/test_css-properties.html
++++ b/devtools/server/tests/mochitest/test_css-properties.html
+@@ -26,21 +26,21 @@ window.onload = function () {
+       });
+     });
+   }
+ 
+   function toSortedString(array) {
+     return JSON.stringify(array.sort());
+   }
+ 
+-  const runCssPropertiesTests = Task.async(function* (url, useActor) {
++  const runCssPropertiesTests = async function (url, useActor) {
+     info(`Opening two tabs ${useActor ? "with" : "without"} CssPropertiesActor support.`);
+ 
+-    let attachmentA = yield promiseAttachUrl(url);
+-    let attachmentB = yield promiseAttachUrl(url);
++    let attachmentA = await promiseAttachUrl(url);
++    let attachmentB = await promiseAttachUrl(url);
+ 
+     const toolboxMockA = {
+       target: {
+         hasActor: () => useActor,
+         client: attachmentA.client,
+         form: attachmentA.tab
+       },
+       // Fake the window for css-properties.js's getClientBrowserVersion to work
+@@ -50,18 +50,18 @@ window.onload = function () {
+       target: {
+         hasActor: () => useActor,
+         client: attachmentB.client,
+         form: attachmentB.tab
+       },
+       win: window
+     };
+ 
+-    yield initCssProperties(toolboxMockA);
+-    yield initCssProperties(toolboxMockB);
++    await initCssProperties(toolboxMockA);
++    await initCssProperties(toolboxMockB);
+ 
+     const cssProperties = getCssProperties(toolboxMockA);
+     const cssPropertiesA = getCssProperties(toolboxMockA);
+     const cssPropertiesB = getCssProperties(toolboxMockB);
+ 
+     is(cssProperties, cssPropertiesA,
+        "Multiple calls with the same toolbox returns the same object.");
+     isnot(cssProperties, cssPropertiesB,
+@@ -96,22 +96,22 @@ window.onload = function () {
+       "A property with color values includes papayawhip.");
+     ok(bgColorValues.includes("rgb"),
+       "A property with color values includes non-colors.");
+ 
+     ok(cssProperties.isValidOnClient("margin", "0px", window.document),
+       "Margin and 0px are valid CSS values");
+     ok(!cssProperties.isValidOnClient("margin", "foo", window.document),
+       "Margin and foo are not valid CSS values");
+-  });
++  };
+ 
+-  addAsyncTest(function* setup() {
++  addAsyncTest(async function setup() {
+     let url = document.getElementById("cssProperties").href;
+-    yield runCssPropertiesTests(url, true);
+-    yield runCssPropertiesTests(url, false);
++    await runCssPropertiesTests(url, true);
++    await runCssPropertiesTests(url, false);
+ 
+     runNextTest();
+   });
+ 
+   SimpleTest.waitForExplicitFinish();
+   runNextTest();
+ };
+   </script>
+diff --git a/devtools/server/tests/mochitest/test_inspector-anonymous.html b/devtools/server/tests/mochitest/test_inspector-anonymous.html
+--- a/devtools/server/tests/mochitest/test_inspector-anonymous.html
++++ b/devtools/server/tests/mochitest/test_inspector-anonymous.html
+@@ -42,73 +42,73 @@ window.onload = function () {
+       let inspector = InspectorFront(client, tab);
+       promiseDone(inspector.getWalker().then(walker => {
+         ok(walker, "getWalker() should return an actor.");
+         gWalker = walker;
+       }).then(runNextTest));
+     });
+   });
+ 
+-  addAsyncTest(function* testXBLAnonymousInHTMLDocument() {
++  addAsyncTest(async function testXBLAnonymousInHTMLDocument() {
+     info("Testing XBL anonymous in an HTML document.");
+     let rawToolbarbutton = gInspectee.createElementNS(XUL_NS, "toolbarbutton");
+     gInspectee.documentElement.appendChild(rawToolbarbutton);
+ 
+-    let toolbarbutton = yield gWalker.querySelector(gWalker.rootNode, "toolbarbutton");
+-    let children = yield gWalker.children(toolbarbutton);
++    let toolbarbutton = await gWalker.querySelector(gWalker.rootNode, "toolbarbutton");
++    let children = await gWalker.children(toolbarbutton);
+ 
+     is(toolbarbutton.numChildren, 0, "XBL content is not visible in HTML doc");
+     is(children.nodes.length, 0, "XBL content is not returned in HTML doc");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testNativeAnonymous() {
++  addAsyncTest(async function testNativeAnonymous() {
+     info("Testing native anonymous content with walker.");
+ 
+-    let select = yield gWalker.querySelector(gWalker.rootNode, "select");
+-    let children = yield gWalker.children(select);
++    let select = await gWalker.querySelector(gWalker.rootNode, "select");
++    let children = await gWalker.children(select);
+ 
+     is(select.numChildren, 2, "No native anon content for form control");
+     is(children.nodes.length, 2, "No native anon content for form control");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testNativeAnonymousStartingNode() {
++  addAsyncTest(async function testNativeAnonymousStartingNode() {
+     info("Tests attaching an element that a walker can't see.");
+ 
+     let serverWalker = DebuggerServer.searchAllConnectionsForActor(gWalker.actorID);
+     let docwalker = new _documentWalker(
+       gInspectee.querySelector("select"),
+       gInspectee.defaultView,
+       nodeFilterConstants.SHOW_ALL,
+       () => {
+         return nodeFilterConstants.FILTER_ACCEPT;
+       }
+     );
+     let scrollbar = docwalker.lastChild();
+     is(scrollbar.tagName, "scrollbar", "An anonymous child has been fetched");
+ 
+-    let node = yield serverWalker.attachElement(scrollbar);
++    let node = await serverWalker.attachElement(scrollbar);
+ 
+     ok(node, "A response has arrived");
+     ok(node.node, "A node is in the response");
+     is(node.node.rawNode.tagName, "SELECT",
+       "The node has changed to a parent that the walker recognizes");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testPseudoElements() {
++  addAsyncTest(async function testPseudoElements() {
+     info("Testing pseudo elements with walker.");
+ 
+     // Markup looks like: <div><::before /><span /><::after /></div>
+-    let pseudo = yield gWalker.querySelector(gWalker.rootNode, "#pseudo");
+-    let children = yield gWalker.children(pseudo);
++    let pseudo = await gWalker.querySelector(gWalker.rootNode, "#pseudo");
++    let children = await gWalker.children(pseudo);
+ 
+     is(pseudo.numChildren, 1, "::before/::after are not counted if there is a child");
+     is(children.nodes.length, 3, "Correct number of children");
+ 
+     let before = children.nodes[0];
+     ok(before.isAnonymous, "Child is anonymous");
+     ok(!before._form.isXBLAnonymous, "Child is not XBL anonymous");
+     ok(!before._form.isShadowAnonymous, "Child is not shadow anonymous");
+@@ -121,47 +121,47 @@ window.onload = function () {
+     ok(after.isAnonymous, "Child is anonymous");
+     ok(!after._form.isXBLAnonymous, "Child is not XBL anonymous");
+     ok(!after._form.isShadowAnonymous, "Child is not shadow anonymous");
+     ok(after._form.isNativeAnonymous, "Child is native anonymous");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testEmptyWithPseudo() {
++  addAsyncTest(async function testEmptyWithPseudo() {
+     info("Testing elements with no childrent, except for pseudos.");
+ 
+     info("Checking an element whose only child is a pseudo element");
+-    let pseudo = yield gWalker.querySelector(gWalker.rootNode, "#pseudo-empty");
+-    let children = yield gWalker.children(pseudo);
++    let pseudo = await gWalker.querySelector(gWalker.rootNode, "#pseudo-empty");
++    let children = await gWalker.children(pseudo);
+ 
+     is(pseudo.numChildren, 1,
+        "::before/::after are is counted if there are no other children");
+     is(children.nodes.length, 1, "Correct number of children");
+ 
+     let before = children.nodes[0];
+     ok(before.isAnonymous, "Child is anonymous");
+     ok(!before._form.isXBLAnonymous, "Child is not XBL anonymous");
+     ok(!before._form.isShadowAnonymous, "Child is not shadow anonymous");
+     ok(before._form.isNativeAnonymous, "Child is native anonymous");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testShadowAnonymous() {
++  addAsyncTest(async function testShadowAnonymous() {
+     // Stylo doesn't currently support shadow DOM (bug 1293844)
+     if (isStylo) {
+       runNextTest();
+       return;
+     }
+ 
+     info("Testing shadow DOM content.");
+ 
+-    let shadow = yield gWalker.querySelector(gWalker.rootNode, "#shadow");
+-    let children = yield gWalker.children(shadow);
++    let shadow = await gWalker.querySelector(gWalker.rootNode, "#shadow");
++    let children = await gWalker.children(shadow);
+ 
+     is(shadow.numChildren, 3, "Children of the shadow root are counted");
+     is(children.nodes.length, 3, "Children returned from walker");
+ 
+     let before = children.nodes[0];
+     ok(before.isAnonymous, "Child is anonymous");
+     ok(!before._form.isXBLAnonymous, "Child is not XBL anonymous");
+     ok(!before._form.isShadowAnonymous, "Child is not shadow anonymous");
+@@ -169,17 +169,17 @@ window.onload = function () {
+ 
+     // <h3>Shadow <em>DOM</em></h3>
+     let shadowChild1 = children.nodes[1];
+     ok(shadowChild1.isAnonymous, "Child is anonymous");
+     ok(!shadowChild1._form.isXBLAnonymous, "Child is not XBL anonymous");
+     ok(shadowChild1._form.isShadowAnonymous, "Child is shadow anonymous");
+     ok(!shadowChild1._form.isNativeAnonymous, "Child is not native anonymous");
+ 
+-    let shadowSubChildren = yield gWalker.children(children.nodes[1]);
++    let shadowSubChildren = await gWalker.children(children.nodes[1]);
+     is(shadowChild1.numChildren, 2, "Subchildren of the shadow root are counted");
+     is(shadowSubChildren.nodes.length, 2, "Subchildren are returned from walker");
+ 
+     // <em>DOM</em>
+     let shadowSubChild = children.nodes[1];
+     ok(shadowSubChild.isAnonymous, "Child is anonymous");
+     ok(!shadowSubChild._form.isXBLAnonymous, "Child is not XBL anonymous");
+     ok(shadowSubChild._form.isShadowAnonymous, "Child is shadow anonymous");
+diff --git a/devtools/server/tests/mochitest/test_inspector-dead-nodes.html b/devtools/server/tests/mochitest/test_inspector-dead-nodes.html
+--- a/devtools/server/tests/mochitest/test_inspector-dead-nodes.html
++++ b/devtools/server/tests/mochitest/test_inspector-dead-nodes.html
+@@ -16,358 +16,358 @@ https://bugzilla.mozilla.org/show_bug.cg
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+   runNextTest();
+ };
+ 
+ let gWalker = null;
+ let gDoc = null;
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   let url = document.getElementById("inspectorContent").href;
+ 
+   let def = defer();
+   attachURL(url, function (err, client, tab, doc) {
+     def.resolve({client, tab, doc});
+   });
+-  let {client, tab, doc} = yield def.promise;
++  let {client, tab, doc} = await def.promise;
+   gDoc = doc;
+ 
+   let {InspectorFront} = require("devtools/shared/fronts/inspector");
+   let inspector = InspectorFront(client, tab);
+-  gWalker = yield inspector.getWalker();
++  gWalker = await inspector.getWalker();
+ 
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.parents(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.parents(nodeFront);
+-  yield newRoot;
++  await gWalker.parents(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.parents() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.children(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "body");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "body");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.children(nodeFront);
+-  yield newRoot;
++  await gWalker.children(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.children() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.siblings(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.siblings(nodeFront);
+-  yield newRoot;
++  await gWalker.siblings(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.siblings() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.nextSibling(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.nextSibling(nodeFront);
+-  yield newRoot;
++  await gWalker.nextSibling(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.nextSibling() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.previousSibling(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.previousSibling(nodeFront);
+-  yield newRoot;
++  await gWalker.previousSibling(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.previousSibling() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.addPseudoClassLock(nodeFront) before the load completes " +
+     "shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.addPseudoClassLock(nodeFront, ":hover");
+-  yield newRoot;
++  await gWalker.addPseudoClassLock(nodeFront, ":hover");
++  await newRoot;
+ 
+   ok(true, "The call to walker.addPseudoClassLock() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.removePseudoClassLock(nodeFront) before the load completes " +
+     "shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.removePseudoClassLock(nodeFront, ":hover");
+-  yield newRoot;
++  await gWalker.removePseudoClassLock(nodeFront, ":hover");
++  await newRoot;
+ 
+   ok(true, "The call to walker.removePseudoClassLock() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.clearPseudoClassLocks(nodeFront) before the load completes " +
+     "shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.clearPseudoClassLocks(nodeFront);
+-  yield newRoot;
++  await gWalker.clearPseudoClassLocks(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.clearPseudoClassLocks() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.innerHTML(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.innerHTML(nodeFront);
+-  yield newRoot;
++  await gWalker.innerHTML(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.innerHTML() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.setInnerHTML(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.setInnerHTML(nodeFront, "<span>innerHTML changed</span>");
+-  yield newRoot;
++  await gWalker.setInnerHTML(nodeFront, "<span>innerHTML changed</span>");
++  await newRoot;
+ 
+   ok(true, "The call to walker.setInnerHTML() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.outerHTML(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.outerHTML(nodeFront);
+-  yield newRoot;
++  await gWalker.outerHTML(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.outerHTML() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.setOuterHTML(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.setOuterHTML(nodeFront, "<h1><span>innerHTML changed</span></h1>");
+-  yield newRoot;
++  await gWalker.setOuterHTML(nodeFront, "<h1><span>innerHTML changed</span></h1>");
++  await newRoot;
+ 
+   ok(true, "The call to walker.setOuterHTML() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.insertAdjacentHTML(nodeFront) before the load completes shouldn't " +
+     "fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.insertAdjacentHTML(nodeFront, "afterEnd",
++  await gWalker.insertAdjacentHTML(nodeFront, "afterEnd",
+     "<span>new adjacent HTML</span>");
+-  yield newRoot;
++  await newRoot;
+ 
+   ok(true, "The call to walker.insertAdjacentHTML() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.removeNode(nodeFront) before the load completes should throw");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+   let hasThrown = false;
+   try {
+-    yield gWalker.removeNode(nodeFront);
++    await gWalker.removeNode(nodeFront);
+   } catch (e) {
+     hasThrown = true;
+   }
+-  yield newRoot;
++  await newRoot;
+ 
+   ok(hasThrown, "The call to walker.removeNode() threw");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.removeNodes([nodeFront]) before the load completes should throw");
+ 
+-  let nodeFront1 = yield gWalker.querySelector(gWalker.rootNode, "h1");
+-  let nodeFront2 = yield gWalker.querySelector(gWalker.rootNode, "#longstring");
+-  let nodeFront3 = yield gWalker.querySelector(gWalker.rootNode, "#shortstring");
++  let nodeFront1 = await gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront2 = await gWalker.querySelector(gWalker.rootNode, "#longstring");
++  let nodeFront3 = await gWalker.querySelector(gWalker.rootNode, "#shortstring");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+   let hasThrown = false;
+   try {
+-    yield gWalker.removeNodes([nodeFront1, nodeFront2, nodeFront3]);
++    await gWalker.removeNodes([nodeFront1, nodeFront2, nodeFront3]);
+   } catch (e) {
+     hasThrown = true;
+   }
+-  yield newRoot;
++  await newRoot;
+ 
+   ok(hasThrown, "The call to walker.removeNodes() threw");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.insertBefore(nodeFront, parent, null) before the load completes " +
+     "shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
+-  let newParentFront = yield gWalker.querySelector(gWalker.rootNode, "#longlist");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
++  let newParentFront = await gWalker.querySelector(gWalker.rootNode, "#longlist");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.insertBefore(nodeFront, newParentFront);
+-  yield newRoot;
++  await gWalker.insertBefore(nodeFront, newParentFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.insertBefore() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.insertBefore(nodeFront, parent, sibling) before the load completes " +
+     "shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
+-  let newParentFront = yield gWalker.querySelector(gWalker.rootNode, "#longlist");
+-  let siblingFront = yield gWalker.querySelector(gWalker.rootNode, "#b");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
++  let newParentFront = await gWalker.querySelector(gWalker.rootNode, "#longlist");
++  let siblingFront = await gWalker.querySelector(gWalker.rootNode, "#b");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.insertBefore(nodeFront, newParentFront, siblingFront);
+-  yield newRoot;
++  await gWalker.insertBefore(nodeFront, newParentFront, siblingFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.insertBefore() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.editTagName(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.editTagName(nodeFront, "h2");
+-  yield newRoot;
++  await gWalker.editTagName(nodeFront, "h2");
++  await newRoot;
+ 
+   ok(true, "The call to walker.editTagName() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.hideNode(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.hideNode(nodeFront);
+-  yield newRoot;
++  await gWalker.hideNode(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.hideNode() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.unhideNode(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.unhideNode(nodeFront);
+-  yield newRoot;
++  await gWalker.unhideNode(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.unhideNode() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.releaseNode(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "h1");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "h1");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.releaseNode(nodeFront);
+-  yield newRoot;
++  await gWalker.releaseNode(nodeFront);
++  await newRoot;
+ 
+   ok(true, "The call to walker.releaseNode() didn't fail");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
++addAsyncTest(async function () {
+   info("Getting a nodeFront, reloading the page, and calling " +
+     "walker.querySelector(nodeFront) before the load completes shouldn't fail");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, "body");
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, "body");
+   let newRoot = waitForMutation(gWalker, isNewRoot);
+   gDoc.defaultView.location.reload();
+-  yield gWalker.querySelector(nodeFront, "h1");
+-  yield newRoot;
++  await gWalker.querySelector(nodeFront, "h1");
++  await newRoot;
+ 
+   ok(true, "The call to walker.querySelector() didn't fail");
+   runNextTest();
+ });
+ 
+ addTest(function cleanup() {
+   gWalker = null;
+   gDoc = null;
+diff --git a/devtools/server/tests/mochitest/test_inspector-display-type.html b/devtools/server/tests/mochitest/test_inspector-display-type.html
+--- a/devtools/server/tests/mochitest/test_inspector-display-type.html
++++ b/devtools/server/tests/mochitest/test_inspector-display-type.html
+@@ -27,46 +27,46 @@ addTest(function setup() {
+     let inspector = InspectorFront(client, tab);
+ 
+     promiseDone(inspector.getWalker().then(walker => {
+       gWalker = walker;
+     }).then(runNextTest));
+   });
+ });
+ 
+-addAsyncTest(function* testInlineBlockDisplayType() {
++addAsyncTest(async function testInlineBlockDisplayType() {
+   info("Test getting the display type of an inline block element.");
+-  let node = yield gWalker.querySelector(gWalker.rootNode, "#inline-block");
++  let node = await gWalker.querySelector(gWalker.rootNode, "#inline-block");
+   let displayType = node.displayType;
+   is(displayType, "inline-block", "The node has a display type of 'inline-block'.");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* testInlineTextChildDisplayType() {
++addAsyncTest(async function testInlineTextChildDisplayType() {
+   info("Test getting the display type of an inline text child.");
+-  let node = yield gWalker.querySelector(gWalker.rootNode, "#inline-block");
+-  let children = yield gWalker.children(node);
++  let node = await gWalker.querySelector(gWalker.rootNode, "#inline-block");
++  let children = await gWalker.children(node);
+   let inlineTextChild = children.nodes[0];
+   let displayType = inlineTextChild.displayType;
+   ok(!displayType, "No display type for inline text child.");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* testGridDisplayType() {
++addAsyncTest(async function testGridDisplayType() {
+   info("Test getting the display type of an grid container.");
+-  let node = yield gWalker.querySelector(gWalker.rootNode, "#grid");
++  let node = await gWalker.querySelector(gWalker.rootNode, "#grid");
+   let displayType = node.displayType;
+   is(displayType, "grid", "The node has a display type of 'grid'.");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* testBlockDisplayType() {
++addAsyncTest(async function testBlockDisplayType() {
+   info("Test getting the display type of a block element.");
+-  let node = yield gWalker.querySelector(gWalker.rootNode, "#block");
+-  let displayType = yield node.displayType;
++  let node = await gWalker.querySelector(gWalker.rootNode, "#block");
++  let displayType = await node.displayType;
+   is(displayType, "block", "The node has a display type of 'block'.");
+   runNextTest();
+ });
+ 
+ addTest(function () {
+   gWalker = null;
+   runNextTest();
+ });
+diff --git a/devtools/server/tests/mochitest/test_inspector-duplicate-node.html b/devtools/server/tests/mochitest/test_inspector-duplicate-node.html
+--- a/devtools/server/tests/mochitest/test_inspector-duplicate-node.html
++++ b/devtools/server/tests/mochitest/test_inspector-duplicate-node.html
+@@ -27,29 +27,29 @@ addTest(function setup() {
+     let inspector = InspectorFront(client, tab);
+     promiseDone(inspector.getWalker().then(walker => {
+       ok(walker, "getWalker() should return an actor.");
+       gWalker = walker;
+     }).then(runNextTest));
+   });
+ });
+ 
+-addTest(Task.async(function* testDuplicateNode() {
++addTest(async function testDuplicateNode() {
+   let className = ".node-to-duplicate";
+-  let matches = yield gWalker.querySelectorAll(gWalker.rootNode, className);
++  let matches = await gWalker.querySelectorAll(gWalker.rootNode, className);
+   is(matches.length, 1, "There should initially be one node to duplicate.");
+ 
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, className);
+-  yield gWalker.duplicateNode(nodeFront);
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, className);
++  await gWalker.duplicateNode(nodeFront);
+ 
+-  matches = yield gWalker.querySelectorAll(gWalker.rootNode, className);
++  matches = await gWalker.querySelectorAll(gWalker.rootNode, className);
+   is(matches.length, 2, "The node should now be duplicated.");
+ 
+   runNextTest();
+-}));
++});
+ 
+ addTest(function cleanup() {
+   gWalker = null;
+   runNextTest();
+ });
+   </script>
+ </head>
+ <body>
+diff --git a/devtools/server/tests/mochitest/test_inspector-insert.html b/devtools/server/tests/mochitest/test_inspector-insert.html
+--- a/devtools/server/tests/mochitest/test_inspector-insert.html
++++ b/devtools/server/tests/mochitest/test_inspector-insert.html
+@@ -31,71 +31,71 @@ addTest(function setup() {
+     let inspectorFront = InspectorFront(client, tab);
+     promiseDone(inspectorFront.getWalker().then(walker => {
+       ok(walker, "getWalker() should return an actor.");
+       gWalker = walker;
+     }).then(runNextTest));
+   });
+ });
+ 
+-addAsyncTest(function* testRearrange() {
+-  let longlist = yield gWalker.querySelector(gWalker.rootNode, "#longlist");
+-  let children = yield gWalker.children(longlist);
++addAsyncTest(async function testRearrange() {
++  let longlist = await gWalker.querySelector(gWalker.rootNode, "#longlist");
++  let children = await gWalker.children(longlist);
+   let nodeA = children.nodes[0];
+   is(nodeA.id, "a", "Got the expected node.");
+ 
+   // Move nodeA to the end of the list.
+-  yield gWalker.insertBefore(nodeA, longlist, null);
++  await gWalker.insertBefore(nodeA, longlist, null);
+   ok(!gInspectee.querySelector("#a").nextSibling,
+      "a should now be at the end of the list.");
+-  children = yield gWalker.children(longlist);
++  children = await gWalker.children(longlist);
+   is(nodeA, children.nodes[children.nodes.length - 1],
+      "a should now be the last returned child.");
+ 
+   // Now move it to the middle of the list.
+   let nextNode = children.nodes[13];
+-  yield gWalker.insertBefore(nodeA, longlist, nextNode);
++  await gWalker.insertBefore(nodeA, longlist, nextNode);
+   let sibling =
+     new DocumentWalker(gInspectee.querySelector("#a"), window).nextSibling();
+   is(sibling, nextNode.rawNode(), "Node should match the expected next node.");
+-  children = yield gWalker.children(longlist);
++  children = await gWalker.children(longlist);
+   is(nodeA, children.nodes[13], "a should be where we expect it.");
+   is(nextNode, children.nodes[14], "next node should be where we expect it.");
+ 
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* testInsertInvalidInput() {
+-  let longlist = yield gWalker.querySelector(gWalker.rootNode, "#longlist");
+-  let children = yield gWalker.children(longlist);
++addAsyncTest(async function testInsertInvalidInput() {
++  let longlist = await gWalker.querySelector(gWalker.rootNode, "#longlist");
++  let children = await gWalker.children(longlist);
+   let nodeA = children.nodes[0];
+   let nextSibling = children.nodes[1];
+ 
+   // Now move it to the original location and make sure no mutation happens.
+   let hasMutated = false;
+   let observer = new gInspectee.defaultView.MutationObserver(() => {
+     hasMutated = true;
+   });
+   observer.observe(longlist.rawNode(), {
+     childList: true,
+   });
+ 
+-  yield gWalker.insertBefore(nodeA, longlist, nodeA);
++  await gWalker.insertBefore(nodeA, longlist, nodeA);
+   ok(!hasMutated, "hasn't mutated");
+   hasMutated = false;
+ 
+-  yield gWalker.insertBefore(nodeA, longlist, nextSibling);
++  await gWalker.insertBefore(nodeA, longlist, nextSibling);
+   ok(!hasMutated, "still hasn't mutated after inserting before nextSibling");
+   hasMutated = false;
+ 
+-  yield gWalker.insertBefore(nodeA, longlist);
++  await gWalker.insertBefore(nodeA, longlist);
+   ok(hasMutated, "has mutated after inserting with null sibling");
+   hasMutated = false;
+ 
+-  yield gWalker.insertBefore(nodeA, longlist);
++  await gWalker.insertBefore(nodeA, longlist);
+   ok(!hasMutated, "hasn't mutated after inserting with null sibling again");
+ 
+   observer.disconnect();
+   runNextTest();
+ });
+ 
+ addTest(function cleanup() {
+   gWalker = null;
+diff --git a/devtools/server/tests/mochitest/test_inspector-mutations-events.html b/devtools/server/tests/mochitest/test_inspector-mutations-events.html
+--- a/devtools/server/tests/mochitest/test_inspector-mutations-events.html
++++ b/devtools/server/tests/mochitest/test_inspector-mutations-events.html
+@@ -23,95 +23,95 @@ window.onload = function () {
+   let walker = null;
+   let eventListener1 = function () {};
+   let eventListener2 = function () {};
+   let eventNode1;
+   let eventNode2;
+   let eventFront1;
+   let eventFront2;
+ 
+-  addAsyncTest(function* setup() {
++  addAsyncTest(async function setup() {
+     info("Setting up inspector and walker actors.");
+     let url = document.getElementById("inspectorContent").href;
+ 
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         inspectee = doc;
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+-    walker = yield inspector.getWalker();
++    walker = await inspector.getWalker();
+     ok(walker, "getWalker() should return an actor.");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* setupEventTest() {
++  addAsyncTest(async function setupEventTest() {
+     eventNode1 = inspectee.querySelector("#a");
+     eventNode2 = inspectee.querySelector("#b");
+ 
+-    eventFront1 = yield walker.querySelector(walker.rootNode, "#a");
+-    eventFront2 = yield walker.querySelector(walker.rootNode, "#b");
++    eventFront1 = await walker.querySelector(walker.rootNode, "#a");
++    eventFront2 = await walker.querySelector(walker.rootNode, "#b");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testChangeEventListenerOnSingleNode() {
++  addAsyncTest(async function testChangeEventListenerOnSingleNode() {
+     checkNodesHaveNoEventListener();
+ 
+     info("add event listener on a single node");
+     eventNode1.addEventListener("click", eventListener1);
+ 
+-    let mutations = yield waitForMutations();
++    let mutations = await waitForMutations();
+     is(mutations.length, 1, "one mutation expected");
+     is(mutations[0].target, eventFront1, "mutation targets eventFront1");
+     is(mutations[0].type, "events", "mutation type is events");
+     is(mutations[0].hasEventListeners, true,
+        "mutation target should have event listeners");
+     is(eventFront1.hasEventListeners, true, "eventFront1 should have event listeners");
+ 
+     info("remove event listener on a single node");
+     eventNode1.removeEventListener("click", eventListener1);
+ 
+-    mutations = yield waitForMutations();
++    mutations = await waitForMutations();
+     is(mutations.length, 1, "one mutation expected");
+     is(mutations[0].target, eventFront1, "mutation targets eventFront1");
+     is(mutations[0].type, "events", "mutation type is events");
+     is(mutations[0].hasEventListeners, false,
+        "mutation target should have no event listeners");
+     is(eventFront1.hasEventListeners, false,
+        "eventFront1 should have no event listeners");
+ 
+     info("perform several event listener changes on a single node");
+     eventNode1.addEventListener("click", eventListener1);
+     eventNode1.addEventListener("click", eventListener2);
+     eventNode1.removeEventListener("click", eventListener1);
+     eventNode1.removeEventListener("click", eventListener2);
+ 
+-    mutations = yield waitForMutations();
++    mutations = await waitForMutations();
+     is(mutations.length, 1, "one mutation expected");
+     is(mutations[0].target, eventFront1, "mutation targets eventFront1");
+     is(mutations[0].type, "events", "mutation type is events");
+     is(mutations[0].hasEventListeners, false,
+        "no event listener expected on mutation target");
+     is(eventFront1.hasEventListeners, false, "no event listener expected on node");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testChangeEventsOnSeveralNodes() {
++  addAsyncTest(async function testChangeEventsOnSeveralNodes() {
+     checkNodesHaveNoEventListener();
+ 
+     info("add event listeners on both nodes");
+     eventNode1.addEventListener("click", eventListener1);
+     eventNode2.addEventListener("click", eventListener2);
+ 
+-    let mutations = yield waitForMutations();
++    let mutations = await waitForMutations();
+     is(mutations.length, 2, "two mutations expected, one for each modified node");
+     // first mutation
+     is(mutations[0].target, eventFront1, "first mutation targets eventFront1");
+     is(mutations[0].type, "events", "mutation type is events");
+     is(mutations[0].hasEventListeners, true,
+        "mutation target should have event listeners");
+     is(eventFront1.hasEventListeners, true, "eventFront1 should have event listeners");
+     // second mutation
+@@ -120,17 +120,17 @@ window.onload = function () {
+     is(mutations[1].hasEventListeners, true,
+        "mutation target should have event listeners");
+     is(eventFront2.hasEventListeners, true, "eventFront1 should have event listeners");
+ 
+     info("remove event listeners on both nodes");
+     eventNode1.removeEventListener("click", eventListener1);
+     eventNode2.removeEventListener("click", eventListener2);
+ 
+-    mutations = yield waitForMutations();
++    mutations = await waitForMutations();
+     is(mutations.length, 2, "one mutation registered for event listener change");
+     // first mutation
+     is(mutations[0].target, eventFront1, "first mutation targets eventFront1");
+     is(mutations[0].type, "events", "mutation type is events");
+     is(mutations[0].hasEventListeners, false,
+        "mutation target should have no event listeners");
+     is(eventFront1.hasEventListeners, false,
+        "eventFront2 should have no event listeners");
+@@ -140,26 +140,26 @@ window.onload = function () {
+     is(mutations[1].hasEventListeners, false,
+        "mutation target should have no event listeners");
+     is(eventFront2.hasEventListeners, false,
+        "eventFront2 should have no event listeners");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testRemoveMissingEvent() {
++  addAsyncTest(async function testRemoveMissingEvent() {
+     checkNodesHaveNoEventListener();
+ 
+     info("try to remove an event listener not previously added");
+     eventNode1.removeEventListener("click", eventListener1);
+ 
+     info("set any attribute on the node to trigger a mutation");
+     eventNode1.setAttribute("data-attr", "somevalue");
+ 
+-    let mutations = yield waitForMutations();
++    let mutations = await waitForMutations();
+     is(mutations.length, 1, "expect only one mutation");
+     isnot(mutations.type, "events", "mutation type should not be events");
+ 
+     runNextTest();
+   });
+ 
+   function checkNodesHaveNoEventListener() {
+     is(eventFront1.hasEventListeners, false,
+diff --git a/devtools/server/tests/mochitest/test_inspector-pick-color.html b/devtools/server/tests/mochitest/test_inspector-pick-color.html
+--- a/devtools/server/tests/mochitest/test_inspector-pick-color.html
++++ b/devtools/server/tests/mochitest/test_inspector-pick-color.html
+@@ -18,70 +18,70 @@ https://bugzilla.mozilla.org/show_bug.cg
+ window.onload = function () {
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+   SimpleTest.waitForExplicitFinish();
+ 
+   let win = null;
+   let inspector = null;
+ 
+-  addAsyncTest(function* () {
++  addAsyncTest(async function () {
+     info("Setting up inspector actor");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         win = doc.defaultView;
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* () {
++  addAsyncTest(async function () {
+     info("Start picking a color from the page");
+-    yield inspector.pickColorFromPage();
++    await inspector.pickColorFromPage();
+ 
+     info("Click in the page and make sure a color-picked event is received");
+     let onColorPicked = waitForEvent("color-picked");
+     win.document.body.click();
+-    let color = yield onColorPicked;
++    let color = await onColorPicked;
+ 
+     is(color, "#000000", "The color-picked event was received with the right color");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* () {
++  addAsyncTest(async function () {
+     info("Start picking a color from the page");
+-    yield inspector.pickColorFromPage();
++    await inspector.pickColorFromPage();
+ 
+     info("Use the escape key to dismiss the eyedropper");
+     let onPickCanceled = waitForEvent("color-pick-canceled");
+ 
+     let keyboardEvent = win.document.createEvent("KeyboardEvent");
+     keyboardEvent.initKeyEvent("keydown", true, true, win, false, false,
+                                false, false, 27, 0);
+     win.document.dispatchEvent(keyboardEvent);
+ 
+-    yield onPickCanceled;
++    await onPickCanceled;
+     ok(true, "The color-pick-canceled event was received");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* () {
++  addAsyncTest(async function () {
+     info("Start picking a color from the page");
+-    yield inspector.pickColorFromPage();
++    await inspector.pickColorFromPage();
+ 
+     info("And cancel the color picking");
+-    yield inspector.cancelPickColorFromPage();
++    await inspector.cancelPickColorFromPage();
+ 
+     runNextTest();
+   });
+ 
+   function waitForEvent(name) {
+     return new Promise(resolve => inspector.once(name, resolve));
+   }
+ 
+diff --git a/devtools/server/tests/mochitest/test_inspector-resize.html b/devtools/server/tests/mochitest/test_inspector-resize.html
+--- a/devtools/server/tests/mochitest/test_inspector-resize.html
++++ b/devtools/server/tests/mochitest/test_inspector-resize.html
+@@ -17,49 +17,49 @@ window.onload = function () {
+   const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+   const {InspectorFront} = require("devtools/shared/fronts/inspector");
+ 
+   SimpleTest.waitForExplicitFinish();
+ 
+   let win = null;
+   let inspector = null;
+ 
+-  addAsyncTest(function* setup() {
++  addAsyncTest(async function setup() {
+     info("Setting up inspector and walker actors.");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+     // eslint-disable-next-line new-cap
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         win = doc.defaultView;
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* () {
+-    let walker = yield inspector.getWalker();
++  addAsyncTest(async function () {
++    let walker = await inspector.getWalker();
+ 
+     // We can't receive events from the walker if we haven't first executed a
+     // method on the actor to initialize it.
+-    yield walker.querySelector(walker.rootNode, "img");
++    await walker.querySelector(walker.rootNode, "img");
+ 
+     let {outerWidth, outerHeight} = win;
+     // eslint-disable-next-line new-cap
+     let onResize = new Promise(resolve => {
+       walker.once("resize", () => {
+         resolve();
+       });
+     });
+     win.resizeTo(800, 600);
+-    yield onResize;
++    await onResize;
+ 
+     ok(true, "The resize event was emitted");
+     win.resizeTo(outerWidth, outerHeight);
+ 
+     runNextTest();
+   });
+ 
+   runNextTest();
+diff --git a/devtools/server/tests/mochitest/test_inspector-scroll-into-view.html b/devtools/server/tests/mochitest/test_inspector-scroll-into-view.html
+--- a/devtools/server/tests/mochitest/test_inspector-scroll-into-view.html
++++ b/devtools/server/tests/mochitest/test_inspector-scroll-into-view.html
+@@ -29,41 +29,41 @@ addTest(function setup() {
+     let inspector = InspectorFront(client, tab);
+     promiseDone(inspector.getWalker().then(walker => {
+       ok(walker, "getWalker() should return an actor.");
+       gWalker = walker;
+     }).then(runNextTest));
+   });
+ });
+ 
+-addTest(Task.async(function* testScrollIntoView() {
++addTest(async function testScrollIntoView() {
+   let id = "#scroll-into-view";
+   let rect = gInspectee.querySelector(id).getBoundingClientRect();
+-  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, id);
++  let nodeFront = await gWalker.querySelector(gWalker.rootNode, id);
+   let inViewport = rect.x >= 0 &&
+                    rect.y >= 0 &&
+                    rect.y <= gInspectee.defaultView.innerHeight &&
+                    rect.x <= gInspectee.defaultView.innerWidth;
+ 
+   ok(!inViewport, "Element is not in viewport.");
+ 
+-  yield nodeFront.scrollIntoView();
++  await nodeFront.scrollIntoView();
+ 
+   SimpleTest.executeSoon(() => {
+     rect = gInspectee.querySelector(id).getBoundingClientRect();
+     inViewport = rect.x >= 0 &&
+                  rect.y >= 0 &&
+                  rect.y <= gInspectee.defaultView.innerHeight &&
+                  rect.x <= gInspectee.defaultView.innerWidth;
+ 
+     ok(inViewport, "Element is in viewport.");
+ 
+     runNextTest();
+   });
+-}));
++});
+ 
+ addTest(function cleanup() {
+   gWalker = null;
+   gInspectee = null;
+   runNextTest();
+ });
+   </script>
+ </head>
+diff --git a/devtools/server/tests/mochitest/test_inspector-search-front.html b/devtools/server/tests/mochitest/test_inspector-search-front.html
+--- a/devtools/server/tests/mochitest/test_inspector-search-front.html
++++ b/devtools/server/tests/mochitest/test_inspector-search-front.html
+@@ -21,153 +21,153 @@ window.onload = function () {
+   let walkerFront = null;
+   let inspector = null;
+ 
+   // WalkerFront specific tests.  These aren't to excercise search
+   // edge cases so much as to test the state the Front maintains between
+   // searches.
+   // See also test_inspector-search.html
+ 
+-  addAsyncTest(function* setup() {
++  addAsyncTest(async function setup() {
+     info("Setting up inspector and walker actors.");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+     // eslint-disable-next-line new-cap
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+-    walkerFront = yield inspector.getWalker();
++    walkerFront = await inspector.getWalker();
+     ok(walkerFront, "getWalker() should return an actor.");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testWalkerFrontDefaults() {
++  addAsyncTest(async function testWalkerFrontDefaults() {
+     info("Testing search API using WalkerFront.");
+-    let nodes = yield walkerFront.querySelectorAll(walkerFront.rootNode, "h2");
+-    let fronts = yield nodes.items();
++    let nodes = await walkerFront.querySelectorAll(walkerFront.rootNode, "h2");
++    let fronts = await nodes.items();
+ 
+-    let frontResult = yield walkerFront.search("");
++    let frontResult = await walkerFront.search("");
+     ok(!frontResult, "Null result on front when searching for ''");
+ 
+-    let results = yield walkerFront.search("h2");
++    let results = await walkerFront.search("h2");
+     isDeeply(results, {
+       node: fronts[0],
+       type: "search",
+       resultsIndex: 0,
+       resultsLength: 3
+     }, "Default options work");
+ 
+-    results = yield walkerFront.search("h2", { });
++    results = await walkerFront.search("h2", { });
+     isDeeply(results, {
+       node: fronts[1],
+       type: "search",
+       resultsIndex: 1,
+       resultsLength: 3
+     }, "Search works with empty options");
+ 
+     // Clear search data to remove result state on the front
+-    yield walkerFront.search("");
++    await walkerFront.search("");
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testMultipleSearches() {
++  addAsyncTest(async function testMultipleSearches() {
+     info("Testing search API using WalkerFront (reverse=false)");
+-    let nodes = yield walkerFront.querySelectorAll(walkerFront.rootNode, "h2");
+-    let fronts = yield nodes.items();
++    let nodes = await walkerFront.querySelectorAll(walkerFront.rootNode, "h2");
++    let fronts = await nodes.items();
+ 
+-    let results = yield walkerFront.search("h2");
++    let results = await walkerFront.search("h2");
+     isDeeply(results, {
+       node: fronts[0],
+       type: "search",
+       resultsIndex: 0,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=false)");
+ 
+-    results = yield walkerFront.search("h2");
++    results = await walkerFront.search("h2");
+     isDeeply(results, {
+       node: fronts[1],
+       type: "search",
+       resultsIndex: 1,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=false)");
+ 
+-    results = yield walkerFront.search("h2");
++    results = await walkerFront.search("h2");
+     isDeeply(results, {
+       node: fronts[2],
+       type: "search",
+       resultsIndex: 2,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=false)");
+ 
+-    results = yield walkerFront.search("h2");
++    results = await walkerFront.search("h2");
+     isDeeply(results, {
+       node: fronts[0],
+       type: "search",
+       resultsIndex: 0,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=false)");
+ 
+     // Clear search data to remove result state on the front
+-    yield walkerFront.search("");
++    await walkerFront.search("");
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testMultipleSearchesReverse() {
++  addAsyncTest(async function testMultipleSearchesReverse() {
+     info("Testing search API using WalkerFront (reverse=true)");
+-    let nodes = yield walkerFront.querySelectorAll(walkerFront.rootNode, "h2");
+-    let fronts = yield nodes.items();
++    let nodes = await walkerFront.querySelectorAll(walkerFront.rootNode, "h2");
++    let fronts = await nodes.items();
+ 
+-    let results = yield walkerFront.search("h2", {reverse: true});
++    let results = await walkerFront.search("h2", {reverse: true});
+     isDeeply(results, {
+       node: fronts[2],
+       type: "search",
+       resultsIndex: 2,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=true)");
+ 
+-    results = yield walkerFront.search("h2", {reverse: true});
++    results = await walkerFront.search("h2", {reverse: true});
+     isDeeply(results, {
+       node: fronts[1],
+       type: "search",
+       resultsIndex: 1,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=true)");
+ 
+-    results = yield walkerFront.search("h2", {reverse: true});
++    results = await walkerFront.search("h2", {reverse: true});
+     isDeeply(results, {
+       node: fronts[0],
+       type: "search",
+       resultsIndex: 0,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=true)");
+ 
+-    results = yield walkerFront.search("h2", {reverse: true});
++    results = await walkerFront.search("h2", {reverse: true});
+     isDeeply(results, {
+       node: fronts[2],
+       type: "search",
+       resultsIndex: 2,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=true)");
+ 
+-    results = yield walkerFront.search("h2", {reverse: false});
++    results = await walkerFront.search("h2", {reverse: false});
+     isDeeply(results, {
+       node: fronts[0],
+       type: "search",
+       resultsIndex: 0,
+       resultsLength: 3
+     }, "Search works with multiple results (reverse=false)");
+ 
+     // Clear search data to remove result state on the front
+-    yield walkerFront.search("");
++    await walkerFront.search("");
+     runNextTest();
+   });
+ 
+   runNextTest();
+ };
+   </script>
+ </head>
+ <body>
+diff --git a/devtools/server/tests/mochitest/test_inspector-search.html b/devtools/server/tests/mochitest/test_inspector-search.html
+--- a/devtools/server/tests/mochitest/test_inspector-search.html
++++ b/devtools/server/tests/mochitest/test_inspector-search.html
+@@ -24,57 +24,57 @@ window.onload = function () {
+   let walkerSearch = null;
+   let inspectee = null;
+   let inspector = null;
+ 
+   // WalkerSearch specific tests.  This is to make sure search results are
+   // coming back as expected.
+   // See also test_inspector-search-front.html.
+ 
+-  addAsyncTest(function* setup() {
++  addAsyncTest(async function setup() {
+     info("Setting up inspector and walker actors.");
+ 
+     let url = document.getElementById("inspectorContent").href;
+ 
+     // eslint-disable-next-line new-cap
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       attachURL(url, function (err, client, tab, doc) {
+         inspectee = doc;
+         inspector = InspectorFront(client, tab);
+         resolve();
+       });
+     });
+ 
+-    let walkerFront = yield inspector.getWalker();
++    let walkerFront = await inspector.getWalker();
+     ok(walkerFront, "getWalker() should return an actor.");
+ 
+     walkerActor = DebuggerServer.searchAllConnectionsForActor(walkerFront.actorID);
+     ok(walkerActor,
+       "Got a reference to the walker actor (" + walkerFront.actorID + ")");
+ 
+     walkerSearch = walkerActor.walkerSearch;
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testIndexExists() {
++  addAsyncTest(function testIndexExists() {
+     info("Testing basic index APIs exist.");
+ 
+     let index = new WalkerIndex(walkerActor);
+     ok(index.data.size > 0, "public index is filled after getting");
+ 
+     index.clearIndex();
+     ok(!index._data, "private index is empty after clearing");
+     ok(index.data.size > 0, "public index is filled after getting");
+ 
+     index.destroy();
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testSearchExists() {
++  addAsyncTest(function testSearchExists() {
+     info("Testing basic search APIs exist.");
+ 
+     ok(walkerSearch, "walker search exists on the WalkerActor");
+     ok(walkerSearch.search, "walker search has `search` method");
+     ok(walkerSearch.index, "walker search has `index` property");
+     is(walkerSearch.walker, walkerActor, "referencing the correct WalkerActor");
+ 
+     let search = new WalkerSearch(walkerActor);
+@@ -82,34 +82,34 @@ window.onload = function () {
+     ok(search.search, "new search instance has `search` method");
+     ok(search.index, "new search instance has `index` property");
+     isnot(search, walkerSearch, "new search instance differs from the WalkerActor's");
+ 
+     search.destroy();
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testEmptySearch() {
++  addAsyncTest(function testEmptySearch() {
+     info("Testing search with an empty query.");
+     let results = walkerSearch.search("");
+     is(results.length, 0, "No results when searching for ''");
+ 
+     results = walkerSearch.search(null);
+     is(results.length, 0, "No results when searching for null");
+ 
+     results = walkerSearch.search(undefined);
+     is(results.length, 0, "No results when searching for undefined");
+ 
+     results = walkerSearch.search(10);
+     is(results.length, 0, "No results when searching for 10");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testBasicSearchData() {
++  addAsyncTest(function testBasicSearchData() {
+     let testData = [
+     {
+       desc: "Search for tag with one result.",
+       search: "body",
+       expected: [
+         {node: inspectee.body, type: "tag"}
+       ]
+     },
+@@ -172,17 +172,17 @@ window.onload = function () {
+       let results = walkerSearch.search(search);
+       isDeeply(results, expected,
+         "Search returns correct results with '" + search + "'");
+     }
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testPseudoElements() {
++  addAsyncTest(function testPseudoElements() {
+     info("Testing ::before and ::after element matching");
+ 
+     let beforeElt = new _documentWalker(inspectee.querySelector("#pseudo"),
+                                         inspectee.defaultView).firstChild();
+     let afterElt = new _documentWalker(inspectee.querySelector("#pseudo"),
+                                        inspectee.defaultView).lastChild();
+     let styleText = inspectee.querySelector("style").childNodes[0];
+ 
+@@ -212,56 +212,56 @@ window.onload = function () {
+     isDeeply(results, [
+       {node: styleText, type: "text"},
+       {node: afterElt, type: "text"}
+     ], "Text search works for pseudo element");
+ 
+     runNextTest();
+   });
+ 
+-  addAsyncTest(function* testSearchMutationChangeResults() {
++  addAsyncTest(async function testSearchMutationChangeResults() {
+     info("Testing search before and after a mutation.");
+     let expected = [
+       {node: inspectee.querySelectorAll("h3")[0], type: "tag"},
+       {node: inspectee.querySelectorAll("h3")[1], type: "tag"},
+       {node: inspectee.querySelectorAll("h3")[2], type: "tag"},
+     ];
+ 
+     let results = walkerSearch.search("h3");
+     isDeeply(results, expected, "Search works with tag results");
+ 
+-    yield mutateDocumentAndWaitForMutation(() => {
++    await mutateDocumentAndWaitForMutation(() => {
+       expected[0].node.remove();
+     });
+ 
+     results = walkerSearch.search("h3");
+     isDeeply(results, [
+       expected[1],
+       expected[2]
+     ], "Results are updated after removal");
+ 
+     // eslint-disable-next-line new-cap
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       info("Waiting for a mutation to happen");
+       let observer = new inspectee.defaultView.MutationObserver(() => {
+         resolve();
+       });
+       observer.observe(inspectee, {attributes: true, subtree: true});
+       inspectee.body.setAttribute("h3", "true");
+     });
+ 
+     results = walkerSearch.search("h3");
+     isDeeply(results, [
+       {node: inspectee.body, type: "attributeName"},
+       expected[1],
+       expected[2]
+     ], "Results are updated after addition");
+ 
+     // eslint-disable-next-line new-cap
+-    yield new Promise(resolve => {
++    await new Promise(resolve => {
+       info("Waiting for a mutation to happen");
+       let observer = new inspectee.defaultView.MutationObserver(() => {
+         resolve();
+       });
+       observer.observe(inspectee, {attributes: true, childList: true, subtree: true});
+       inspectee.body.removeAttribute("h3");
+       expected[1].node.remove();
+       expected[2].node.remove();
+diff --git a/devtools/server/tests/mochitest/test_memory.html b/devtools/server/tests/mochitest/test_memory.html
+--- a/devtools/server/tests/mochitest/test_memory.html
++++ b/devtools/server/tests/mochitest/test_memory.html
+@@ -13,27 +13,27 @@ Bug 923275 - Add a memory monitor widget
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    let measurement = yield memory.measure();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    let measurement = await memory.measure();
+     ok(measurement.total > 0, "total memory is valid");
+     ok(measurement.domSize > 0, "domSize is valid");
+     ok(measurement.styleSize > 0, "styleSize is valid");
+     ok(measurement.jsObjectsSize > 0, "jsObjectsSize is valid");
+     ok(measurement.jsStringsSize > 0, "jsStringsSize is valid");
+     ok(measurement.jsOtherSize > 0, "jsOtherSize is valid");
+     ok(measurement.otherSize > 0, "otherSize is valid");
+     ok(measurement.jsMilliseconds, "jsMilliseconds is valid");
+     ok(measurement.nonJSMilliseconds, "nonJSMilliseconds is valid");
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_01.html b/devtools/server/tests/mochitest/test_memory_allocations_01.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_01.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_01.html
+@@ -11,16 +11,17 @@ Bug 1067491 - Test recording allocations
+ </head>
+ <body>
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
++  let { Task } = require("devtools/shared/task");
+   SimpleTest.waitForExplicitFinish();
+ 
+   Task.spawn(function* () {
+     let { memory, client } = yield startServerAndGetSelectedTabMemory();
+     yield memory.attach();
+ 
+     yield memory.startRecordingAllocations();
+     ok(true, "Can start recording allocations");
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_02.html b/devtools/server/tests/mochitest/test_memory_allocations_02.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_02.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_02.html
+@@ -13,19 +13,19 @@ Bug 1132764 - Test controlling the maxim
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+     let allocs = [];
+     let eventsFired = 0;
+     let intervalId = null;
+     function onAlloc() {
+       eventsFired++;
+     }
+     function startAllocating() {
+@@ -36,45 +36,45 @@ window.onload = function () {
+       }, 1);
+     }
+     function stopAllocating() {
+       clearInterval(intervalId);
+     }
+ 
+     memory.on("allocations", onAlloc);
+ 
+-    yield memory.startRecordingAllocations({
++    await memory.startRecordingAllocations({
+       drainAllocationsTimeout: 10
+     });
+ 
+-    yield waitUntil(() => eventsFired > 5);
++    await waitUntil(() => eventsFired > 5);
+     ok(eventsFired > 5,
+        "Some allocation events fired without allocating much via auto drain");
+-    yield memory.stopRecordingAllocations();
++    await memory.stopRecordingAllocations();
+ 
+     // Set a really high auto drain timer so we can test if
+     // it fires on GC
+     eventsFired = 0;
+     let startTime = performance.now();
+     let drainTimer = 1000000;
+-    yield memory.startRecordingAllocations({
++    await memory.startRecordingAllocations({
+       drainAllocationsTimeout: drainTimer
+     });
+ 
+     startAllocating();
+-    yield waitUntil(() => {
++    await waitUntil(() => {
+       Cu.forceGC();
+       return eventsFired > 1;
+     });
+     stopAllocating();
+     ok(performance.now() - drainTimer < startTime,
+        "Allocation events fired on GC before timer");
+-    yield memory.stopRecordingAllocations();
++    await memory.stopRecordingAllocations();
+ 
+     memory.off("allocations", onAlloc);
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_03.html b/devtools/server/tests/mochitest/test_memory_allocations_03.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_03.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_03.html
+@@ -13,40 +13,40 @@ Bug 1067491 - Test that frames keep the 
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+-    yield memory.startRecordingAllocations();
++    await memory.startRecordingAllocations();
+ 
+     // Allocate twice with the exact same stack (hence setTimeout rather than
+     // allocating directly in the generator), but with getAllocations() calls in
+     // between.
+ 
+     let allocs = [];
+     function allocator() {
+       allocs.push({});
+     }
+ 
+     setTimeout(allocator, 1);
+-    yield waitForTime(2);
+-    let first = yield memory.getAllocations();
++    await waitForTime(2);
++    let first = await memory.getAllocations();
+ 
+     setTimeout(allocator, 1);
+-    yield waitForTime(2);
+-    let second = yield memory.getAllocations();
++    await waitForTime(2);
++    let second = await memory.getAllocations();
+ 
+-    yield memory.stopRecordingAllocations();
++    await memory.stopRecordingAllocations();
+ 
+     // Assert that each frame in the first response has the same index in the
+     // second response. This isn't commutative, so we don't check that all
+     // of the second response's frames are the same in the first response,
+     // because there might be new allocations that happen after the first query
+     // but before the second.
+ 
+     function assertSameFrame(a, b) {
+@@ -65,16 +65,16 @@ window.onload = function () {
+       is(a.parent, b.parent);
+     }
+ 
+     for (let i = 0; i < first.frames.length; i++) {
+       info("Checking frames at index " + i + ":");
+       assertSameFrame(first.frames[i], second.frames[i]);
+     }
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_04.html b/devtools/server/tests/mochitest/test_memory_allocations_04.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_04.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_04.html
+@@ -13,50 +13,50 @@ Bug 1068171 - Test controlling the memor
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+     let allocs = [];
+     function allocator() {
+       for (let i = 0; i < 100; i++) {
+         allocs.push({});
+       }
+     }
+ 
+-    let testProbability = Task.async(function* (p, expected) {
++    let testProbability = async function (p, expected) {
+       info("probability = " + p);
+-      yield memory.startRecordingAllocations({
++      await memory.startRecordingAllocations({
+         probability: p
+       });
+       allocator();
+-      let response = yield memory.getAllocations();
+-      yield memory.stopRecordingAllocations();
++      let response = await memory.getAllocations();
++      await memory.stopRecordingAllocations();
+       return response.allocations.length;
+-    });
++    };
+ 
+-    is((yield testProbability(0.0)), 0,
++    is((await testProbability(0.0)), 0,
+        "With probability = 0.0, we shouldn't get any allocations.");
+ 
+-    ok((yield testProbability(1.0)) >= 100,
++    ok((await testProbability(1.0)) >= 100,
+        "With probability = 1.0, we should get all 100 allocations (plus "
+        + "whatever allocations the actor and SpiderMonkey make).");
+ 
+     // We don't test any other probabilities because the test would be
+     // non-deterministic. We don't have a way to control the PRNG like we do in
+     // jit-tests
+     // (js/src/jit-test/tests/debug/Memory-allocationsSamplingProbability-*.js).
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_05.html b/devtools/server/tests/mochitest/test_memory_allocations_05.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_05.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_05.html
+@@ -13,44 +13,44 @@ Bug 1068144 - Test getting the timestamp
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+     let allocs = [];
+     function allocator() {
+       allocs.push(new Object());
+     }
+ 
+     // Using setTimeout results in wildly varying delays that make it hard to
+     // test our timestamps and results in intermittent failures. Instead, we
+     // actually spin an empty loop for a whole millisecond.
+     function actuallyWaitOneWholeMillisecond() {
+       let start = window.performance.now();
+       // eslint-disable-next-line curly
+       while (window.performance.now() - start < 1.000);
+     }
+ 
+-    yield memory.startRecordingAllocations();
++    await memory.startRecordingAllocations();
+ 
+     allocator();
+     actuallyWaitOneWholeMillisecond();
+     allocator();
+     actuallyWaitOneWholeMillisecond();
+     allocator();
+ 
+-    let response = yield memory.getAllocations();
+-    yield memory.stopRecordingAllocations();
++    let response = await memory.getAllocations();
++    await memory.stopRecordingAllocations();
+ 
+     ok(response.allocationsTimestamps, "The response should have timestamps.");
+     is(response.allocationsTimestamps.length, response.allocations.length,
+        "There should be a timestamp for every allocation.");
+ 
+     let allocatorIndices = response.allocations
+       .map(function (a, idx) {
+         let frame = response.frames[a];
+@@ -78,16 +78,16 @@ window.onload = function () {
+         // ms
+         ok(delta >= 1,
+            "The timestamp should be about 1 ms after the last timestamp.");
+       }
+ 
+       lastTimestamp = timestamp;
+     }
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_06.html b/devtools/server/tests/mochitest/test_memory_allocations_06.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_06.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_06.html
+@@ -13,39 +13,39 @@ Bug 1132764 - Test controlling the maxim
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+     let allocs = [];
+     function allocator() {
+       allocs.push(new Object());
+     }
+ 
+-    yield memory.startRecordingAllocations({
++    await memory.startRecordingAllocations({
+       maxLogLength: 1
+     });
+ 
+     allocator();
+     allocator();
+     allocator();
+ 
+-    let response = yield memory.getAllocations();
+-    yield memory.stopRecordingAllocations();
++    let response = await memory.getAllocations();
++    await memory.stopRecordingAllocations();
+ 
+     is(response.allocations.length, 1,
+        "There should only be one entry in the allocations log.");
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_allocations_07.html b/devtools/server/tests/mochitest/test_memory_allocations_07.html
+--- a/devtools/server/tests/mochitest/test_memory_allocations_07.html
++++ b/devtools/server/tests/mochitest/test_memory_allocations_07.html
+@@ -13,45 +13,45 @@ Bug 1192335 - Test getting the byte size
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+     let allocs = [];
+     function allocator() {
+       allocs.push(new Object());
+     }
+ 
+-    yield memory.startRecordingAllocations();
++    await memory.startRecordingAllocations();
+ 
+     allocator();
+     allocator();
+     allocator();
+ 
+-    let response = yield memory.getAllocations();
+-    yield memory.stopRecordingAllocations();
++    let response = await memory.getAllocations();
++    await memory.stopRecordingAllocations();
+ 
+     ok(response.allocationSizes, "The response should have bytesizes.");
+     is(response.allocationSizes.length, response.allocations.length,
+        "There should be a bytesize for every allocation.");
+     ok(response.allocationSizes.length >= 3,
+        "There are atleast 3 allocations.");
+     ok(response.allocationSizes.every(isPositiveNumber),
+        "every bytesize is a positive number");
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ 
+ function isPositiveNumber(n) {
+   return typeof n === "number" && n > 0;
+ }
+ </script>
+ </pre>
+ </body>
+diff --git a/devtools/server/tests/mochitest/test_memory_attach_01.html b/devtools/server/tests/mochitest/test_memory_attach_01.html
+--- a/devtools/server/tests/mochitest/test_memory_attach_01.html
++++ b/devtools/server/tests/mochitest/test_memory_attach_01.html
+@@ -13,21 +13,21 @@ Bug 960671 - Test attaching and detachin
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+     ok(true, "Shouldn't have gotten an error attaching.");
+-    yield memory.detach();
++    await memory.detach();
+     ok(true, "Shouldn't have gotten an error detaching.");
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_attach_02.html b/devtools/server/tests/mochitest/test_memory_attach_02.html
+--- a/devtools/server/tests/mochitest/test_memory_attach_02.html
++++ b/devtools/server/tests/mochitest/test_memory_attach_02.html
+@@ -13,37 +13,37 @@ Bug 960671 - Test attaching and detachin
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
+ 
+     let e = null;
+     try {
+-      yield memory.detach();
++      await memory.detach();
+     } catch (ee) {
+       e = ee;
+     }
+     ok(e, "Should have hit the wrongState error");
+ 
+-    yield memory.attach();
++    await memory.attach();
+ 
+     e = null;
+     try {
+-      yield memory.attach();
++      await memory.attach();
+     } catch (ee) {
+       e = ee;
+     }
+     ok(e, "Should have hit the wrongState error");
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_census.html b/devtools/server/tests/mochitest/test_memory_census.html
+--- a/devtools/server/tests/mochitest/test_memory_census.html
++++ b/devtools/server/tests/mochitest/test_memory_census.html
+@@ -13,23 +13,23 @@ Bug 1067491 - Test taking a census over 
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+-    let census = yield memory.takeCensus();
++    let census = await memory.takeCensus();
+     is(typeof census, "object");
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_gc_01.html b/devtools/server/tests/mochitest/test_memory_gc_01.html
+--- a/devtools/server/tests/mochitest/test_memory_gc_01.html
++++ b/devtools/server/tests/mochitest/test_memory_gc_01.html
+@@ -13,38 +13,38 @@ Bug 1067491 - Test forcing a gc.
+ <pre id="test">
+ <script src="memory-helpers.js" type="application/javascript"></script>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
+ 
+     let beforeGC, afterGC;
+ 
+     do {
+       let objects = [];
+       for (let i = 0; i < 1000; i++) {
+         let o = {};
+         o[Math.random()] = 1;
+         objects.push(o);
+       }
+       objects = null;
+ 
+-      yield { total: beforeGC } = memory.measure();
++      beforeGC = (await memory.measure()).total;
+ 
+-      yield memory.forceGarbageCollection();
++      await memory.forceGarbageCollection();
+ 
+-      yield { total: afterGC } = memory.measure();
++      afterGC = (await memory.measure()).total;
+     } while (beforeGC < afterGC);
+ 
+     ok(true, "The amount of memory after GC should eventually decrease");
+ 
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_memory_gc_events.html b/devtools/server/tests/mochitest/test_memory_gc_events.html
+--- a/devtools/server/tests/mochitest/test_memory_gc_events.html
++++ b/devtools/server/tests/mochitest/test_memory_gc_events.html
+@@ -15,30 +15,30 @@ Bug 1137527 - Test receiving GC events f
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+ 
+   let EventEmitter = require("devtools/shared/event-emitter");
+ 
+-  Task.spawn(function* () {
+-    let { memory, client } = yield startServerAndGetSelectedTabMemory();
+-    yield memory.attach();
++  (async function () {
++    let { memory, client } = await startServerAndGetSelectedTabMemory();
++    await memory.attach();
+ 
+     let gotGcEvent = new Promise(resolve => {
+       EventEmitter.on(memory, "garbage-collection", gcData => {
+         ok(gcData, "Got GC data");
+         resolve();
+       });
+     });
+ 
+     memory.forceGarbageCollection();
+-    yield gotGcEvent;
++    await gotGcEvent;
+ 
+-    yield memory.detach();
++    await memory.detach();
+     destroyServerAndFinish(client);
+-  });
++  })();
+ };
+ </script>
+ </pre>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/test_styles-layout.html b/devtools/server/tests/mochitest/test_styles-layout.html
+--- a/devtools/server/tests/mochitest/test_styles-layout.html
++++ b/devtools/server/tests/mochitest/test_styles-layout.html
+@@ -32,37 +32,37 @@ addTest(function () {
+   });
+ });
+ 
+ addTest(function () {
+   ok(gStyles.getLayout, "The PageStyleActor has a getLayout method");
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
+-  let node = yield gWalker.querySelector(gWalker.rootNode, "#layout-element");
+-  let layout = yield gStyles.getLayout(node, {});
++addAsyncTest(async function () {
++  let node = await gWalker.querySelector(gWalker.rootNode, "#layout-element");
++  let layout = await gStyles.getLayout(node, {});
+ 
+   let properties = ["width", "height",
+                     "margin-top", "margin-right", "margin-bottom",
+                     "margin-left", "padding-top", "padding-right",
+                     "padding-bottom", "padding-left", "border-top-width",
+                     "border-right-width", "border-bottom-width",
+                     "border-left-width", "z-index", "box-sizing", "display",
+                     "position"];
+   for (let prop of properties) {
+     ok((prop in layout), "The layout object returned has " + prop);
+   }
+ 
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
+-  let node = yield gWalker.querySelector(gWalker.rootNode, "#layout-element");
+-  let layout = yield gStyles.getLayout(node, {});
++addAsyncTest(async function () {
++  let node = await gWalker.querySelector(gWalker.rootNode, "#layout-element");
++  let layout = await gStyles.getLayout(node, {});
+ 
+   let expected = {
+     "box-sizing": "border-box",
+     "position": "absolute",
+     "z-index": "2",
+     "display": "block",
+     "width": 50,
+     "height": 50,
+@@ -74,25 +74,25 @@ addAsyncTest(function* () {
+ 
+   for (let name in expected) {
+     is(layout[name], expected[name], "The " + name + " property is correct");
+   }
+ 
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* () {
+-  let node = yield gWalker.querySelector(gWalker.rootNode,
++addAsyncTest(async function () {
++  let node = await gWalker.querySelector(gWalker.rootNode,
+                                          "#layout-auto-margin-element");
+ 
+-  let layout = yield gStyles.getLayout(node, {});
++  let layout = await gStyles.getLayout(node, {});
+   ok(!("autoMargins" in layout),
+      "By default, getLayout doesn't return auto margins");
+ 
+-  layout = yield gStyles.getLayout(node, {autoMargins: true});
++  layout = await gStyles.getLayout(node, {autoMargins: true});
+   ok(("autoMargins" in layout),
+      "getLayout does return auto margins when asked to");
+   is(layout.autoMargins.left, "auto", "The left margin is auto");
+   is(layout.autoMargins.right, "auto", "The right margin is auto");
+   ok(!layout.autoMargins.bottom, "The bottom margin is not auto");
+   ok(!layout.autoMargins.top, "The top margin is not auto");
+ 
+   runNextTest();
+diff --git a/devtools/server/tests/mochitest/test_styles-modify.html b/devtools/server/tests/mochitest/test_styles-modify.html
+--- a/devtools/server/tests/mochitest/test_styles-modify.html
++++ b/devtools/server/tests/mochitest/test_styles-modify.html
+@@ -19,84 +19,84 @@ window.onload = function () {
+   SimpleTest.waitForExplicitFinish();
+   runNextTest();
+ };
+ 
+ var gWalker = null;
+ var gStyles = null;
+ var gInspectee = null;
+ 
+-addAsyncTest(function* setup() {
++addAsyncTest(async function setup() {
+   let url = document.getElementById("inspectorContent").href;
+   let inspector;
+ 
+-  yield new Promise(resolve => {
++  await new Promise(resolve => {
+     attachURL(url, function (err, client, tab, doc) {
+       gInspectee = doc;
+       let {InspectorFront} = require("devtools/shared/fronts/inspector");
+       inspector = InspectorFront(client, tab);
+       resolve();
+     });
+   });
+ 
+-  gWalker = yield inspector.getWalker();
+-  gStyles = yield inspector.getPageStyle();
++  gWalker = await inspector.getWalker();
++  gStyles = await inspector.getPageStyle();
+ 
+   runNextTest();
+ });
+ 
+-addAsyncTest(function* modifyProperties() {
++addAsyncTest(async function modifyProperties() {
+   let localNode = gInspectee.querySelector("#inheritable-rule-inheritable-style");
+ 
+-  let node = yield gWalker.querySelector(gWalker.rootNode,
++  let node = await gWalker.querySelector(gWalker.rootNode,
+     "#inheritable-rule-inheritable-style");
+ 
+-  let applied = yield gStyles.getApplied(node,
++  let applied = await gStyles.getApplied(node,
+     { inherited: false, filter: "user" });
+ 
+   let elementStyle = applied[0].rule;
+   is(elementStyle.cssText, localNode.style.cssText, "Got expected css text");
+ 
+   // Change an existing property...
+-  yield setProperty(elementStyle, 0, "color", "black");
++  await setProperty(elementStyle, 0, "color", "black");
+   // Create a new property
+-  yield setProperty(elementStyle, 1, "background-color", "green");
++  await setProperty(elementStyle, 1, "background-color", "green");
+ 
+   // Create a new property and then change it immediately.
+-  yield setProperty(elementStyle, 2, "border", "1px solid black");
+-  yield setProperty(elementStyle, 2, "border", "2px solid black");
++  await setProperty(elementStyle, 2, "border", "1px solid black");
++  await setProperty(elementStyle, 2, "border", "2px solid black");
+ 
+   is(elementStyle.cssText,
+      "color: black; background-color: green; border: 2px solid black;",
+      "Should have expected cssText");
+   is(elementStyle.cssText, localNode.style.cssText,
+      "Local node and style front match.");
+ 
+   // Remove all the properties
+-  yield removeProperty(elementStyle, 0, "color");
+-  yield removeProperty(elementStyle, 0, "background-color");
+-  yield removeProperty(elementStyle, 0, "border");
++  await removeProperty(elementStyle, 0, "color");
++  await removeProperty(elementStyle, 0, "background-color");
++  await removeProperty(elementStyle, 0, "border");
+ 
+   is(elementStyle.cssText, "", "Should have expected cssText");
+   is(elementStyle.cssText, localNode.style.cssText,
+      "Local node and style front match.");
+ 
+   runNextTest();
+ });
+ 
+-function* setProperty(rule, index, name, value) {
++async function setProperty(rule, index, name, value) {
+   let changes = rule.startModifyingProperties(isCssPropertyKnown);
+   changes.setProperty(index, name, value);
+-  yield changes.apply();
++  await changes.apply();
+ }
+ 
+-function* removeProperty(rule, index, name) {
++async function removeProperty(rule, index, name) {
+   let changes = rule.startModifyingProperties(isCssPropertyKnown);
+   changes.removeProperty(index, name);
+-  yield changes.apply();
++  await changes.apply();
+ }
+ 
+ addTest(function cleanup() {
+   gStyles = null;
+   gWalker = null;
+   gInspectee = null;
+   runNextTest();
+ });
+diff --git a/devtools/server/tests/mochitest/test_websocket-server.html b/devtools/server/tests/mochitest/test_websocket-server.html
+--- a/devtools/server/tests/mochitest/test_websocket-server.html
++++ b/devtools/server/tests/mochitest/test_websocket-server.html
+@@ -9,76 +9,75 @@
+ </head>
+ <body>
+ <script>
+ "use strict";
+ 
+ window.onload = function () {
+   const CC = Components.Constructor;
+   const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+-  const { Task } = require("devtools/shared/task");
+   const WebSocketServer = require("devtools/server/websocket-server");
+ 
+   const ServerSocket = CC("@mozilla.org/network/server-socket;1",
+     "nsIServerSocket", "init");
+ 
+-  add_task(function* () {
++  add_task(async function () {
+     // Create a TCP server on auto-assigned port
+     let server = new ServerSocket(-1, true, -1);
+     ok(server, `Launched WebSocket server on port ${server.port}`);
+     server.asyncListen({
+-      onSocketAccepted: Task.async(function* (socket, transport) {
++      async onSocketAccepted(socket, transport) {
+         info("Accepted incoming connection");
+         let input = transport.openInputStream(0, 0, 0);
+         let output = transport.openOutputStream(0, 0, 0);
+ 
+         // Perform the WebSocket handshake
+-        let webSocket = yield WebSocketServer.accept(transport, input, output);
++        let webSocket = await WebSocketServer.accept(transport, input, output);
+ 
+         // Echo the received message back to the sender
+         webSocket.onmessage = ({ data }) => {
+           info("Server received message, echoing back");
+           webSocket.send(data);
+         };
+-      }),
++      },
+ 
+       onStopListening(socket, status) {
+         info(`Server stopped listening with status: ${status}`);
+       }
+     });
+ 
+     SimpleTest.registerCleanupFunction(() => {
+       server.close();
+     });
+ 
+     // Create client connection
+-    let client = yield new Promise((resolve, reject) => {
++    let client = await new Promise((resolve, reject) => {
+       let socket = new WebSocket(`ws://localhost:${server.port}`);
+       socket.onopen = () => resolve(socket);
+       socket.onerror = reject;
+     });
+     ok(client, `Created WebSocket connection to port ${server.port}`);
+ 
+     // Create a promise that resolves when the WebSocket closes
+     let closed = new Promise(resolve => {
+       client.onclose = resolve;
+     });
+ 
+     // Send a message
+     let message = "hello there";
+     client.send(message);
+     info("Sent a message to server");
+     // Check that it was echoed
+-    let echoedMessage = yield new Promise((resolve, reject) => {
++    let echoedMessage = await new Promise((resolve, reject) => {
+       client.onmessage = ({ data }) => resolve(data);
+       client.onerror = reject;
+     });
+ 
+     is(echoedMessage, message, "Echoed message matches");
+ 
+     // Close the connection
+     client.close();
+-    yield closed;
++    await closed;
+   });
+ };
+ </script>
+ </body>
+ </html>
+diff --git a/devtools/server/tests/mochitest/webconsole-helpers.js b/devtools/server/tests/mochitest/webconsole-helpers.js
+--- a/devtools/server/tests/mochitest/webconsole-helpers.js
++++ b/devtools/server/tests/mochitest/webconsole-helpers.js
+@@ -33,19 +33,19 @@ if (!DebuggerServer.initialized) {
+  *           - consoleClient: the console client
+  *           - cleanup: a generator function which can be called to close
+  *             the opened tab and disconnect its debugger client.
+  */
+ async function attachURL(url) {
+   let win = window.open(url, "_blank");
+   let client = null;
+ 
+-  let cleanup = function* () {
++  let cleanup = async function () {
+     if (client) {
+-      yield client.close();
++      await client.close();
+       client = null;
+     }
+     if (win) {
+       win.close();
+       win = null;
+     }
+   };
+   SimpleTest.registerCleanupFunction(cleanup);
+diff --git a/devtools/server/tests/unit/head_dbg.js b/devtools/server/tests/unit/head_dbg.js
+--- a/devtools/server/tests/unit/head_dbg.js
++++ b/devtools/server/tests/unit/head_dbg.js
+@@ -16,17 +16,16 @@ ChromeUtils.import("resource://testing-c
+   version: "1",
+   platformVersion: "42",
+   crashReporter: true,
+ });
+ 
+ const { require, loader } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
+ const { worker } = ChromeUtils.import("resource://devtools/shared/worker/loader.js", {});
+ const defer = require("devtools/shared/defer");
+-const { Task } = require("devtools/shared/task");
+ const { console } = require("resource://gre/modules/Console.jsm");
+ const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
+ 
+ const Services = require("Services");
+ // Always log packets when running tests. runxpcshelltests.py will throw
+ // the output away anyway, unless you give it the --verbose flag.
+ Services.prefs.setBoolPref("devtools.debugger.log", true);
+ // Enable remote debugging for the relevant tests.
+@@ -87,29 +86,29 @@ function makeMemoryActorTest(testGenerat
+       });
+ 
+       getTestTab(client, TEST_GLOBAL_NAME, function (tabForm, rootForm) {
+         if (!tabForm || !rootForm) {
+           ok(false, "Could not attach to test tab: " + TEST_GLOBAL_NAME);
+           return;
+         }
+ 
+-        Task.spawn(function* () {
++        (async function () {
+           try {
+             const memoryFront = new MemoryFront(client, tabForm, rootForm);
+-            yield memoryFront.attach();
+-            yield* testGeneratorFunction(client, memoryFront);
+-            yield memoryFront.detach();
++            await memoryFront.attach();
++            await testGeneratorFunction(client, memoryFront);
++            await memoryFront.detach();
+           } catch (err) {
+             DevToolsUtils.reportException("makeMemoryActorTest", err);
+             ok(false, "Got an error: " + err);
+           }
+ 
+           finishClient(client);
+-        });
++        })();
+       });
+     });
+   };
+ }
+ 
+ /**
+  * Save as makeMemoryActorTest but attaches the MemoryFront to the MemoryActor
+  * scoped to the full runtime rather than to a tab.
+@@ -125,30 +124,30 @@ function makeFullRuntimeMemoryActorTest(
+       });
+ 
+       getChromeActors(client).then(function (form) {
+         if (!form) {
+           ok(false, "Could not attach to chrome actors");
+           return;
+         }
+ 
+-        Task.spawn(function* () {
++        (async function () {
+           try {
+-            const rootForm = yield listTabs(client);
++            const rootForm = await listTabs(client);
+             const memoryFront = new MemoryFront(client, form, rootForm);
+-            yield memoryFront.attach();
+-            yield* testGeneratorFunction(client, memoryFront);
+-            yield memoryFront.detach();
++            await memoryFront.attach();
++            await testGeneratorFunction(client, memoryFront);
++            await memoryFront.detach();
+           } catch (err) {
+             DevToolsUtils.reportException("makeMemoryActorTest", err);
+             ok(false, "Got an error: " + err);
+           }
+ 
+           finishClient(client);
+-        });
++        })();
+       });
+     });
+   };
+ }
+ 
+ function createTestGlobal(name) {
+   let sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"]
+                            .createInstance(Ci.nsIPrincipal));
+diff --git a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js
+--- a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js
++++ b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_01.js
+@@ -3,16 +3,16 @@
+ 
+ "use strict";
+ 
+ // Test that we can tell the memory actor to take a heap snapshot over the RDP
+ // and then create a HeapSnapshot instance from the resulting file.
+ 
+ const { OS } = require("resource://gre/modules/osfile.jsm");
+ 
+-const run_test = makeMemoryActorTest(function* (client, memoryFront) {
+-  const snapshotFilePath = yield memoryFront.saveHeapSnapshot();
+-  ok(!!(yield OS.File.stat(snapshotFilePath)),
++const run_test = makeMemoryActorTest(async function (client, memoryFront) {
++  const snapshotFilePath = await memoryFront.saveHeapSnapshot();
++  ok(!!(await OS.File.stat(snapshotFilePath)),
+      "Should have the heap snapshot file");
+   const snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
+   ok(snapshot instanceof HeapSnapshot,
+      "And we should be able to read a HeapSnapshot instance from the file");
+ });
+diff --git a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js
+--- a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js
++++ b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_02.js
+@@ -3,18 +3,18 @@
+ 
+ "use strict";
+ 
+ // Test that we can properly stream heap snapshot files over the RDP as bulk
+ // data.
+ 
+ const { OS } = require("resource://gre/modules/osfile.jsm");
+ 
+-const run_test = makeMemoryActorTest(function* (client, memoryFront) {
+-  const snapshotFilePath = yield memoryFront.saveHeapSnapshot({
++const run_test = makeMemoryActorTest(async function (client, memoryFront) {
++  const snapshotFilePath = await memoryFront.saveHeapSnapshot({
+     forceCopy: true
+   });
+-  ok(!!(yield OS.File.stat(snapshotFilePath)),
++  ok(!!(await OS.File.stat(snapshotFilePath)),
+      "Should have the heap snapshot file");
+   const snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
+   ok(snapshot instanceof HeapSnapshot,
+      "And we should be able to read a HeapSnapshot instance from the file");
+ });
+diff --git a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js
+--- a/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js
++++ b/devtools/server/tests/unit/test_MemoryActor_saveHeapSnapshot_03.js
+@@ -3,16 +3,16 @@
+ 
+ "use strict";
+ 
+ // Test that we can save full runtime heap snapshots when attached to the
+ // ChromeActor or a ChildProcessActor.
+ 
+ const { OS } = require("resource://gre/modules/osfile.jsm");
+ 
+-const run_test = makeFullRuntimeMemoryActorTest(function* (client, memoryFront) {
+-  const snapshotFilePath = yield memoryFront.saveHeapSnapshot();
+-  ok(!!(yield OS.File.stat(snapshotFilePath)),
++const run_test = makeFullRuntimeMemoryActorTest(async function (client, memoryFront) {
++  const snapshotFilePath = await memoryFront.saveHeapSnapshot();
++  ok(!!(await OS.File.stat(snapshotFilePath)),
+      "Should have the heap snapshot file");
+   const snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
+   ok(snapshot instanceof HeapSnapshot,
+      "And we should be able to read a HeapSnapshot instance from the file");
+ });
+diff --git a/devtools/server/tests/unit/test_addon_reload.js b/devtools/server/tests/unit/test_addon_reload.js
+--- a/devtools/server/tests/unit/test_addon_reload.js
++++ b/devtools/server/tests/unit/test_addon_reload.js
+@@ -29,18 +29,18 @@ function promiseWebExtensionStartup() {
+       Management.off("ready", listener);
+       resolve(extension);
+     };
+ 
+     Management.on("ready", listener);
+   });
+ }
+ 
+-function* findAddonInRootList(client, addonId) {
+-  const result = yield client.listAddons();
++async function findAddonInRootList(client, addonId) {
++  const result = await client.listAddons();
+   const addonActor = result.addons.filter(addon => addon.id === addonId)[0];
+   ok(addonActor, `Found add-on actor for ${addonId}`);
+   return addonActor;
+ }
+ 
+ async function reloadAddon(client, addonActor) {
+   // The add-on will be re-installed after a successful reload.
+   const onInstalled = promiseAddonEvent("onInstalled");
+@@ -48,75 +48,75 @@ async function reloadAddon(client, addon
+   await onInstalled;
+ }
+ 
+ function getSupportFile(path) {
+   const allowMissing = false;
+   return do_get_file(path, allowMissing);
+ }
+ 
+-add_task(function* testReloadExitedAddon() {
+-  const client = yield new Promise(resolve => {
++add_task(async function testReloadExitedAddon() {
++  const client = await new Promise(resolve => {
+     get_chrome_actors(client => resolve(client));
+   });
+ 
+   // Install our main add-on to trigger reloads on.
+   const addonFile = getSupportFile("addons/web-extension");
+-  const [installedAddon] = yield Promise.all([
++  const [installedAddon] = await Promise.all([
+     AddonManager.installTemporaryAddon(addonFile),
+     promiseWebExtensionStartup(),
+   ]);
+ 
+   // Install a decoy add-on.
+   const addonFile2 = getSupportFile("addons/web-extension2");
+-  const [installedAddon2] = yield Promise.all([
++  const [installedAddon2] = await Promise.all([
+     AddonManager.installTemporaryAddon(addonFile2),
+     promiseWebExtensionStartup(),
+   ]);
+ 
+-  let addonActor = yield findAddonInRootList(client, installedAddon.id);
++  let addonActor = await findAddonInRootList(client, installedAddon.id);
+ 
+-  yield Promise.all([
++  await Promise.all([
+     reloadAddon(client, addonActor),
+     promiseWebExtensionStartup(),
+   ]);
+ 
+   // Uninstall the decoy add-on, which should cause its actor to exit.
+   const onUninstalled = promiseAddonEvent("onUninstalled");
+   installedAddon2.uninstall();
+-  yield onUninstalled;
++  await onUninstalled;
+ 
+   // Try to re-list all add-ons after a reload.
+   // This was throwing an exception because of the exited actor.
+-  const newAddonActor = yield findAddonInRootList(client, installedAddon.id);
++  const newAddonActor = await findAddonInRootList(client, installedAddon.id);
+   equal(newAddonActor.id, addonActor.id);
+ 
+   // The actor id should be the same after the reload
+   equal(newAddonActor.actor, addonActor.actor);
+ 
+   const onAddonListChanged = new Promise((resolve) => {
+     client.addListener("addonListChanged", function listener() {
+       client.removeListener("addonListChanged", listener);
+       resolve();
+     });
+   });
+ 
+   // Install an upgrade version of the first add-on.
+   const addonUpgradeFile = getSupportFile("addons/web-extension-upgrade");
+-  const [upgradedAddon] = yield Promise.all([
++  const [upgradedAddon] = await Promise.all([
+     AddonManager.installTemporaryAddon(addonUpgradeFile),
+     promiseWebExtensionStartup(),
+   ]);
+ 
+   // Waiting for addonListChanged unsolicited event
+-  yield onAddonListChanged;
++  await onAddonListChanged;
+ 
+   // re-list all add-ons after an upgrade.
+-  const upgradedAddonActor = yield findAddonInRootList(client, upgradedAddon.id);
++  const upgradedAddonActor = await findAddonInRootList(client, upgradedAddon.id);
+   equal(upgradedAddonActor.id, addonActor.id);
+   // The actor id should be the same after the upgrade.
+   equal(upgradedAddonActor.actor, addonActor.actor);
+ 
+   // The addon metadata has been updated.
+   equal(upgradedAddonActor.name, "Test Addons Actor Upgrade");
+ 
+-  yield close(client);
++  await close(client);
+ });
+diff --git a/devtools/server/tests/unit/test_addons_actor.js b/devtools/server/tests/unit/test_addons_actor.js
+--- a/devtools/server/tests/unit/test_addons_actor.js
++++ b/devtools/server/tests/unit/test_addons_actor.js
+@@ -3,50 +3,50 @@
+ /* eslint-disable no-shadow */
+ 
+ "use strict";
+ 
+ const {AddonsFront} = require("devtools/shared/fronts/addons");
+ 
+ startupAddonsManager();
+ 
+-function* connect() {
+-  const client = yield new Promise(resolve => {
++async function connect() {
++  const client = await new Promise(resolve => {
+     get_chrome_actors(client => resolve(client));
+   });
+-  const root = yield listTabs(client);
++  const root = await listTabs(client);
+   const addonsActor = root.addonsActor;
+   ok(addonsActor, "Got AddonsActor instance");
+ 
+   const addons = AddonsFront(client, {addonsActor});
+   return [client, addons];
+ }
+ 
+-add_task(function* testSuccessfulInstall() {
+-  const [client, addons] = yield connect();
++add_task(async function testSuccessfulInstall() {
++  const [client, addons] = await connect();
+ 
+   const allowMissing = false;
+   const usePlatformSeparator = true;
+   const addonPath = getFilePath("addons/web-extension",
+                                 allowMissing, usePlatformSeparator);
+-  const installedAddon = yield addons.installTemporaryAddon(addonPath);
++  const installedAddon = await addons.installTemporaryAddon(addonPath);
+   equal(installedAddon.id, "test-addons-actor@mozilla.org");
+   // The returned object is currently not a proper actor.
+   equal(installedAddon.actor, false);
+ 
+-  const addonList = yield client.listAddons();
++  const addonList = await client.listAddons();
+   ok(addonList && addonList.addons && addonList.addons.map(a => a.name),
+      "Received list of add-ons");
+   const addon = addonList.addons.filter(a => a.id === installedAddon.id)[0];
+   ok(addon, "Test add-on appeared in root install list");
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-add_task(function* testNonExistantPath() {
+-  const [client, addons] = yield connect();
++add_task(async function testNonExistantPath() {
++  const [client, addons] = await connect();
+ 
+-  yield Assert.rejects(
++  await Assert.rejects(
+     addons.installTemporaryAddon("some-non-existant-path"),
+     /Could not install add-on.*Component returned failure/);
+ 
+-  yield close(client);
++  await close(client);
+ });
+diff --git a/devtools/server/tests/unit/test_blackboxing-01.js b/devtools/server/tests/unit/test_blackboxing-01.js
+--- a/devtools/server/tests/unit/test_blackboxing-01.js
++++ b/devtools/server/tests/unit/test_blackboxing-01.js
+@@ -23,79 +23,79 @@ function run_test() {
+                            });
+   });
+   do_test_pending();
+ }
+ 
+ const BLACK_BOXED_URL = "http://example.com/blackboxme.js";
+ const SOURCE_URL = "http://example.com/source.js";
+ 
+-const testBlackBox = Task.async(function* () {
+-  let packet = yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++const testBlackBox = async function () {
++  let packet = await executeOnNextTickAndWaitForPause(evalCode, gClient);
+   let source = gThreadClient.source(packet.frame.where.source);
+ 
+-  yield setBreakpoint(source, {
++  await setBreakpoint(source, {
+     line: 2
+   });
+-  yield resume(gThreadClient);
++  await resume(gThreadClient);
+ 
+-  const { sources } = yield getSources(gThreadClient);
++  const { sources } = await getSources(gThreadClient);
+   let sourceClient = gThreadClient.source(
+     sources.filter(s => s.url == BLACK_BOXED_URL)[0]);
+   Assert.ok(!sourceClient.isBlackBoxed,
+             "By default the source is not black boxed.");
+ 
+   // Test that we can step into `doStuff` when we are not black boxed.
+-  yield runTest(
++  await runTest(
+     function onSteppedLocation(location) {
+       Assert.equal(location.source.url, BLACK_BOXED_URL);
+       Assert.equal(location.line, 2);
+     },
+     function onDebuggerStatementFrames(frames) {
+       Assert.ok(!frames.some(f => f.where.source.isBlackBoxed));
+     }
+   );
+ 
+-  yield blackBox(sourceClient);
++  await blackBox(sourceClient);
+   Assert.ok(sourceClient.isBlackBoxed);
+ 
+   // Test that we step through `doStuff` when we are black boxed and its frame
+   // doesn't show up.
+-  yield runTest(
++  await runTest(
+     function onSteppedLocation(location) {
+       Assert.equal(location.source.url, SOURCE_URL);
+       Assert.equal(location.line, 4);
+     },
+     function onDebuggerStatementFrames(frames) {
+       for (let f of frames) {
+         if (f.where.source.url == BLACK_BOXED_URL) {
+           Assert.ok(f.where.source.isBlackBoxed);
+         } else {
+           Assert.ok(!f.where.source.isBlackBoxed);
+         }
+       }
+     }
+   );
+ 
+-  yield unBlackBox(sourceClient);
++  await unBlackBox(sourceClient);
+   Assert.ok(!sourceClient.isBlackBoxed);
+ 
+   // Test that we can step into `doStuff` again.
+-  yield runTest(
++  await runTest(
+     function onSteppedLocation(location) {
+       Assert.equal(location.source.url, BLACK_BOXED_URL);
+       Assert.equal(location.line, 2);
+     },
+     function onDebuggerStatementFrames(frames) {
+       Assert.ok(!frames.some(f => f.where.source.isBlackBoxed));
+     }
+   );
+ 
+   finishClient(gClient);
+-});
++};
+ 
+ function evalCode() {
+   /* eslint-disable */
+   Cu.evalInSandbox(
+     "" + function doStuff(k) { // line 1
+       let arg = 15;            // line 2 - Step in here
+       k(arg);                  // line 3
+     },                         // line 4
+@@ -117,31 +117,31 @@ function evalCode() {
+     gDebuggee,
+     "1.8",
+     SOURCE_URL,
+     1
+   );
+   /* eslint-enable */
+ }
+ 
+-const runTest = Task.async(function* (onSteppedLocation, onDebuggerStatementFrames) {
+-  let packet = yield executeOnNextTickAndWaitForPause(gDebuggee.runTest,
++const runTest = async function (onSteppedLocation, onDebuggerStatementFrames) {
++  let packet = await executeOnNextTickAndWaitForPause(gDebuggee.runTest,
+                                                       gClient);
+   Assert.equal(packet.why.type, "breakpoint");
+ 
+-  yield stepIn(gClient, gThreadClient);
++  await stepIn(gClient, gThreadClient);
+ 
+-  const location = yield getCurrentLocation();
++  const location = await getCurrentLocation();
+   onSteppedLocation(location);
+ 
+-  packet = yield resumeAndWaitForPause(gClient, gThreadClient);
++  packet = await resumeAndWaitForPause(gClient, gThreadClient);
+   Assert.equal(packet.why.type, "debuggerStatement");
+ 
+-  let { frames } = yield getFrames(gThreadClient, 0, 100);
++  let { frames } = await getFrames(gThreadClient, 0, 100);
+   onDebuggerStatementFrames(frames);
+ 
+   return resume(gThreadClient);
+-});
++};
+ 
+-const getCurrentLocation = Task.async(function* () {
+-  const response = yield getFrames(gThreadClient, 0, 1);
++const getCurrentLocation = async function () {
++  const response = await getFrames(gThreadClient, 0, 1);
+   return response.frames[0].where;
+-});
++};
+diff --git a/devtools/server/tests/unit/test_blackboxing-07.js b/devtools/server/tests/unit/test_blackboxing-07.js
+--- a/devtools/server/tests/unit/test_blackboxing-07.js
++++ b/devtools/server/tests/unit/test_blackboxing-07.js
+@@ -24,30 +24,30 @@ function run_test() {
+                            });
+   });
+   do_test_pending();
+ }
+ 
+ const BLACK_BOXED_URL = "http://example.com/black-boxed.min.js";
+ const SOURCE_URL = "http://example.com/source.js";
+ 
+-const testBlackBox = Task.async(function* () {
+-  yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++const testBlackBox = async function () {
++  await executeOnNextTickAndWaitForPause(evalCode, gClient);
+ 
+-  const { sources } = yield getSources(gThreadClient);
++  const { sources } = await getSources(gThreadClient);
+   equal(sources.length, 2);
+ 
+   const blackBoxedSource = sources.filter(s => s.url === BLACK_BOXED_URL)[0];
+   equal(blackBoxedSource.isBlackBoxed, true);
+ 
+   const regularSource = sources.filter(s => s.url === SOURCE_URL)[0];
+   equal(regularSource.isBlackBoxed, false);
+ 
+   finishClient(gClient);
+-});
++};
+ 
+ function evalCode() {
+   Cu.evalInSandbox(
+     "" + function blackBoxed() {},
+     gDebuggee,
+     "1.8",
+     BLACK_BOXED_URL,
+     1
+diff --git a/devtools/server/tests/unit/test_breakpoint-03.js b/devtools/server/tests/unit/test_breakpoint-03.js
+--- a/devtools/server/tests/unit/test_breakpoint-03.js
++++ b/devtools/server/tests/unit/test_breakpoint-03.js
+@@ -32,37 +32,37 @@ function run_test_with_server(server, ca
+                            "test-stack",
+                            function (response, tabClient, threadClient) {
+                              gThreadClient = threadClient;
+                              test_skip_breakpoint();
+                            });
+   });
+ }
+ 
+-var test_no_skip_breakpoint = Task.async(function* (source, location) {
+-  let [response, bpClient] = yield source.setBreakpoint(
++var test_no_skip_breakpoint = async function (source, location) {
++  let [response, bpClient] = await source.setBreakpoint(
+     Object.assign({}, location, { noSliding: true })
+   );
+ 
+   Assert.ok(!response.actualLocation);
+   Assert.equal(bpClient.location.line, gDebuggee.line0 + 3);
+-  yield bpClient.remove();
+-});
++  await bpClient.remove();
++};
+ 
+ var test_skip_breakpoint = function () {
+-  gThreadClient.addOneTimeListener("paused", Task.async(function* (event, packet) {
++  gThreadClient.addOneTimeListener("paused", async function (event, packet) {
+     let location = { line: gDebuggee.line0 + 3 };
+     let source = gThreadClient.source(packet.frame.where.source);
+ 
+     // First, make sure that we can disable sliding with the
+     // `noSliding` option.
+-    yield test_no_skip_breakpoint(source, location);
++    await test_no_skip_breakpoint(source, location);
+ 
+     // Now make sure that the breakpoint properly slides forward one line.
+-    const [response, bpClient] = yield source.setBreakpoint(location);
++    const [response, bpClient] = await source.setBreakpoint(location);
+     Assert.ok(!!response.actualLocation);
+     Assert.equal(response.actualLocation.source.actor, source.actor);
+     Assert.equal(response.actualLocation.line, location.line + 1);
+ 
+     gThreadClient.addOneTimeListener("paused", function (event, packet) {
+       // Check the return value.
+       Assert.equal(packet.type, "paused");
+       Assert.equal(packet.frame.where.source.actor, source.actor);
+@@ -77,17 +77,17 @@ var test_skip_breakpoint = function () {
+       bpClient.remove(function (response) {
+         gThreadClient.resume(function () {
+           gClient.close().then(gCallback);
+         });
+       });
+     });
+ 
+     gThreadClient.resume();
+-  }));
++  });
+ 
+   // Use `evalInSandbox` to make the debugger treat it as normal
+   // globally-scoped code, where breakpoint sliding rules apply.
+   /* eslint-disable */
+   Cu.evalInSandbox(
+     "var line0 = Error().lineNumber;\n" +
+     "debugger;\n" +      // line0 + 1
+     "var a = 1;\n" +     // line0 + 2
+diff --git a/devtools/server/tests/unit/test_breakpoint-13.js b/devtools/server/tests/unit/test_breakpoint-13.js
+--- a/devtools/server/tests/unit/test_breakpoint-13.js
++++ b/devtools/server/tests/unit/test_breakpoint-13.js
+@@ -35,17 +35,17 @@ function run_test_with_server(server, ca
+   });
+ }
+ 
+ function test_simple_breakpoint() {
+   gThreadClient.addOneTimeListener("paused", function (event, packet) {
+     let source = gThreadClient.source(packet.frame.where.source);
+     let location = { line: gDebuggee.line0 + 2 };
+ 
+-    source.setBreakpoint(location, Task.async(function* (response, bpClient) {
++    source.setBreakpoint(location, async function (response, bpClient) {
+       const testCallbacks = [
+         function (packet) {
+           // Check that the stepping worked.
+           Assert.equal(packet.frame.where.line, gDebuggee.line0 + 5);
+           Assert.equal(packet.why.type, "resumeLimit");
+         },
+         function (packet) {
+           // Entered the foo function call frame.
+@@ -87,26 +87,26 @@ function test_simple_breakpoint() {
+           Assert.notEqual(packet.why.type, "debuggerStatement");
+           Assert.equal(packet.why.type, "resumeLimit");
+         },
+       ];
+ 
+       for (let callback of testCallbacks) {
+         let waiter = waitForPause(gThreadClient);
+         gThreadClient.stepIn();
+-        let packet = yield waiter;
++        let packet = await waiter;
+         callback(packet);
+       }
+ 
+       // Remove the breakpoint and finish.
+       let waiter = waitForPause(gThreadClient);
+       gThreadClient.stepIn();
+-      yield waiter;
++      await waiter;
+       bpClient.remove(() => gThreadClient.resume(() => gClient.close().then(gCallback)));
+-    }));
++    });
+   });
+ 
+   /* eslint-disable */
+   Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
+                    "function foo() {\n" + // line0 + 1
+                    "  this.a = 1;\n" +    // line0 + 2 <-- Breakpoint is set here.
+                    "}\n" +                // line0 + 3
+                    "debugger;\n" +        // line0 + 4
+diff --git a/devtools/server/tests/unit/test_breakpoint-14.js b/devtools/server/tests/unit/test_breakpoint-14.js
+--- a/devtools/server/tests/unit/test_breakpoint-14.js
++++ b/devtools/server/tests/unit/test_breakpoint-14.js
+@@ -35,17 +35,17 @@ function run_test_with_server(server, ca
+   });
+ }
+ 
+ function test_simple_breakpoint() {
+   gThreadClient.addOneTimeListener("paused", function (event, packet) {
+     let source = gThreadClient.source(packet.frame.where.source);
+     let location = { line: gDebuggee.line0 + 2 };
+ 
+-    source.setBreakpoint(location, Task.async(function* (response, bpClient) {
++    source.setBreakpoint(location, async function (response, bpClient) {
+       const testCallbacks = [
+         function (packet) {
+           // Check that the stepping worked.
+           Assert.equal(packet.frame.where.line, gDebuggee.line0 + 5);
+           Assert.equal(packet.why.type, "resumeLimit");
+         },
+         function (packet) {
+           // Reached the breakpoint.
+@@ -85,26 +85,26 @@ function test_simple_breakpoint() {
+           Assert.notEqual(packet.why.type, "debuggerStatement");
+           Assert.equal(packet.why.type, "resumeLimit");
+         },
+       ];
+ 
+       for (let callback of testCallbacks) {
+         let waiter = waitForPause(gThreadClient);
+         gThreadClient.stepOver();
+-        let packet = yield waiter;
++        let packet = await waiter;
+         callback(packet);
+       }
+ 
+       // Remove the breakpoint and finish.
+       let waiter = waitForPause(gThreadClient);
+       gThreadClient.stepOver();
+-      yield waiter;
++      await waiter;
+       bpClient.remove(() => gThreadClient.resume(() => gClient.close().then(gCallback)));
+-    }));
++    });
+   });
+ 
+   /* eslint-disable */
+   Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
+                    "function foo() {\n" + // line0 + 1
+                    "  this.a = 1;\n" +    // line0 + 2 <-- Breakpoint is set here.
+                    "}\n" +                // line0 + 3
+                    "debugger;\n" +        // line0 + 4
+diff --git a/devtools/server/tests/unit/test_breakpoint-15.js b/devtools/server/tests/unit/test_breakpoint-15.js
+--- a/devtools/server/tests/unit/test_breakpoint-15.js
++++ b/devtools/server/tests/unit/test_breakpoint-15.js
+@@ -22,46 +22,46 @@ function run_test() {
+                              testSameBreakpoint();
+                            });
+   });
+   do_test_pending();
+ }
+ 
+ const SOURCE_URL = "http://example.com/source.js";
+ 
+-const testSameBreakpoint = Task.async(function* () {
+-  let packet = yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++const testSameBreakpoint = async function () {
++  let packet = await executeOnNextTickAndWaitForPause(evalCode, gClient);
+   let source = gThreadClient.source(packet.frame.where.source);
+ 
+   // Whole line
+   let wholeLineLocation = {
+     line: 2
+   };
+ 
+-  let [, firstBpClient] = yield setBreakpoint(source, wholeLineLocation);
+-  let [, secondBpClient] = yield setBreakpoint(source, wholeLineLocation);
++  let [, firstBpClient] = await setBreakpoint(source, wholeLineLocation);
++  let [, secondBpClient] = await setBreakpoint(source, wholeLineLocation);
+ 
+   Assert.equal(firstBpClient.actor, secondBpClient.actor,
+                "Should get the same actor w/ whole line breakpoints");
+ 
+   // Specific column
+ 
+   let columnLocation = {
+     line: 2,
+     column: 6
+   };
+ 
+-  [, firstBpClient] = yield setBreakpoint(source, columnLocation);
+-  [, secondBpClient] = yield setBreakpoint(source, columnLocation);
++  [, firstBpClient] = await setBreakpoint(source, columnLocation);
++  [, secondBpClient] = await setBreakpoint(source, columnLocation);
+ 
+   Assert.equal(secondBpClient.actor, secondBpClient.actor,
+                "Should get the same actor column breakpoints");
+ 
+   finishClient(gClient);
+-});
++};
+ 
+ function evalCode() {
+   /* eslint-disable */
+   Cu.evalInSandbox(
+     "" + function doStuff(k) { // line 1
+       let arg = 15;            // line 2 - Step in here
+       k(arg);                  // line 3
+     } + "\n"                   // line 4
+diff --git a/devtools/server/tests/unit/test_breakpoint-19.js b/devtools/server/tests/unit/test_breakpoint-19.js
+--- a/devtools/server/tests/unit/test_breakpoint-19.js
++++ b/devtools/server/tests/unit/test_breakpoint-19.js
+@@ -46,25 +46,25 @@ function setUpCode() {
+     "\ndebugger;",         // 5
+     gDebuggee,
+     "1.8",
+     URL
+   );
+   /* eslint-enable */
+ }
+ 
+-const testBreakpoint = Task.async(function* () {
+-  let source = yield getSource(gThreadClient, URL);
+-  let [response, ] = yield setBreakpoint(source, {line: 2});
++const testBreakpoint = async function () {
++  let source = await getSource(gThreadClient, URL);
++  let [response, ] = await setBreakpoint(source, {line: 2});
+   ok(!response.error);
+ 
+   let actor = response.actor;
+   ok(actor);
+ 
+-  yield executeOnNextTickAndWaitForPause(setUpCode, gClient);
+-  yield resume(gThreadClient);
++  await executeOnNextTickAndWaitForPause(setUpCode, gClient);
++  await resume(gThreadClient);
+ 
+-  let packet = yield executeOnNextTickAndWaitForPause(gDebuggee.test, gClient);
++  let packet = await executeOnNextTickAndWaitForPause(gDebuggee.test, gClient);
+   equal(packet.why.type, "breakpoint");
+   notEqual(packet.why.actors.indexOf(actor), -1);
+ 
+   finishClient(gClient);
+-});
++};
+diff --git a/devtools/server/tests/unit/test_breakpoint-20.js b/devtools/server/tests/unit/test_breakpoint-20.js
+--- a/devtools/server/tests/unit/test_breakpoint-20.js
++++ b/devtools/server/tests/unit/test_breakpoint-20.js
+@@ -16,76 +16,76 @@ function run_test() {
+   gDebuggee = addTestGlobal("test-breakpoints");
+   gClient = new DebuggerClient(DebuggerServer.connectPipe());
+   gClient.connect().then(function () {
+     attachTestThread(gClient, "test-breakpoints", testBreakpoint);
+   });
+   do_test_pending();
+ }
+ 
+-const testBreakpoint = Task.async(function* (threadResponse, tabClient,
++const testBreakpoint = async function (threadResponse, tabClient,
+                                              threadClient, tabResponse) {
+   evalSetupCode();
+ 
+   // Load the test source once.
+ 
+   evalTestCode();
+   equal(gDebuggee.functions.length, 1,
+         "The test code should have added a function.");
+ 
+   // Set a breakpoint in the test source.
+ 
+-  const source = yield getSource(threadClient, "test.js");
+-  const [response, ] = yield setBreakpoint(source, {
++  const source = await getSource(threadClient, "test.js");
++  const [response, ] = await setBreakpoint(source, {
+     line: 3
+   });
+   ok(!response.error, "Shouldn't get an error setting the BP.");
+   ok(!response.actualLocation,
+      "Shouldn't get an actualLocation, the location we provided was good.");
+   const bpActor = response.actor;
+ 
+-  yield resume(threadClient);
++  await resume(threadClient);
+ 
+   // Load the test source again.
+ 
+   evalTestCode();
+   equal(gDebuggee.functions.length, 2,
+         "The test code should have added another function.");
+ 
+   // Should hit our breakpoint in a script defined by the first instance of the
+   // test source.
+ 
+-  const bpPause1 = yield executeOnNextTickAndWaitForPause(gDebuggee.functions[0],
++  const bpPause1 = await executeOnNextTickAndWaitForPause(gDebuggee.functions[0],
+                                                           gClient);
+   equal(bpPause1.why.type, "breakpoint",
+         "Should pause because of hitting our breakpoint (not debugger statement).");
+   equal(bpPause1.why.actors[0], bpActor,
+         "And the breakpoint actor should be correct.");
+-  const dbgStmtPause1 = yield executeOnNextTickAndWaitForPause(() => resume(threadClient),
++  const dbgStmtPause1 = await executeOnNextTickAndWaitForPause(() => resume(threadClient),
+                                                                gClient);
+   equal(dbgStmtPause1.why.type, "debuggerStatement",
+         "And we should hit the debugger statement after the pause.");
+-  yield resume(threadClient);
++  await resume(threadClient);
+ 
+   // Should also hit our breakpoint in a script defined by the second instance
+   // of the test source.
+ 
+-  const bpPause2 = yield executeOnNextTickAndWaitForPause(gDebuggee.functions[1],
++  const bpPause2 = await executeOnNextTickAndWaitForPause(gDebuggee.functions[1],
+                                                           gClient);
+   equal(bpPause2.why.type, "breakpoint",
+         "Should pause because of hitting our breakpoint (not debugger statement).");
+   equal(bpPause2.why.actors[0], bpActor,
+         "And the breakpoint actor should be correct.");
+-  const dbgStmtPause2 = yield executeOnNextTickAndWaitForPause(() => resume(threadClient),
++  const dbgStmtPause2 = await executeOnNextTickAndWaitForPause(() => resume(threadClient),
+                                                                gClient);
+   equal(dbgStmtPause2.why.type, "debuggerStatement",
+         "And we should hit the debugger statement after the pause.");
+ 
+   finishClient(gClient);
+-});
++};
+ 
+ function evalSetupCode() {
+   Cu.evalInSandbox(
+     "this.functions = [];",
+     gDebuggee,
+     "1.8",
+     "setup.js",
+     1
+diff --git a/devtools/server/tests/unit/test_breakpoint-21.js b/devtools/server/tests/unit/test_breakpoint-21.js
+--- a/devtools/server/tests/unit/test_breakpoint-21.js
++++ b/devtools/server/tests/unit/test_breakpoint-21.js
+@@ -29,41 +29,41 @@ function run_test_with_server(server, ca
+                            "test-breakpoints",
+                            function (response, tabClient, threadClient) {
+                              gThreadClient = threadClient;
+                              test();
+                            });
+   });
+ }
+ 
+-const test = Task.async(function* () {
++const test = async function () {
+   // Populate the `ScriptStore` so that we only test that the script
+   // is added through `onNewScript`
+-  yield getSources(gThreadClient);
++  await getSources(gThreadClient);
+ 
+-  let packet = yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++  let packet = await executeOnNextTickAndWaitForPause(evalCode, gClient);
+   let source = gThreadClient.source(packet.frame.where.source);
+   let location = {
+     line: gDebuggee.line0 + 8
+   };
+ 
+-  let [res, bpClient] = yield setBreakpoint(source, location);
++  let [res, bpClient] = await setBreakpoint(source, location);
+   ok(!res.error);
+ 
+-  yield resume(gThreadClient);
+-  packet = yield waitForPause(gClient);
++  await resume(gThreadClient);
++  packet = await waitForPause(gClient);
+   Assert.equal(packet.type, "paused");
+   Assert.equal(packet.why.type, "breakpoint");
+   Assert.equal(packet.why.actors[0], bpClient.actor);
+   Assert.equal(packet.frame.where.source.actor, source.actor);
+   Assert.equal(packet.frame.where.line, location.line);
+ 
+-  yield resume(gThreadClient);
++  await resume(gThreadClient);
+   finishClient(gClient);
+-});
++};
+ 
+ /* eslint-disable */
+ function evalCode() {
+   // Start a new script
+   Cu.evalInSandbox(
+     "var line0 = Error().lineNumber;\n(" + function () {
+       debugger;
+       var a = (function () {
+diff --git a/devtools/server/tests/unit/test_breakpoint-22.js b/devtools/server/tests/unit/test_breakpoint-22.js
+--- a/devtools/server/tests/unit/test_breakpoint-22.js
++++ b/devtools/server/tests/unit/test_breakpoint-22.js
+@@ -28,44 +28,44 @@ function run_test_with_server(server, ca
+                            "test-breakpoints",
+                            function (response, tabClient, threadClient) {
+                              gThreadClient = threadClient;
+                              test();
+                            });
+   });
+ }
+ 
+-const test = Task.async(function* () {
++const test = async function () {
+   // Populate the `ScriptStore` so that we only test that the script
+   // is added through `onNewScript`
+-  yield getSources(gThreadClient);
++  await getSources(gThreadClient);
+ 
+-  let packet = yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++  let packet = await executeOnNextTickAndWaitForPause(evalCode, gClient);
+   let source = gThreadClient.source(packet.frame.where.source);
+   let location = {
+     line: gDebuggee.line0 + 2
+   };
+ 
+-  let [res, ] = yield setBreakpoint(source, location);
++  let [res, ] = await setBreakpoint(source, location);
+   ok(!res.error);
+ 
+   let location2 = {
+     line: gDebuggee.line0 + 7
+   };
+ 
+-  yield source.setBreakpoint(location2).then(_ => {
++  await source.setBreakpoint(location2).then(_ => {
+     do_throw("no code shall not be found the specified line or below it");
+   }, reason => {
+     Assert.equal(reason.error, "noCodeAtLineColumn");
+     ok(reason.message);
+   });
+ 
+-  yield resume(gThreadClient);
++  await resume(gThreadClient);
+   finishClient(gClient);
+-});
++};
+ 
+ function evalCode() {
+   // Start a new script
+   Cu.evalInSandbox(`
+ var line0 = Error().lineNumber;
+ function some_function() {
+   // breakpoint is valid here -- it slides one line below (line0 + 2)
+ }
+diff --git a/devtools/server/tests/unit/test_listsources-04.js b/devtools/server/tests/unit/test_listsources-04.js
+--- a/devtools/server/tests/unit/test_listsources-04.js
++++ b/devtools/server/tests/unit/test_listsources-04.js
+@@ -16,37 +16,37 @@ function run_test() {
+     // `rpc` method which talks to the main thread does not work.
+     // run_test_with_server(WorkerDebuggerServer, do_test_finished);
+     do_test_finished();
+   });
+   do_test_pending();
+ }
+ 
+ function run_test_with_server(server, cb) {
+-  Task.spawn(function* () {
++  (async function () {
+     initTestDebuggerServer(server);
+     const debuggee = addTestGlobal("test-sources", server);
+     const client = new DebuggerClient(server.connectPipe());
+-    yield client.connect();
+-    const [,, threadClient] = yield attachTestTabAndResume(client, "test-sources");
++    await client.connect();
++    const [,, threadClient] = await attachTestTabAndResume(client, "test-sources");
+ 
+-    yield threadClient.reconfigure({ useSourceMaps: true });
++    await threadClient.reconfigure({ useSourceMaps: true });
+     addSources(debuggee);
+ 
+-    threadClient.getSources(Task.async(function* (res) {
++    threadClient.getSources(async function (res) {
+       Assert.equal(res.sources.length, 3, "3 sources exist");
+ 
+-      yield threadClient.reconfigure({ useSourceMaps: false });
++      await threadClient.reconfigure({ useSourceMaps: false });
+ 
+       threadClient.getSources(function (res) {
+         Assert.equal(res.sources.length, 1, "1 source exist");
+         client.close().then(cb);
+       });
+-    }));
+-  });
++    });
++  })();
+ }
+ 
+ function addSources(debuggee) {
+   let { code, map } = (new SourceNode(null, null, null, [
+     new SourceNode(1, 0, "a.js", "function a() { return 'a'; }\n"),
+     new SourceNode(1, 0, "b.js", "function b() { return 'b'; }\n"),
+     new SourceNode(1, 0, "c.js", "function c() { return 'c'; }\n"),
+   ])).toStringWithSourceMap({
+diff --git a/devtools/server/tests/unit/test_objectgrips-14.js b/devtools/server/tests/unit/test_objectgrips-14.js
+--- a/devtools/server/tests/unit/test_objectgrips-14.js
++++ b/devtools/server/tests/unit/test_objectgrips-14.js
+@@ -36,26 +36,26 @@ function evalCode() {
+         debugger;
+       })();
+     })();
+ 
+     debugger;
+   });
+ }
+ 
+-const testObjectGroup = Task.async(function* () {
+-  let packet = yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++const testObjectGroup = async function () {
++  let packet = await executeOnNextTickAndWaitForPause(evalCode, gClient);
+ 
+   const ugh = packet.frame.environment.parent.parent.bindings.variables.ugh;
+-  const ughClient = yield gThreadClient.pauseGrip(ugh.value);
++  const ughClient = await gThreadClient.pauseGrip(ugh.value);
+ 
+-  packet = yield getPrototypeAndProperties(ughClient);
+-  packet = yield resumeAndWaitForPause(gClient, gThreadClient);
++  packet = await getPrototypeAndProperties(ughClient);
++  packet = await resumeAndWaitForPause(gClient, gThreadClient);
+ 
+   const ugh2 = packet.frame.environment.bindings.variables.ugh;
+   const ugh2Client = gThreadClient.pauseGrip(ugh2.value);
+ 
+-  packet = yield getPrototypeAndProperties(ugh2Client);
++  packet = await getPrototypeAndProperties(ugh2Client);
+   Assert.equal(packet.ownProperties.length.value, 1);
+ 
+-  yield resume(gThreadClient);
++  await resume(gThreadClient);
+   finishClient(gClient);
+-});
++};
+diff --git a/devtools/server/tests/unit/test_objectgrips-15.js b/devtools/server/tests/unit/test_objectgrips-15.js
+--- a/devtools/server/tests/unit/test_objectgrips-15.js
++++ b/devtools/server/tests/unit/test_objectgrips-15.js
+@@ -34,26 +34,26 @@ function evalCode() {
+       ugh.push(i++);
+       debugger;
+     }
+ 
+     Promise.resolve().then(foo).then(foo);
+   });
+ }
+ 
+-const testObjectGroup = Task.async(function* () {
+-  let packet = yield executeOnNextTickAndWaitForPause(evalCode, gClient);
++const testObjectGroup = async function () {
++  let packet = await executeOnNextTickAndWaitForPause(evalCode, gClient);
+ 
+   const ugh = packet.frame.environment.parent.bindings.variables.ugh;
+-  const ughClient = yield gThreadClient.pauseGrip(ugh.value);
++  const ughClient = await gThreadClient.pauseGrip(ugh.value);
+ 
+-  packet = yield getPrototypeAndProperties(ughClient);
++  packet = await getPrototypeAndProperties(ughClient);
+ 
+-  packet = yield resumeAndWaitForPause(gClient, gThreadClient);
++  packet = await resumeAndWaitForPause(gClient, gThreadClient);
+   const ugh2 = packet.frame.environment.parent.bindings.variables.ugh;
+   const ugh2Client = gThreadClient.pauseGrip(ugh2.value);
+ 
+-  packet = yield getPrototypeAndProperties(ugh2Client);
++  packet = await getPrototypeAndProperties(ugh2Client);
+   Assert.equal(packet.ownProperties.length.value, 2);
+ 
+-  yield resume(gThreadClient);
++  await resume(gThreadClient);
+   finishClient(gClient);
+-});
++};
+diff --git a/devtools/server/tests/unit/test_promise_state-01.js b/devtools/server/tests/unit/test_promise_state-01.js
+--- a/devtools/server/tests/unit/test_promise_state-01.js
++++ b/devtools/server/tests/unit/test_promise_state-01.js
+@@ -12,27 +12,27 @@
+ function run_test() {
+   initTestDebuggerServer();
+   const debuggee = addTestGlobal("test-promise-state");
+   const client = new DebuggerClient(DebuggerServer.connectPipe());
+   client.connect().then(function () {
+     attachTestTabAndResume(
+       client, "test-promise-state",
+       function (response, tabClient, threadClient) {
+-        Task.spawn(function* () {
+-          const packet = yield executeOnNextTickAndWaitForPause(
++        (async function () {
++          const packet = await executeOnNextTickAndWaitForPause(
+             () => evalCode(debuggee), client);
+ 
+           const grip = packet.frame.environment.bindings.variables.p;
+           ok(grip.value.preview);
+           equal(grip.value.class, "Promise");
+           equal(grip.value.promiseState.state, "pending");
+ 
+           finishClient(client);
+-        });
++        })();
+       });
+   });
+   do_test_pending();
+ }
+ 
+ function evalCode(debuggee) {
+   /* eslint-disable */
+   Cu.evalInSandbox(
+diff --git a/devtools/server/tests/unit/test_promise_state-02.js b/devtools/server/tests/unit/test_promise_state-02.js
+--- a/devtools/server/tests/unit/test_promise_state-02.js
++++ b/devtools/server/tests/unit/test_promise_state-02.js
+@@ -12,30 +12,30 @@
+ function run_test() {
+   initTestDebuggerServer();
+   const debuggee = addTestGlobal("test-promise-state");
+   const client = new DebuggerClient(DebuggerServer.connectPipe());
+   client.connect().then(function () {
+     attachTestTabAndResume(
+       client, "test-promise-state",
+       function (response, tabClient, threadClient) {
+-        Task.spawn(function* () {
+-          const packet = yield executeOnNextTickAndWaitForPause(
++        (async function () {
++          const packet = await executeOnNextTickAndWaitForPause(
+             () => evalCode(debuggee), client);
+ 
+           const grip = packet.frame.environment.bindings.variables.p;
+           ok(grip.value.preview);
+           equal(grip.value.class, "Promise");
+           equal(grip.value.promiseState.state, "fulfilled");
+           equal(grip.value.promiseState.value.actorID, packet.frame.arguments[0].actorID,
+                 "The promise's fulfilled state value should be the same value passed " +
+                 "to the then function");
+ 
+           finishClient(client);
+-        });
++        })();
+       });
+   });
+   do_test_pending();
+ }
+ 
+ function evalCode(debuggee) {
+   /* eslint-disable */
+   Cu.evalInSandbox(
+diff --git a/devtools/server/tests/unit/test_promise_state-03.js b/devtools/server/tests/unit/test_promise_state-03.js
+--- a/devtools/server/tests/unit/test_promise_state-03.js
++++ b/devtools/server/tests/unit/test_promise_state-03.js
+@@ -12,30 +12,30 @@
+ function run_test() {
+   initTestDebuggerServer();
+   const debuggee = addTestGlobal("test-promise-state");
+   const client = new DebuggerClient(DebuggerServer.connectPipe());
+   client.connect().then(function () {
+     attachTestTabAndResume(
+       client, "test-promise-state",
+       function (response, tabClient, threadClient) {
+-        Task.spawn(function* () {
+-          const packet = yield executeOnNextTickAndWaitForPause(
++        (async function () {
++          const packet = await executeOnNextTickAndWaitForPause(
+             () => evalCode(debuggee), client);
+ 
+           const grip = packet.frame.environment.bindings.variables.p;
+           ok(grip.value.preview);
+           equal(grip.value.class, "Promise");
+           equal(grip.value.promiseState.state, "rejected");
+           equal(grip.value.promiseState.reason.actorID, packet.frame.arguments[0].actorID,
+                 "The promise's rejected state reason should be the same value passed " +
+                 "to the then function");
+ 
+           finishClient(client);
+-        });
++        })();
+       });
+   });
+   do_test_pending();
+ }
+ 
+ function evalCode(debuggee) {
+   /* eslint-disable */
+   Cu.evalInSandbox(
+diff --git a/devtools/server/tests/unit/test_promises_actor_attach.js b/devtools/server/tests/unit/test_promises_actor_attach.js
+--- a/devtools/server/tests/unit/test_promises_actor_attach.js
++++ b/devtools/server/tests/unit/test_promises_actor_attach.js
+@@ -5,50 +5,50 @@
+ 
+ /**
+  * Test that we can attach and detach to the PromisesActor under the correct
+  * states.
+  */
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("promises-actor-test");
+-  let chromeActors = yield getChromeActors(client);
++add_task(async function () {
++  let client = await startTestDebuggerServer("promises-actor-test");
++  let chromeActors = await getChromeActors(client);
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testAttach(client, chromeActors);
++  await attachTab(client, chromeActors);
++  await testAttach(client, chromeActors);
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "promises-actor-test");
+   ok(targetTab, "Found our target tab.");
+ 
+-  let [ tabResponse ] = yield attachTab(client, targetTab);
++  let [ tabResponse ] = await attachTab(client, targetTab);
+ 
+-  yield testAttach(client, tabResponse);
++  await testAttach(client, tabResponse);
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testAttach(client, parent) {
++async function testAttach(client, parent) {
+   let promises = PromisesFront(client, parent);
+ 
+   try {
+-    yield promises.detach();
++    await promises.detach();
+     ok(false, "Should not be able to detach when in a detached state.");
+   } catch (e) {
+     ok(true, "Expected detach to fail when already in a detached state.");
+   }
+ 
+-  yield promises.attach();
++  await promises.attach();
+   ok(true, "Expected attach to succeed.");
+ 
+   try {
+-    yield promises.attach();
++    await promises.attach();
+     ok(false, "Should not be able to attach when in an attached state.");
+   } catch (e) {
+     ok(true, "Expected attach to fail when already in an attached state.");
+   }
+ 
+-  yield promises.detach();
++  await promises.detach();
+   ok(true, "Expected detach to succeed.");
+ }
+diff --git a/devtools/server/tests/unit/test_promises_actor_exist.js b/devtools/server/tests/unit/test_promises_actor_exist.js
+--- a/devtools/server/tests/unit/test_promises_actor_exist.js
++++ b/devtools/server/tests/unit/test_promises_actor_exist.js
+@@ -3,30 +3,30 @@
+ /* eslint-disable no-shadow */
+ 
+ "use strict";
+ 
+ /**
+  * Test that the PromisesActor exists in the TabActors and ChromeActors.
+  */
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("promises-actor-test");
++add_task(async function () {
++  let client = await startTestDebuggerServer("promises-actor-test");
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "promises-actor-test");
+   ok(targetTab, "Found our target tab.");
+ 
+   // Attach to the TabActor and check the response
+   client.request({ to: targetTab.actor, type: "attach" }, response => {
+     ok(!("error" in response), "Expect no error in response.");
+     ok(response.from, targetTab.actor,
+       "Expect the target TabActor in response form field.");
+     ok(response.type, "tabAttached",
+       "Expect tabAttached in the response type.");
+     is(typeof response.promisesActor === "string",
+       "Should have a tab context PromisesActor.");
+   });
+ 
+-  let chromeActors = yield getChromeActors(client);
++  let chromeActors = await getChromeActors(client);
+   ok(typeof chromeActors.promisesActor === "string",
+     "Should have a chrome context PromisesActor.");
+ });
+diff --git a/devtools/server/tests/unit/test_promises_actor_list_promises.js b/devtools/server/tests/unit/test_promises_actor_list_promises.js
+--- a/devtools/server/tests/unit/test_promises_actor_list_promises.js
++++ b/devtools/server/tests/unit/test_promises_actor_list_promises.js
+@@ -6,45 +6,45 @@
+  * PromisesActor.
+  */
+ 
+ "use strict";
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ const SECRET = "MyLittleSecret";
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("promises-actor-test");
+-  let chromeActors = yield getChromeActors(client);
++add_task(async function () {
++  let client = await startTestDebuggerServer("promises-actor-test");
++  let chromeActors = await getChromeActors(client);
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testListPromises(client, chromeActors, v =>
++  await attachTab(client, chromeActors);
++  await testListPromises(client, chromeActors, v =>
+     new Promise(resolve => resolve(v)));
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "promises-actor-test");
+   ok(targetTab, "Found our target tab.");
+ 
+-  yield testListPromises(client, targetTab, v => {
++  await testListPromises(client, targetTab, v => {
+     const debuggee = DebuggerServer.getTestGlobal("promises-actor-test");
+     return debuggee.Promise.resolve(v);
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testListPromises(client, form, makePromise) {
++async function testListPromises(client, form, makePromise) {
+   let resolution = SECRET + Math.random();
+   let promise = makePromise(resolution);
+   let front = PromisesFront(client, form);
+ 
+-  yield front.attach();
++  await front.attach();
+ 
+-  let promises = yield front.listPromises();
++  let promises = await front.listPromises();
+ 
+   let found = false;
+   for (let p of promises) {
+     equal(p.type, "object", "Expect type to be Object");
+     equal(p.class, "Promise", "Expect class to be Promise");
+     equal(typeof p.promiseState.creationTimestamp, "number",
+       "Expect creation timestamp to be a number");
+     if (p.promiseState.state !== "pending") {
+@@ -54,12 +54,12 @@ function* testListPromises(client, form,
+ 
+     if (p.promiseState.state === "fulfilled" &&
+         p.promiseState.value === resolution) {
+       found = true;
+     }
+   }
+ 
+   ok(found, "Found our promise");
+-  yield front.detach();
++  await front.detach();
+   // Appease eslint
+   void promise;
+ }
+diff --git a/devtools/server/tests/unit/test_promises_actor_onnewpromise.js b/devtools/server/tests/unit/test_promises_actor_onnewpromise.js
+--- a/devtools/server/tests/unit/test_promises_actor_onnewpromise.js
++++ b/devtools/server/tests/unit/test_promises_actor_onnewpromise.js
+@@ -7,46 +7,46 @@
+  */
+ 
+ "use strict";
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ 
+ var EventEmitter = require("devtools/shared/event-emitter");
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("promises-actor-test");
+-  let chromeActors = yield getChromeActors(client);
++add_task(async function () {
++  let client = await startTestDebuggerServer("promises-actor-test");
++  let chromeActors = await getChromeActors(client);
+ 
+   ok(Promise.toString().includes("native code"), "Expect native DOM Promise");
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testNewPromisesEvent(client, chromeActors,
++  await attachTab(client, chromeActors);
++  await testNewPromisesEvent(client, chromeActors,
+     v => new Promise(resolve => resolve(v)));
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "promises-actor-test");
+   ok(targetTab, "Found our target tab.");
+ 
+-  yield testNewPromisesEvent(client, targetTab, v => {
++  await testNewPromisesEvent(client, targetTab, v => {
+     const debuggee = DebuggerServer.getTestGlobal("promises-actor-test");
+     return debuggee.Promise.resolve(v);
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testNewPromisesEvent(client, form, makePromise) {
++async function testNewPromisesEvent(client, form, makePromise) {
+   let front = PromisesFront(client, form);
+   let resolution = "MyLittleSecret" + Math.random();
+   let found = false;
+ 
+-  yield front.attach();
+-  yield front.listPromises();
++  await front.attach();
++  await front.listPromises();
+ 
+   let onNewPromise = new Promise(resolve => {
+     EventEmitter.on(front, "new-promises", promises => {
+       for (let p of promises) {
+         equal(p.type, "object", "Expect type to be Object");
+         equal(p.class, "Promise", "Expect class to be Promise");
+         equal(typeof p.promiseState.creationTimestamp, "number",
+           "Expect creation timestamp to be a number");
+@@ -59,14 +59,14 @@ function* testNewPromisesEvent(client, f
+           dump("Found non-target promise\n");
+         }
+       }
+     });
+   });
+ 
+   let promise = makePromise(resolution);
+ 
+-  yield onNewPromise;
++  await onNewPromise;
+   ok(found, "Found our new promise");
+-  yield front.detach();
++  await front.detach();
+   // Appease eslint
+   void promise;
+ }
+diff --git a/devtools/server/tests/unit/test_promises_actor_onpromisesettled.js b/devtools/server/tests/unit/test_promises_actor_onpromisesettled.js
+--- a/devtools/server/tests/unit/test_promises_actor_onpromisesettled.js
++++ b/devtools/server/tests/unit/test_promises_actor_onpromisesettled.js
+@@ -9,63 +9,63 @@
+ "use strict";
+ 
+ ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm", this);
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ 
+ var EventEmitter = require("devtools/shared/event-emitter");
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("promises-actor-test");
+-  let chromeActors = yield getChromeActors(client);
++add_task(async function () {
++  let client = await startTestDebuggerServer("promises-actor-test");
++  let chromeActors = await getChromeActors(client);
+ 
+   ok(Promise.toString().includes("native code"), "Expect native DOM Promise");
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testPromisesSettled(client, chromeActors,
++  await attachTab(client, chromeActors);
++  await testPromisesSettled(client, chromeActors,
+     v => new Promise(resolve => resolve(v)),
+     v => new Promise((resolve, reject) => reject(v)));
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "promises-actor-test");
+   ok(targetTab, "Found our target tab.");
+ 
+-  yield testPromisesSettled(client, targetTab, v => {
++  await testPromisesSettled(client, targetTab, v => {
+     const debuggee = DebuggerServer.getTestGlobal("promises-actor-test");
+     return debuggee.Promise.resolve(v);
+   }, v => {
+     const debuggee = DebuggerServer.getTestGlobal("promises-actor-test");
+     return debuggee.Promise.reject(v);
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testPromisesSettled(client, form, makeResolvePromise,
++async function testPromisesSettled(client, form, makeResolvePromise,
+     makeRejectPromise) {
+   let front = PromisesFront(client, form);
+   let resolution = "MyLittleSecret" + Math.random();
+ 
+-  yield front.attach();
+-  yield front.listPromises();
++  await front.attach();
++  await front.listPromises();
+ 
+   let onPromiseSettled = oncePromiseSettled(front, resolution, true, false);
+   let resolvedPromise = makeResolvePromise(resolution);
+-  let foundResolvedPromise = yield onPromiseSettled;
++  let foundResolvedPromise = await onPromiseSettled;
+   ok(foundResolvedPromise, "Found our resolved promise");
+ 
+   PromiseTestUtils.expectUncaughtRejection(r => r.message == resolution);
+   onPromiseSettled = oncePromiseSettled(front, resolution, false, true);
+   let rejectedPromise = makeRejectPromise(resolution);
+-  let foundRejectedPromise = yield onPromiseSettled;
++  let foundRejectedPromise = await onPromiseSettled;
+   ok(foundRejectedPromise, "Found our rejected promise");
+ 
+-  yield front.detach();
++  await front.detach();
+   // Appease eslint
+   void resolvedPromise;
+   void rejectedPromise;
+ }
+ 
+ function oncePromiseSettled(front, resolution, resolveValue, rejectValue) {
+   return new Promise(resolve => {
+     EventEmitter.on(front, "promises-settled", promises => {
+diff --git a/devtools/server/tests/unit/test_promises_client_getdependentpromises.js b/devtools/server/tests/unit/test_promises_client_getdependentpromises.js
+--- a/devtools/server/tests/unit/test_promises_client_getdependentpromises.js
++++ b/devtools/server/tests/unit/test_promises_client_getdependentpromises.js
+@@ -6,85 +6,85 @@
+  */
+ 
+ "use strict";
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ 
+ var EventEmitter = require("devtools/shared/event-emitter");
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("test-promises-dependentpromises");
+-  let chromeActors = yield getChromeActors(client);
+-  yield attachTab(client, chromeActors);
++add_task(async function () {
++  let client = await startTestDebuggerServer("test-promises-dependentpromises");
++  let chromeActors = await getChromeActors(client);
++  await attachTab(client, chromeActors);
+ 
+   ok(Promise.toString().includes("native code"), "Expect native DOM Promise.");
+ 
+-  yield testGetDependentPromises(client, chromeActors, () => {
++  await testGetDependentPromises(client, chromeActors, () => {
+     let p = new Promise(() => {});
+     p.name = "p";
+     let q = p.then();
+     q.name = "q";
+     let r = p.catch(() => {});
+     r.name = "r";
+ 
+     return p;
+   });
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "test-promises-dependentpromises");
+   ok(targetTab, "Found our target tab.");
+-  yield attachTab(client, targetTab);
++  await attachTab(client, targetTab);
+ 
+-  yield testGetDependentPromises(client, targetTab, () => {
++  await testGetDependentPromises(client, targetTab, () => {
+     const debuggee =
+       DebuggerServer.getTestGlobal("test-promises-dependentpromises");
+ 
+     let p = new debuggee.Promise(() => {});
+     p.name = "p";
+     let q = p.then();
+     q.name = "q";
+     let r = p.catch(() => {});
+     r.name = "r";
+ 
+     return p;
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testGetDependentPromises(client, form, makePromises) {
++async function testGetDependentPromises(client, form, makePromises) {
+   let front = PromisesFront(client, form);
+ 
+-  yield front.attach();
+-  yield front.listPromises();
++  await front.attach();
++  await front.listPromises();
+ 
+   // Get the grip for promise p
+   let onNewPromise = new Promise(resolve => {
+     EventEmitter.on(front, "new-promises", promises => {
+       for (let p of promises) {
+         if (p.preview.ownProperties.name &&
+             p.preview.ownProperties.name.value === "p") {
+           resolve(p);
+         }
+       }
+     });
+   });
+ 
+   let promise = makePromises();
+ 
+-  let grip = yield onNewPromise;
++  let grip = await onNewPromise;
+   ok(grip, "Found our promise p.");
+ 
+   let objectClient = new ObjectClient(client, grip);
+   ok(objectClient, "Got Object Client.");
+ 
+   // Get the dependent promises for promise p and assert that the list of
+   // dependent promises is correct
+-  yield new Promise(resolve => {
++  await new Promise(resolve => {
+     objectClient.getDependentPromises(response => {
+       let dependentNames = response.promises.map(p =>
+         p.preview.ownProperties.name.value);
+       let expectedDependentNames = ["q", "r"];
+ 
+       equal(dependentNames.length, expectedDependentNames.length,
+         "Got expected number of dependent promises.");
+ 
+@@ -101,12 +101,12 @@ function* testGetDependentPromises(clien
+         ok(!p.promiseState.timeToSettle,
+           "Expect time to settle to be undefined.");
+       }
+ 
+       resolve();
+     });
+   });
+ 
+-  yield front.detach();
++  await front.detach();
+   // Appease eslint
+   void promise;
+ }
+diff --git a/devtools/server/tests/unit/test_promises_object_creationtimestamp.js b/devtools/server/tests/unit/test_promises_object_creationtimestamp.js
+--- a/devtools/server/tests/unit/test_promises_object_creationtimestamp.js
++++ b/devtools/server/tests/unit/test_promises_object_creationtimestamp.js
+@@ -9,74 +9,74 @@
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ 
+ var EventEmitter = require("devtools/shared/event-emitter");
+ 
+ ChromeUtils.defineModuleGetter(this, "Preferences",
+                                "resource://gre/modules/Preferences.jsm");
+ 
+-add_task(function* () {
++add_task(async function () {
+   let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+   Preferences.set("privacy.reduceTimerPrecision", false);
+ 
+   registerCleanupFunction(function () {
+     Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+   });
+ 
+-  let client = yield startTestDebuggerServer("promises-object-test");
+-  let chromeActors = yield getChromeActors(client);
++  let client = await startTestDebuggerServer("promises-object-test");
++  let chromeActors = await getChromeActors(client);
+ 
+   ok(Promise.toString().includes("native code"), "Expect native DOM Promise.");
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testPromiseCreationTimestamp(client, chromeActors, v => {
++  await attachTab(client, chromeActors);
++  await testPromiseCreationTimestamp(client, chromeActors, v => {
+     return new Promise(resolve => resolve(v));
+   });
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "promises-object-test");
+   ok(targetTab, "Found our target tab.");
+ 
+-  yield testPromiseCreationTimestamp(client, targetTab, v => {
++  await testPromiseCreationTimestamp(client, targetTab, v => {
+     const debuggee = DebuggerServer.getTestGlobal("promises-object-test");
+     return debuggee.Promise.resolve(v);
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testPromiseCreationTimestamp(client, form, makePromise) {
++async function testPromiseCreationTimestamp(client, form, makePromise) {
+   let front = PromisesFront(client, form);
+   let resolution = "MyLittleSecret" + Math.random();
+ 
+-  yield front.attach();
+-  yield front.listPromises();
++  await front.attach();
++  await front.listPromises();
+ 
+   let onNewPromise = new Promise(resolve => {
+     EventEmitter.on(front, "new-promises", promises => {
+       for (let p of promises) {
+         if (p.promiseState.state === "fulfilled" &&
+             p.promiseState.value === resolution) {
+           resolve(p);
+         }
+       }
+     });
+   });
+ 
+   let start = Date.now();
+   let promise = makePromise(resolution);
+   let end = Date.now();
+ 
+-  let grip = yield onNewPromise;
++  let grip = await onNewPromise;
+   ok(grip, "Found our new promise.");
+ 
+   let creationTimestamp = grip.promiseState.creationTimestamp;
+ 
+   ok(start - 1 <= creationTimestamp && creationTimestamp <= end + 1,
+     "Expect promise creation timestamp to be within elapsed time range: " +
+      (start - 1) + " <= " + creationTimestamp + " <= " + (end + 1));
+ 
+-  yield front.detach();
++  await front.detach();
+   // Appease eslint
+   void promise;
+ }
+diff --git a/devtools/server/tests/unit/test_promises_object_timetosettle-01.js b/devtools/server/tests/unit/test_promises_object_timetosettle-01.js
+--- a/devtools/server/tests/unit/test_promises_object_timetosettle-01.js
++++ b/devtools/server/tests/unit/test_promises_object_timetosettle-01.js
+@@ -7,57 +7,57 @@
+  */
+ 
+ "use strict";
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ 
+ var EventEmitter = require("devtools/shared/event-emitter");
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("test-promises-timetosettle");
+-  let chromeActors = yield getChromeActors(client);
++add_task(async function () {
++  let client = await startTestDebuggerServer("test-promises-timetosettle");
++  let chromeActors = await getChromeActors(client);
+ 
+   ok(Promise.toString().includes("native code"), "Expect native DOM Promise.");
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testGetTimeToSettle(client, chromeActors, () => {
++  await attachTab(client, chromeActors);
++  await testGetTimeToSettle(client, chromeActors, () => {
+     let p = new Promise(() => {});
+     p.name = "p";
+     let q = p.then();
+     q.name = "q";
+ 
+     return p;
+   });
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "test-promises-timetosettle");
+   ok(targetTab, "Found our target tab.");
+ 
+-  yield testGetTimeToSettle(client, targetTab, () => {
++  await testGetTimeToSettle(client, targetTab, () => {
+     const debuggee =
+       DebuggerServer.getTestGlobal("test-promises-timetosettle");
+ 
+     let p = new debuggee.Promise(() => {});
+     p.name = "p";
+     let q = p.then();
+     q.name = "q";
+ 
+     return p;
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testGetTimeToSettle(client, form, makePromises) {
++async function testGetTimeToSettle(client, form, makePromises) {
+   let front = PromisesFront(client, form);
+ 
+-  yield front.attach();
+-  yield front.listPromises();
++  await front.attach();
++  await front.listPromises();
+ 
+   let onNewPromise = new Promise(resolve => {
+     EventEmitter.on(front, "new-promises", promises => {
+       for (let p of promises) {
+         if (p.promiseState.state === "pending") {
+           ok(!p.promiseState.timeToSettle,
+             "Expect no time to settle for unsettled promise.");
+         } else {
+@@ -68,13 +68,13 @@ function* testGetTimeToSettle(client, fo
+         }
+       }
+       resolve();
+     });
+   });
+ 
+   let promise = makePromises();
+ 
+-  yield onNewPromise;
+-  yield front.detach();
++  await onNewPromise;
++  await front.detach();
+   // Appease eslint
+   void promise;
+ }
+diff --git a/devtools/server/tests/unit/test_promises_object_timetosettle-02.js b/devtools/server/tests/unit/test_promises_object_timetosettle-02.js
+--- a/devtools/server/tests/unit/test_promises_object_timetosettle-02.js
++++ b/devtools/server/tests/unit/test_promises_object_timetosettle-02.js
+@@ -8,49 +8,49 @@
+ 
+ "use strict";
+ 
+ const { PromisesFront } = require("devtools/shared/fronts/promises");
+ const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm", {});
+ 
+ var EventEmitter = require("devtools/shared/event-emitter");
+ 
+-add_task(function* () {
+-  let client = yield startTestDebuggerServer("test-promises-timetosettle");
+-  let chromeActors = yield getChromeActors(client);
+-  yield attachTab(client, chromeActors);
++add_task(async function () {
++  let client = await startTestDebuggerServer("test-promises-timetosettle");
++  let chromeActors = await getChromeActors(client);
++  await attachTab(client, chromeActors);
+ 
+   ok(Promise.toString().includes("native code"), "Expect native DOM Promise.");
+ 
+   // We have to attach the chrome TabActor before playing with the PromiseActor
+-  yield attachTab(client, chromeActors);
+-  yield testGetTimeToSettle(client, chromeActors,
++  await attachTab(client, chromeActors);
++  await testGetTimeToSettle(client, chromeActors,
+     v => new Promise(resolve => setTimeout(() => resolve(v), 100)));
+ 
+-  let response = yield listTabs(client);
++  let response = await listTabs(client);
+   let targetTab = findTab(response.tabs, "test-promises-timetosettle");
+   ok(targetTab, "Found our target tab.");
+-  yield attachTab(client, targetTab);
++  await attachTab(client, targetTab);
+ 
+-  yield testGetTimeToSettle(client, targetTab, v => {
++  await testGetTimeToSettle(client, targetTab, v => {
+     const debuggee =
+       DebuggerServer.getTestGlobal("test-promises-timetosettle");
+     return new debuggee.Promise(resolve => setTimeout(() => resolve(v), 100));
+   });
+ 
+-  yield close(client);
++  await close(client);
+ });
+ 
+-function* testGetTimeToSettle(client, form, makePromise) {
++async function testGetTimeToSettle(client, form, makePromise) {
+   let front = PromisesFront(client, form);
+   let resolution = "MyLittleSecret" + Math.random();
+   let found = false;
+ 
+-  yield front.attach();
+-  yield front.listPromises();
++  await front.attach();
++  await front.listPromises();
+ 
+   let onNewPromise = new Promise(resolve => {
+     EventEmitter.on(front, "promises-settled", promises => {
+       for (let p of promises) {
+         if (p.promiseState.state === "fulfilled" &&
+             p.promiseState.value === resolution) {
+           let timeToSettle = Math.floor(p.promiseState.timeToSettle / 100) * 100;
+           ok(timeToSettle >= 100,
+@@ -62,14 +62,14 @@ function* testGetTimeToSettle(client, fo
+           dump("Found non-target promise.\n");
+         }
+       }
+     });
+   });
+ 
+   let promise = makePromise(resolution);
+ 
+-  yield onNewPromise;
++  await onNewPromise;
+   ok(found, "Found our new promise.");
+-  yield front.detach();
++  await front.detach();
+   // Appease eslint
+   void promise;
+ }
+diff --git a/devtools/server/tests/unit/test_protocolSpec.js b/devtools/server/tests/unit/test_protocolSpec.js
+--- a/devtools/server/tests/unit/test_protocolSpec.js
++++ b/devtools/server/tests/unit/test_protocolSpec.js
+@@ -1,19 +1,19 @@
+ "use strict";
+ 
+-const run_test = Test(function* () {
++const run_test = Test(async function () {
+   initTestDebuggerServer();
+   const connection = DebuggerServer.connectPipe();
+   const client = Async(new DebuggerClient(connection));
+ 
+-  yield client.connect();
++  await client.connect();
+ 
+-  const response = yield client.request({
++  const response = await client.request({
+     to: "root",
+     type: "protocolDescription"
+   });
+ 
+   assert(response.from == "root");
+   assert(typeof (response.types) === "object");
+ 
+-  yield client.close();
++  await client.close();
+ });
+diff --git a/devtools/server/tests/unit/test_protocol_formtype.js b/devtools/server/tests/unit/test_protocol_formtype.js
+--- a/devtools/server/tests/unit/test_protocol_formtype.js
++++ b/devtools/server/tests/unit/test_protocol_formtype.js
+@@ -136,45 +136,45 @@ var RootFront = protocol.FrontClassWithS
+     this.manage(this);
+   },
+ 
+   form(v, ctx, detail) {
+     this.lastForm = v;
+   }
+ });
+ 
+-const run_test = Test(function* () {
++const run_test = Test(async function () {
+   DebuggerServer.createRootActor = (conn => {
+     return RootActor(conn);
+   });
+   DebuggerServer.init();
+ 
+   const connection = DebuggerServer.connectPipe();
+   const conn = new DebuggerClient(connection);
+   const client = Async(conn);
+ 
+-  yield client.connect();
++  await client.connect();
+ 
+   let rootFront = RootFront(conn);
+ 
+   // Trigger some methods that return forms.
+-  let retval = yield rootFront.getDefault();
++  let retval = await rootFront.getDefault();
+   Assert.ok(retval instanceof RootFront);
+   Assert.ok(rootFront.lastForm.childActor instanceof ChildFront);
+ 
+-  retval = yield rootFront.getDetail1();
++  retval = await rootFront.getDetail1();
+   Assert.ok(retval instanceof RootFront);
+   Assert.ok(rootFront.lastForm.detailItem instanceof ChildFront);
+ 
+-  retval = yield rootFront.getDetail2();
++  retval = await rootFront.getDetail2();
+   Assert.ok(retval instanceof RootFront);
+   Assert.ok(typeof (rootFront.lastForm) === "string");
+ 
+   // getUnknownDetail should fail, since no typeName is specified.
+   try {
+-    yield rootFront.getUnknownDetail();
++    await rootFront.getUnknownDetail();
+     Assert.ok(false);
+   } catch (ex) {
+     // empty
+   }
+ 
+-  yield client.close();
++  await client.close();
+ });
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-column-in-gcd-script.js b/devtools/server/tests/unit/test_setBreakpoint-on-column-in-gcd-script.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-column-in-gcd-script.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-column-in-gcd-script.js
+@@ -1,42 +1,42 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-column-in-gcd-script.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     let global = testGlobal("test");
+     loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
+     Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+     DebuggerServer.addTestGlobal(global);
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+-    let { sources } = yield getSources(threadClient);
++    let { sources } = await getSources(threadClient);
+     let source = findSource(sources, SOURCE_URL);
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 6, column: 17 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       reload(tabClient).then(function () {
+         loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
+       });
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+@@ -45,14 +45,14 @@ function run_test() {
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     Assert.equal(where.column, location.column);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value, 1);
+     Assert.equal(variables.b.value.type, "undefined");
+     Assert.equal(variables.c.value.type, "undefined");
+-    yield resume(threadClient);
++    await resume(threadClient);
+ 
+-    yield close(client);
++    await close(client);
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js b/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
+@@ -1,39 +1,39 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-column-with-no-offsets-at-end-of-line.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+ 
+     let global = createTestGlobal("test");
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+     let promise = waitForNewSource(threadClient, SOURCE_URL);
+     loadSubScript(SOURCE_URL, global);
+-    let { source } = yield promise;
++    let { source } = await promise;
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 4, column: 23 };
+-    let [packet, ] = yield setBreakpoint(sourceClient, location);
++    let [packet, ] = await setBreakpoint(sourceClient, location);
+     Assert.ok(packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+     Cu.evalInSandbox("f()", global);
+-    yield close(client);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-column.js b/devtools/server/tests/unit/test_setBreakpoint-on-column.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-column.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-column.js
+@@ -1,42 +1,42 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-column.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+ 
+     let global = createTestGlobal("test");
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+     let promise = waitForNewSource(threadClient, SOURCE_URL);
+     loadSubScript(SOURCE_URL, global);
+-    let { source } = yield promise;
++    let { source } = await promise;
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 4, column: 17 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(!packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       Cu.evalInSandbox("f()", global);
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+     Assert.equal(why.actors[0], breakpointClient.actor);
+     let frame = packet.frame;
+@@ -44,14 +44,14 @@ function run_test() {
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     Assert.equal(where.column, location.column);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value, 1);
+     Assert.equal(variables.b.value.type, "undefined");
+     Assert.equal(variables.c.value.type, "undefined");
+ 
+-    yield resume(threadClient);
+-    yield close(client);
++    await resume(threadClient);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-line-in-gcd-script.js b/devtools/server/tests/unit/test_setBreakpoint-on-line-in-gcd-script.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-in-gcd-script.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-in-gcd-script.js
+@@ -1,42 +1,42 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-line-in-gcd-script.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     let global = createTestGlobal("test");
+     loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
+     Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+     DebuggerServer.addTestGlobal(global);
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+-    let { sources } = yield getSources(threadClient);
++    let { sources } = await getSources(threadClient);
+     let source = findSource(sources, SOURCE_URL);
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 7 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       reload(tabClient).then(function () {
+         loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
+       });
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+@@ -44,14 +44,14 @@ function run_test() {
+     let frame = packet.frame;
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value, 1);
+     Assert.equal(variables.b.value.type, "undefined");
+     Assert.equal(variables.c.value.type, "undefined");
+-    yield resume(threadClient);
++    await resume(threadClient);
+ 
+-    yield close(client);
++    await close(client);
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-offsets.js b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-offsets.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-offsets.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-offsets.js
+@@ -1,70 +1,70 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-line-with-multiple-offsets.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+ 
+     let global = createTestGlobal("test");
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
++    let [, tabClient] = await attachTab(client, tab);
+ 
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+     let promise = waitForNewSource(threadClient, SOURCE_URL);
+     loadSubScript(SOURCE_URL, global);
+-    let { source } = yield promise;
++    let { source } = await promise;
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 4 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(!packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       Cu.evalInSandbox("f()", global);
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+     Assert.equal(why.actors[0], breakpointClient.actor);
+     let frame = packet.frame;
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.i.value.type, "undefined");
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       resume(threadClient);
+     }, client);
+     Assert.equal(packet.type, "paused");
+     why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+     Assert.equal(why.actors[0], breakpointClient.actor);
+     frame = packet.frame;
+     where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     variables = frame.environment.bindings.variables;
+     Assert.equal(variables.i.value, 0);
+ 
+-    yield resume(threadClient);
+-    yield close(client);
++    await resume(threadClient);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-statements.js b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-statements.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-statements.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-statements.js
+@@ -1,57 +1,57 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-line-with-multiple-statements.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+ 
+     let global = createTestGlobal("test");
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
++    let [, tabClient] = await attachTab(client, tab);
+ 
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+     let promise = waitForNewSource(threadClient, SOURCE_URL);
+     loadSubScript(SOURCE_URL, global);
+-    let { source } = yield promise;
++    let { source } = await promise;
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 4 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(!packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       Cu.evalInSandbox("f()", global);
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+     Assert.equal(why.actors[0], breakpointClient.actor);
+     let frame = packet.frame;
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value.type, "undefined");
+     Assert.equal(variables.b.value.type, "undefined");
+     Assert.equal(variables.c.value.type, "undefined");
+ 
+-    yield resume(threadClient);
+-    yield close(client);
++    await resume(threadClient);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
+@@ -1,43 +1,43 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-line-with-no-offsets-in-gcd-script.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     let global = createTestGlobal("test");
+     loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
+     Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+-    let { sources } = yield getSources(threadClient);
++    let { sources } = await getSources(threadClient);
+     let source = findSource(sources, SOURCE_URL);
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 7 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       reload(tabClient).then(function () {
+         loadSubScriptWithOptions(SOURCE_URL, {target: global, ignoreCache: true});
+       });
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+@@ -45,14 +45,14 @@ function run_test() {
+     let frame = packet.frame;
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, 8);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value, 1);
+     Assert.equal(variables.c.value.type, "undefined");
+ 
+-    yield resume(threadClient);
+-    yield close(client);
++    await resume(threadClient);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets.js b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets.js
+@@ -1,57 +1,57 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-line-with-no-offsets.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+ 
+     let global = createTestGlobal("test");
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, tabClient] = await attachTab(client, tab);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+     let promise = waitForNewSource(threadClient, SOURCE_URL);
+     loadSubScript(SOURCE_URL, global);
+-    let { source } = yield promise;
++    let { source } = await promise;
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 5 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(!packet.isPending);
+     Assert.ok("actualLocation" in packet);
+     let actualLocation = packet.actualLocation;
+     Assert.equal(actualLocation.line, 6);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       Cu.evalInSandbox("f()", global);
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+     Assert.equal(why.actors[0], breakpointClient.actor);
+     let frame = packet.frame;
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, actualLocation.line);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value, 1);
+     Assert.equal(variables.c.value.type, "undefined");
+ 
+-    yield resume(threadClient);
+-    yield close(client);
++    await resume(threadClient);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-line.js b/devtools/server/tests/unit/test_setBreakpoint-on-line.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-line.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-on-line.js
+@@ -1,57 +1,57 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-line.js");
+ 
+ function run_test() {
+-  return Task.spawn(function* () {
++  return (async function () {
+     do_test_pending();
+ 
+     DebuggerServer.registerModule("xpcshell-test/testactors");
+     DebuggerServer.init(() => true);
+ 
+     let global = createTestGlobal("test");
+     DebuggerServer.addTestGlobal(global);
+ 
+     let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    yield connect(client);
++    await connect(client);
+ 
+-    let { tabs } = yield listTabs(client);
++    let { tabs } = await listTabs(client);
+     let tab = findTab(tabs, "test");
+-    let [, tabClient] = yield attachTab(client, tab);
++    let [, tabClient] = await attachTab(client, tab);
+ 
+-    let [, threadClient] = yield attachThread(tabClient);
+-    yield resume(threadClient);
++    let [, threadClient] = await attachThread(tabClient);
++    await resume(threadClient);
+ 
+     let promise = waitForNewSource(threadClient, SOURCE_URL);
+     loadSubScript(SOURCE_URL, global);
+-    let { source } = yield promise;
++    let { source } = await promise;
+     let sourceClient = threadClient.source(source);
+ 
+     let location = { line: 5 };
+-    let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
++    let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
+     Assert.ok(!packet.isPending);
+     Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = yield executeOnNextTickAndWaitForPause(function () {
++    packet = await executeOnNextTickAndWaitForPause(function () {
+       Cu.evalInSandbox("f()", global);
+     }, client);
+     Assert.equal(packet.type, "paused");
+     let why = packet.why;
+     Assert.equal(why.type, "breakpoint");
+     Assert.equal(why.actors.length, 1);
+     Assert.equal(why.actors[0], breakpointClient.actor);
+     let frame = packet.frame;
+     let where = frame.where;
+     Assert.equal(where.source.actor, source.actor);
+     Assert.equal(where.line, location.line);
+     let variables = frame.environment.bindings.variables;
+     Assert.equal(variables.a.value, 1);
+     Assert.equal(variables.b.value.type, "undefined");
+     Assert.equal(variables.c.value.type, "undefined");
+ 
+-    yield resume(threadClient);
+-    yield close(client);
++    await resume(threadClient);
++    await close(client);
+ 
+     do_test_finished();
+-  });
++  })();
+ }
+diff --git a/devtools/server/tests/unit/test_sourcemaps-03.js b/devtools/server/tests/unit/test_sourcemaps-03.js
+--- a/devtools/server/tests/unit/test_sourcemaps-03.js
++++ b/devtools/server/tests/unit/test_sourcemaps-03.js
+@@ -23,57 +23,57 @@ function run_test() {
+                              gThreadClient = threadClient;
+                              test_simple_source_map();
+                            });
+   });
+   do_test_pending();
+ }
+ 
+ function testBreakpointMapping(name, callback) {
+-  Task.spawn(function* () {
+-    let response = yield waitForPause(gThreadClient);
++  (async function () {
++    let response = await waitForPause(gThreadClient);
+     Assert.equal(response.why.type, "debuggerStatement");
+ 
+-    const source = yield getSource(gThreadClient, "http://example.com/www/js/" + name + ".js");
+-    response = yield setBreakpoint(source, {
++    const source = await getSource(gThreadClient, "http://example.com/www/js/" + name + ".js");
++    response = await setBreakpoint(source, {
+       // Setting the breakpoint on an empty line so that it is pushed down one
+       // line and we can check the source mapped actualLocation later.
+       line: 3
+     });
+ 
+     // Should not slide breakpoints for sourcemapped sources
+     Assert.ok(!response.actualLocation);
+ 
+-    yield setBreakpoint(source, { line: 4 });
++    await setBreakpoint(source, { line: 4 });
+ 
+     // The eval will cause us to resume, then we get an unsolicited pause
+     // because of our breakpoint, we resume again to finish the eval, and
+     // finally receive our last pause which has the result of the client
+     // evaluation.
+-    response = yield gThreadClient.eval(null, name + "()");
++    response = await gThreadClient.eval(null, name + "()");
+     Assert.equal(response.type, "resumed");
+ 
+-    response = yield waitForPause(gThreadClient);
++    response = await waitForPause(gThreadClient);
+     Assert.equal(response.why.type, "breakpoint");
+     // Assert that we paused because of the breakpoint at the correct
+     // location in the code by testing that the value of `ret` is still
+     // undefined.
+     Assert.equal(response.frame.environment.bindings.variables.ret.value.type,
+                  "undefined");
+ 
+-    response = yield resume(gThreadClient);
++    response = await resume(gThreadClient);
+ 
+-    response = yield waitForPause(gThreadClient);
++    response = await waitForPause(gThreadClient);
+     Assert.equal(response.why.type, "clientEvaluated");
+     Assert.equal(response.why.frameFinished.return, name);
+ 
+-    response = yield resume(gThreadClient);
++    response = await resume(gThreadClient);
+ 
+     callback();
+-  });
++  })();
+ 
+   gDebuggee.eval("(" + function () {
+     debugger;
+   } + "());");
+ }
+ 
+ function test_simple_source_map() {
+   let expectedSources = new Set([
+diff --git a/devtools/server/tests/unit/test_sourcemaps-16.js b/devtools/server/tests/unit/test_sourcemaps-16.js
+--- a/devtools/server/tests/unit/test_sourcemaps-16.js
++++ b/devtools/server/tests/unit/test_sourcemaps-16.js
+@@ -16,31 +16,30 @@ function run_test() {
+   gDebuggee = addTestGlobal("test-sourcemaps");
+   gClient = new DebuggerClient(DebuggerServer.connectPipe());
+   gClient.connect().then(function () {
+     attachTestThread(gClient, "test-sourcemaps", testSourcemap);
+   });
+   do_test_pending();
+ }
+ 
+-const testSourcemap = Task.async(
+-  function* (threadResponse, tabClient, threadClient, tabResponse) {
+-    evalTestCode();
++const testSourcemap = async function (threadResponse, tabClient, threadClient,
++  tabResponse) {
++  evalTestCode();
+ 
+-    const { sources } = yield getSources(threadClient);
++  const { sources } = await getSources(threadClient);
+ 
+-    for (let form of sources) {
+-      let sourceResponse = yield getSourceContent(threadClient.source(form));
+-      ok(sourceResponse, "Should be able to get the source response");
+-      ok(sourceResponse.source, "Should have the source text as well");
+-    }
++  for (let form of sources) {
++    let sourceResponse = await getSourceContent(threadClient.source(form));
++    ok(sourceResponse, "Should be able to get the source response");
++    ok(sourceResponse.source, "Should have the source text as well");
++  }
+ 
+-    finishClient(gClient);
+-  }
+-);
++  finishClient(gClient);
++};
+ 
+ const TEST_FILE = "babel_and_browserify_script_with_source_map.js";
+ 
+ function evalTestCode() {
+   const testFileContents = readFile(TEST_FILE);
+   Cu.evalInSandbox(testFileContents,
+                    gDebuggee,
+                    "1.8",
+diff --git a/devtools/server/tests/unit/test_stepping-07.js b/devtools/server/tests/unit/test_stepping-07.js
+--- a/devtools/server/tests/unit/test_stepping-07.js
++++ b/devtools/server/tests/unit/test_stepping-07.js
+@@ -21,55 +21,55 @@ function run_test() {
+ function run_test_with_server(server, callback) {
+   gCallback = callback;
+   initTestDebuggerServer(server);
+   gDebuggee = addTestGlobal("test-stepping", server);
+   gClient = new DebuggerClient(server.connectPipe());
+   gClient.connect(testSteppingAndReturns);
+ }
+ 
+-const testSteppingAndReturns = Task.async(function* () {
+-  const [attachResponse,, threadClient] = yield attachTestTabAndResume(gClient,
++const testSteppingAndReturns = async function () {
++  const [attachResponse,, threadClient] = await attachTestTabAndResume(gClient,
+                                                                        "test-stepping");
+   ok(!attachResponse.error, "Should not get an error attaching");
+ 
+   dumpn("Evaluating test code and waiting for first debugger statement");
+-  const dbgStmt1 = yield executeOnNextTickAndWaitForPause(evaluateTestCode, gClient);
++  const dbgStmt1 = await executeOnNextTickAndWaitForPause(evaluateTestCode, gClient);
+   equal(dbgStmt1.frame.where.line, 3,
+         "Should be at debugger statement on line 3");
+ 
+   dumpn("Testing stepping with implicit return");
+-  const step1 = yield stepOver(gClient, threadClient);
++  const step1 = await stepOver(gClient, threadClient);
+   equal(step1.frame.where.line, 4, "Should step to line 4");
+-  const step2 = yield stepOver(gClient, threadClient);
++  const step2 = await stepOver(gClient, threadClient);
+   equal(step2.frame.where.line, 7,
+         "Should step to line 7, the implicit return at the last line of the function");
+   // This assertion doesn't pass yet. You would need to do *another*
+   // step at the end of this function to get the frameFinished.
+   // See bug 923975.
+   //
+   // ok(step2.why.frameFinished, "This should be the implicit function return");
+ 
+   dumpn("Continuing and waiting for second debugger statement");
+-  const dbgStmt2 = yield resumeAndWaitForPause(gClient, threadClient);
++  const dbgStmt2 = await resumeAndWaitForPause(gClient, threadClient);
+   equal(dbgStmt2.frame.where.line, 12,
+         "Should be at debugger statement on line 3");
+ 
+   dumpn("Testing stepping with explicit return");
+-  const step3 = yield stepOver(gClient, threadClient);
++  const step3 = await stepOver(gClient, threadClient);
+   equal(step3.frame.where.line, 13, "Should step to line 13");
+-  const step4 = yield stepOver(gClient, threadClient);
++  const step4 = await stepOver(gClient, threadClient);
+   equal(step4.frame.where.line, 15, "Should step out of the function from line 15");
+   // This step is a bit funny, see bug 1013219 for details.
+-  const step5 = yield stepOver(gClient, threadClient);
++  const step5 = await stepOver(gClient, threadClient);
+   equal(step5.frame.where.line, 15, "Should step out of the function from line 15");
+   ok(step5.why.frameFinished, "This should be the explicit function return");
+ 
+   finishClient(gClient, gCallback);
+-});
++};
+ 
+ function evaluateTestCode() {
+   /* eslint-disable */
+   Cu.evalInSandbox(
+     `                                   //  1
+     function implicitReturn() {         //  2
+       debugger;                         //  3
+       if (this.someUndefinedProperty) { //  4
+diff --git a/devtools/server/tests/unit/test_symbols-01.js b/devtools/server/tests/unit/test_symbols-01.js
+--- a/devtools/server/tests/unit/test_symbols-01.js
++++ b/devtools/server/tests/unit/test_symbols-01.js
+@@ -20,17 +20,17 @@ function run_test() {
+                              add_task(testSymbols.bind(null, client, debuggee));
+                              run_next_test();
+                            });
+   });
+ 
+   do_test_pending();
+ }
+ 
+-function* testSymbols(client, debuggee) {
++async function testSymbols(client, debuggee) {
+   const evalCode = () => {
+     /* eslint-disable */
+     Cu.evalInSandbox(
+       "(" + function () {
+         var symbolWithName = Symbol("Chris");
+         var symbolWithoutName = Symbol();
+         var iteratorSymbol = Symbol.iterator;
+         debugger;
+@@ -38,17 +38,17 @@ function* testSymbols(client, debuggee) 
+       debuggee,
+       "1.8",
+       URL,
+       1
+     );
+     /* eslint-enable */
+   };
+ 
+-  const packet = yield executeOnNextTickAndWaitForPause(evalCode, client);
++  const packet = await executeOnNextTickAndWaitForPause(evalCode, client);
+   const {
+     symbolWithName,
+     symbolWithoutName,
+     iteratorSymbol
+   } = packet.frame.environment.bindings.variables;
+ 
+   equal(symbolWithName.value.type, "symbol");
+   equal(symbolWithName.value.name, "Chris");
+diff --git a/devtools/server/tests/unit/test_symbols-02.js b/devtools/server/tests/unit/test_symbols-02.js
+--- a/devtools/server/tests/unit/test_symbols-02.js
++++ b/devtools/server/tests/unit/test_symbols-02.js
+@@ -20,17 +20,17 @@ function run_test() {
+                              add_task(testSymbols.bind(null, client, debuggee));
+                              run_next_test();
+                            });
+   });
+ 
+   do_test_pending();
+ }
+ 
+-function* testSymbols(client, debuggee) {
++async function testSymbols(client, debuggee) {
+   const evalCode = () => {
+     /* eslint-disable */
+     Cu.evalInSandbox(
+       "(" + function () {
+         Symbol.prototype.toString = () => {
+           throw new Error("lololol");
+         };
+         var sym = Symbol("le troll");
+@@ -39,16 +39,16 @@ function* testSymbols(client, debuggee) 
+       debuggee,
+       "1.8",
+       URL,
+       1
+     );
+     /* eslint-enable */
+   };
+ 
+-  const packet = yield executeOnNextTickAndWaitForPause(evalCode, client);
++  const packet = await executeOnNextTickAndWaitForPause(evalCode, client);
+   const { sym } = packet.frame.environment.bindings.variables;
+ 
+   equal(sym.value.type, "symbol");
+   equal(sym.value.name, "le troll");
+ 
+   finishClient(client);
+ }
+diff --git a/devtools/server/websocket-server.js b/devtools/server/websocket-server.js
+--- a/devtools/server/websocket-server.js
++++ b/devtools/server/websocket-server.js
+@@ -1,16 +1,15 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ "use strict";
+ 
+ const { Cc, CC } = require("chrome");
+-const { Task } = require("devtools/shared/task");
+ const { executeSoon } = require("devtools/shared/DevToolsUtils");
+ const { delimitedRead } = require("devtools/shared/transport/stream-utils");
+ const CryptoHash = CC("@mozilla.org/security/hash;1", "nsICryptoHash", "initWithString");
+ const threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
+ 
+ // Limit the header size to put an upper bound on allocated memory
+ const HEADER_MAX_LEN = 8000;
+ 
+@@ -75,22 +74,22 @@ function writeString(output, data) {
+     wait();
+   });
+ }
+ 
+ /**
+  * Read HTTP request from async input stream.
+  * @return Request line (string) and Map of header names and values.
+  */
+-const readHttpRequest = Task.async(function* (input) {
++const readHttpRequest = async function (input) {
+   let requestLine = "";
+   let headers = new Map();
+ 
+   while (true) {
+-    let line = yield readLine(input);
++    let line = await readLine(input);
+     if (line.length == 0) {
+       break;
+     }
+ 
+     if (!requestLine) {
+       requestLine = line;
+     } else {
+       let colon = line.indexOf(":");
+@@ -100,17 +99,17 @@ const readHttpRequest = Task.async(funct
+ 
+       let name = line.slice(0, colon).toLowerCase();
+       let value = line.slice(colon + 1).trim();
+       headers.set(name, value);
+     }
+   }
+ 
+   return { requestLine, headers };
+-});
++};
+ 
+ /**
+  * Write HTTP response (array of strings) to async output stream.
+  */
+ function writeHttpResponse(output, response) {
+   let responseString = response.join("\r\n") + "\r\n\r\n";
+   return writeString(output, responseString);
+ }
+@@ -160,46 +159,46 @@ function computeKey(key) {
+   let hash = new CryptoHash("sha1");
+   hash.update(data, data.length);
+   return hash.finish(true);
+ }
+ 
+ /**
+  * Perform the server part of a WebSocket opening handshake on an incoming connection.
+  */
+-const serverHandshake = Task.async(function* (input, output) {
++const serverHandshake = async function (input, output) {
+   // Read the request
+-  let request = yield readHttpRequest(input);
++  let request = await readHttpRequest(input);
+ 
+   try {
+     // Check and extract info from the request
+     let { acceptKey } = processRequest(request);
+ 
+     // Send response headers
+-    yield writeHttpResponse(output, [
++    await writeHttpResponse(output, [
+       "HTTP/1.1 101 Switching Protocols",
+       "Upgrade: websocket",
+       "Connection: Upgrade",
+       `Sec-WebSocket-Accept: ${acceptKey}`,
+     ]);
+   } catch (error) {
+     // Send error response in case of error
+-    yield writeHttpResponse(output, [ "HTTP/1.1 400 Bad Request" ]);
++    await writeHttpResponse(output, [ "HTTP/1.1 400 Bad Request" ]);
+     throw error;
+   }
+-});
++};
+ 
+ /**
+  * Accept an incoming WebSocket server connection.
+  * Takes an established nsISocketTransport in the parameters.
+  * Performs the WebSocket handshake and waits for the WebSocket to open.
+  * Returns Promise with a WebSocket ready to send and receive messages.
+  */
+-const accept = Task.async(function* (transport, input, output) {
+-  yield serverHandshake(input, output);
++const accept = async function (transport, input, output) {
++  await serverHandshake(input, output);
+ 
+   let transportProvider = {
+     setListener(upgradeListener) {
+       // The onTransportAvailable callback shouldn't be called synchronously.
+       executeSoon(() => {
+         upgradeListener.onTransportAvailable(transport, input, output);
+       });
+     }
+@@ -210,11 +209,11 @@ const accept = Task.async(function* (tra
+     socket.addEventListener("close", () => {
+       input.close();
+       output.close();
+     });
+ 
+     socket.onopen = () => resolve(socket);
+     socket.onerror = err => reject(err);
+   });
+-});
++};
+ 
+ exports.accept = accept;

+ 22 - 23
mozilla-release/patches/1438489-60a1.patch

@@ -2,7 +2,7 @@
 # User Mark Banner <standard8@mozilla.com>
 # Date 1518696017 0
 # Node ID bd967c4c3c166053088a0c823935c36d8caf9cf6
-# Parent  957f3b8af870c72e1f758115d536fe6173bfd0bb
+# Parent  debe7125f479206ee46ebcc5ae4047dbcb47e4d9
 Bug 1438489 - Enable ESLint rule mozilla/use-services for devtools/. r=jdescottes
 
 MozReview-Commit-ID: FZscEA6Q3Kb
@@ -755,9 +755,9 @@ diff --git a/devtools/server/actors/thread.js b/devtools/server/actors/thread.js
  const DevToolsUtils = require("devtools/shared/DevToolsUtils");
  const flags = require("devtools/shared/flags");
  const { assert, dumpn } = DevToolsUtils;
- const promise = require("promise");
  const { DevToolsWorker } = require("devtools/shared/worker/worker");
-@@ -624,19 +624,17 @@ const ThreadActor = ActorClassWithSpec(t
+ const { threadSpec } = require("devtools/shared/specs/script");
+@@ -621,19 +621,17 @@ const ThreadActor = ActorClassWithSpec(t
     */
    _maybeListenToEvents: function (request) {
      // Break-on-DOMEvents is only supported in content debugging.
@@ -778,7 +778,7 @@ diff --git a/devtools/server/actors/thread.js b/devtools/server/actors/thread.js
     * listener early enough.
     */
    _onWindowReady: function () {
-@@ -775,24 +773,21 @@ const ThreadActor = ActorClassWithSpec(t
+@@ -772,24 +770,21 @@ const ThreadActor = ActorClassWithSpec(t
     * Return an array containing all the event listeners attached to the
     * specified event target and its ancestors in the event target chain.
     *
@@ -805,7 +805,7 @@ diff --git a/devtools/server/actors/thread.js b/devtools/server/actors/thread.js
            continue;
          }
          // Create a listener-like object suitable for our purposes.
-@@ -1079,25 +1074,22 @@ const ThreadActor = ActorClassWithSpec(t
+@@ -1076,25 +1071,22 @@ const ThreadActor = ActorClassWithSpec(t
      // This request is only supported in content debugging.
      if (!this.global) {
        return {
@@ -832,7 +832,7 @@ diff --git a/devtools/server/actors/thread.js b/devtools/server/actors/thread.js
          // Native event listeners don't provide any listenerObject or type and
          // are not that useful to a JS debugger.
          if (!listener || !handler.type) {
-@@ -1188,19 +1180,17 @@ const ThreadActor = ActorClassWithSpec(t
+@@ -1185,19 +1177,17 @@ const ThreadActor = ActorClassWithSpec(t
        frame.onStep = undefined;
        frame.onPop = undefined;
      }
@@ -1047,7 +1047,7 @@ diff --git a/devtools/server/main.js b/devtools/server/main.js
 diff --git a/devtools/server/performance/profiler.js b/devtools/server/performance/profiler.js
 --- a/devtools/server/performance/profiler.js
 +++ b/devtools/server/performance/profiler.js
-@@ -1,14 +1,14 @@
+@@ -1,34 +1,30 @@
  /* This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -1060,10 +1060,9 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
  loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
  loader.lazyRequireGetter(this, "DevToolsUtils", "devtools/shared/DevToolsUtils");
  loader.lazyRequireGetter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm", true);
- loader.lazyRequireGetter(this, "Task", "devtools/shared/task", true);
  
  // Events piped from system observers to Profiler instances.
-@@ -16,20 +16,16 @@ const PROFILER_SYSTEM_EVENTS = [
+ const PROFILER_SYSTEM_EVENTS = [
    "console-api-profiler",
    "profiler-started",
    "profiler-stopped"
@@ -1084,7 +1083,7 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
    // by the pref `devtools.performance.profiler.sample-rate-khz`.
    interval: 1,
    features: ["js"],
-@@ -102,20 +98,20 @@ const ProfilerManager = (function () {
+@@ -104,20 +100,20 @@ const ProfilerManager = (function () {
          entries: options.entries || DEFAULT_PROFILER_OPTIONS.entries,
          interval: options.interval || DEFAULT_PROFILER_OPTIONS.interval,
          features: options.features || DEFAULT_PROFILER_OPTIONS.features,
@@ -1107,17 +1106,18 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
            config.threadFilters.length
          );
        } catch (e) {
-@@ -135,17 +131,17 @@ const ProfilerManager = (function () {
-      * Attempts to stop the nsIProfiler module.
-      */
-     stop: function () {
+@@ -141,17 +137,17 @@ const ProfilerManager = (function () {
        // Actually stop the profiler only if the last client has stopped profiling.
        // Since this is used as a root actor, and the profiler module interacts
        // with the whole platform, we need to avoid a case in which the profiler
        // is stopped when there might be other clients still profiling.
-       if (this.length <= 1) {
+       // Also check for `started` to only stop the profiler when the actor
+       // actually started it. This is to prevent stopping the profiler initiated
+       // by some other code, like Talos.
+       if (this.length <= 1 && this.started) {
 -        nsIProfilerModule.StopProfiler();
 +        Services.profiler.StopProfiler();
+         this.started = false;
        }
        this._updateProfilerStatusPolling();
        return { started: false };
@@ -1125,8 +1125,7 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
  
      /**
       * Returns all the samples accumulated since the profiler was started,
-      * along with the current time. The data has the following format:
-@@ -178,43 +174,43 @@ const ProfilerManager = (function () {
+@@ -185,43 +181,43 @@ const ProfilerManager = (function () {
       *        when the profiler just started.
       * @param boolean stringify
       *        Whether or not the returned profile object should be a string or not to
@@ -1175,7 +1174,7 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
      },
  
      /**
-@@ -229,18 +225,18 @@ const ProfilerManager = (function () {
+@@ -236,18 +232,18 @@ const ProfilerManager = (function () {
  
      /**
       * Verifies whether or not the nsIProfiler module has started.
@@ -1196,7 +1195,7 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
          totalSize,
          generation
        };
-@@ -248,17 +244,17 @@ const ProfilerManager = (function () {
+@@ -255,17 +251,17 @@ const ProfilerManager = (function () {
  
      /**
       * Returns an array of objects that describes the shared libraries
@@ -1215,7 +1214,7 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
       *
       * @return {number}
       */
-@@ -379,17 +375,17 @@ const ProfilerManager = (function () {
+@@ -386,17 +382,17 @@ const ProfilerManager = (function () {
        this._updateProfilerStatusPolling();
      },
  
@@ -1234,7 +1233,7 @@ diff --git a/devtools/server/performance/profiler.js b/devtools/server/performan
        } else if (this._poller) {
          // No subscribers; turn off if it exists.
          this._poller.disarm();
-@@ -530,17 +526,17 @@ class Profiler {
+@@ -537,17 +533,17 @@ class Profiler {
      return { registered: response };
    }
  
@@ -1281,7 +1280,7 @@ new file mode 100644
 diff --git a/devtools/server/tests/unit/head_dbg.js b/devtools/server/tests/unit/head_dbg.js
 --- a/devtools/server/tests/unit/head_dbg.js
 +++ b/devtools/server/tests/unit/head_dbg.js
-@@ -40,19 +40,17 @@ const { DebuggerClient } = require("devt
+@@ -38,19 +38,17 @@ const { DebuggerClient } = require("devt
  const ObjectClient = require("devtools/shared/client/object-client");
  const { MemoryFront } = require("devtools/shared/fronts/memory");
  
@@ -1302,7 +1301,7 @@ diff --git a/devtools/server/tests/unit/head_dbg.js b/devtools/server/tests/unit
    // Create a directory for extensions.
    const profileDir = do_get_profile().clone();
    profileDir.append("extensions");
-@@ -314,18 +312,17 @@ var listener = {
+@@ -312,18 +310,17 @@ var listener = {
        dumpn("head_dbg.js observed a console message: " + string);
      } catch (_) {
        // Swallow everything to avoid console reentrancy errors. We did our best

+ 322 - 0
mozilla-release/patches/1440093-60a1.patch

@@ -0,0 +1,322 @@
+# HG changeset patch
+# User Jason Laster <jason.laster.11@gmail.com>
+# Date 1519295280 -7200
+# Node ID 5261ab013f200c7a40b7695a45f88dc60d9dc3d3
+# Parent  abf1d5c1648a7c3d7acfc1eb34e1efb009ab70de
+Bug 1440093 - Breakpoints at the end of a line are missed. r=jimb
+
+diff --git a/devtools/server/actors/source.js b/devtools/server/actors/source.js
+--- a/devtools/server/actors/source.js
++++ b/devtools/server/actors/source.js
+@@ -923,24 +923,30 @@ let SourceActor = ActorClassWithSpec(sou
+       for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
+         for (let { columnNumber: column, offset } of columnToOffsetMap) {
+           if (column >= generatedColumn && column <= generatedLastColumn) {
+             entryPoints.push({ script, offsets: [offset] });
+           }
+         }
+       }
+ 
+-      // If we don't find any matching entrypoints, then
+-      // we should check to see if the breakpoint is to the left of the first offset.
++      // If we don't find any matching entrypoints,
++      // then we should see if the breakpoint comes before or after the column offsets.
+       if (entryPoints.length === 0) {
+         for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
+           if (columnToOffsetMap.length > 0) {
+-            let { columnNumber: column, offset } = columnToOffsetMap[0];
+-            if (generatedColumn < column) {
+-              entryPoints.push({ script, offsets: [offset] });
++            const firstColumnOffset = columnToOffsetMap[0];
++            const lastColumnOffset = columnToOffsetMap[columnToOffsetMap.length - 1];
++
++            if (generatedColumn < firstColumnOffset.columnNumber) {
++              entryPoints.push({ script, offsets: [firstColumnOffset.offset] });
++            }
++
++            if (generatedColumn > lastColumnOffset.columnNumber) {
++              entryPoints.push({ script, offsets: [lastColumnOffset.offset] });
+             }
+           }
+         }
+       }
+     }
+ 
+     if (entryPoints.length === 0) {
+       return false;
+diff --git a/devtools/server/tests/unit/setBreakpoint-on-column-with-no-offsets-at-end-of-line.js b/devtools/server/tests/unit/setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
+deleted file mode 100644
+--- a/devtools/server/tests/unit/setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
++++ /dev/null
+@@ -1,6 +0,0 @@
+-"use strict";
+-
+-function f() {
+-  var a = 1; var b = 2;
+-  var c = 3;
+-}
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js b/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js
+--- a/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js
++++ b/devtools/server/tests/unit/test_setBreakpoint-at-the-beginning-of-a-line.js
+@@ -1,64 +1,59 @@
+ "use strict";
+ 
+ var SOURCE_URL = getFileUrl("setBreakpoint-on-column.js");
+ 
+-function run_test() {
+-  return async function () {
+-    do_test_pending();
++async function run_test() {
++  do_test_pending();
++  DebuggerServer.registerModule("xpcshell-test/testactors");
++  DebuggerServer.init(() => true);
++  let global = createTestGlobal("test");
++  DebuggerServer.addTestGlobal(global);
+ 
+-    DebuggerServer.registerModule("xpcshell-test/testactors");
+-    DebuggerServer.init(() => true);
+-
+-    let global = createTestGlobal("test");
+-    DebuggerServer.addTestGlobal(global);
+-
+-    let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    await connect(client);
++  let client = new DebuggerClient(DebuggerServer.connectPipe());
++  await connect(client);
+ 
+-    let { tabs } = await listTabs(client);
+-    let tab = findTab(tabs, "test");
+-    let [, tabClient] = await attachTab(client, tab);
+-    let [, threadClient] = await attachThread(tabClient);
+-    await resume(threadClient);
++  let { tabs } = await listTabs(client);
++  let tab = findTab(tabs, "test");
++  let [, tabClient] = await attachTab(client, tab);
++  let [, threadClient] = await attachThread(tabClient);
++  await resume(threadClient);
+ 
+-    let promise = waitForNewSource(threadClient, SOURCE_URL);
+-    loadSubScript(SOURCE_URL, global);
+-    let { source } = await promise;
+-    let sourceClient = threadClient.source(source);
++  let promise = waitForNewSource(threadClient, SOURCE_URL);
++  loadSubScript(SOURCE_URL, global);
++  let { source } = await promise;
++  let sourceClient = threadClient.source(source);
+ 
+-    let location = { line: 4, column: 2 };
+-    let [packet, breakpointClient] = await setBreakpoint(
+-      sourceClient,
+-      location
+-    );
++  let location = { line: 4, column: 2 };
++  let [packet, breakpointClient] = await setBreakpoint(
++    sourceClient,
++    location
++  );
+ 
+-    Assert.ok(!packet.isPending);
+-    Assert.equal(false, "actualLocation" in packet);
++  Assert.ok(!packet.isPending);
++  Assert.equal(false, "actualLocation" in packet);
+ 
+-    packet = await executeOnNextTickAndWaitForPause(function () {
+-      Cu.evalInSandbox("f()", global);
+-    }, client);
++  packet = await executeOnNextTickAndWaitForPause(function () {
++    Cu.evalInSandbox("f()", global);
++  }, client);
+ 
+-    Assert.equal(packet.type, "paused");
+-    let why = packet.why;
+-    Assert.equal(why.type, "breakpoint");
+-    Assert.equal(why.actors.length, 1);
+-    Assert.equal(why.actors[0], breakpointClient.actor);
++  Assert.equal(packet.type, "paused");
++  let why = packet.why;
++  Assert.equal(why.type, "breakpoint");
++  Assert.equal(why.actors.length, 1);
++  Assert.equal(why.actors[0], breakpointClient.actor);
+ 
+-    let frame = packet.frame;
+-    let where = frame.where;
+-    Assert.equal(where.source.actor, source.actor);
+-    Assert.equal(where.line, location.line);
+-    Assert.equal(where.column, 6);
++  let frame = packet.frame;
++  let where = frame.where;
++  Assert.equal(where.source.actor, source.actor);
++  Assert.equal(where.line, location.line);
++  Assert.equal(where.column, 6);
+ 
+-    let variables = frame.environment.bindings.variables;
+-    Assert.equal(variables.a.value.type, "undefined");
+-    Assert.equal(variables.b.value.type, "undefined");
+-    Assert.equal(variables.c.value.type, "undefined");
++  let variables = frame.environment.bindings.variables;
++  Assert.equal(variables.a.value.type, "undefined");
++  Assert.equal(variables.b.value.type, "undefined");
++  Assert.equal(variables.c.value.type, "undefined");
+ 
+-    await resume(threadClient);
+-    await close(client);
+-
+-    do_test_finished();
+-  };
++  await resume(threadClient);
++  await close(client);
++  do_test_finished();
+ }
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-at-the-end-of-a-line.js b/devtools/server/tests/unit/test_setBreakpoint-at-the-end-of-a-line.js
+new file mode 100644
+--- /dev/null
++++ b/devtools/server/tests/unit/test_setBreakpoint-at-the-end-of-a-line.js
+@@ -0,0 +1,62 @@
++"use strict";
++
++var SOURCE_URL = getFileUrl("setBreakpoint-on-column.js");
++
++async function run_test() {
++  do_test_pending();
++
++  DebuggerServer.registerModule("xpcshell-test/testactors");
++  DebuggerServer.init(() => true);
++
++  let global = createTestGlobal("test");
++  DebuggerServer.addTestGlobal(global);
++
++  let client = new DebuggerClient(DebuggerServer.connectPipe());
++  await connect(client);
++
++  let { tabs } = await listTabs(client);
++  let tab = findTab(tabs, "test");
++  let [, tabClient] = await attachTab(client, tab);
++  let [, threadClient] = await attachThread(tabClient);
++  await resume(threadClient);
++
++  let promise = waitForNewSource(threadClient, SOURCE_URL);
++  loadSubScript(SOURCE_URL, global);
++  let { source } = await promise;
++  let sourceClient = threadClient.source(source);
++
++  let location = { line: 4, column: 42 };
++  let [packet, breakpointClient] = await setBreakpoint(
++    sourceClient,
++    location
++  );
++
++  Assert.ok(!packet.isPending);
++  Assert.equal(false, "actualLocation" in packet);
++
++  packet = await executeOnNextTickAndWaitForPause(function () {
++    Cu.evalInSandbox("f()", global);
++  }, client);
++
++  Assert.equal(packet.type, "paused");
++  let why = packet.why;
++  Assert.equal(why.type, "breakpoint");
++  Assert.equal(why.actors.length, 1);
++  Assert.equal(why.actors[0], breakpointClient.actor);
++
++  let frame = packet.frame;
++  let where = frame.where;
++  Assert.equal(where.source.actor, source.actor);
++  Assert.equal(where.line, location.line);
++  Assert.equal(where.column, 28);
++
++  let variables = frame.environment.bindings.variables;
++  Assert.equal(variables.a.value, 1);
++  Assert.equal(variables.b.value, 2);
++  Assert.equal(variables.c.value.type, "undefined");
++
++  await resume(threadClient);
++  await close(client);
++
++  do_test_finished();
++}
+diff --git a/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js b/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
+deleted file mode 100644
+--- a/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
++++ /dev/null
+@@ -1,39 +0,0 @@
+-"use strict";
+-
+-var SOURCE_URL = getFileUrl("setBreakpoint-on-column-with-no-offsets-at-end-of-line.js");
+-
+-function run_test() {
+-  return (async function () {
+-    do_test_pending();
+-
+-    DebuggerServer.registerModule("xpcshell-test/testactors");
+-    DebuggerServer.init(() => true);
+-
+-    let global = createTestGlobal("test");
+-    DebuggerServer.addTestGlobal(global);
+-
+-    let client = new DebuggerClient(DebuggerServer.connectPipe());
+-    await connect(client);
+-
+-    let { tabs } = await listTabs(client);
+-    let tab = findTab(tabs, "test");
+-    let [, tabClient] = await attachTab(client, tab);
+-    let [, threadClient] = await attachThread(tabClient);
+-    await resume(threadClient);
+-
+-    let promise = waitForNewSource(threadClient, SOURCE_URL);
+-    loadSubScript(SOURCE_URL, global);
+-    let { source } = await promise;
+-    let sourceClient = threadClient.source(source);
+-
+-    let location = { line: 4, column: 23 };
+-    let [packet, ] = await setBreakpoint(sourceClient, location);
+-    Assert.ok(packet.isPending);
+-    Assert.equal(false, "actualLocation" in packet);
+-
+-    Cu.evalInSandbox("f()", global);
+-    await close(client);
+-
+-    do_test_finished();
+-  })();
+-}
+diff --git a/devtools/server/tests/unit/xpcshell.ini b/devtools/server/tests/unit/xpcshell.ini
+--- a/devtools/server/tests/unit/xpcshell.ini
++++ b/devtools/server/tests/unit/xpcshell.ini
+@@ -16,17 +16,16 @@ support-files =
+   registertestactors-02.js
+   registertestactors-03.js
+   sourcemapped.js
+   testactors.js
+   hello-actor.js
+   setBreakpoint-on-column.js
+   setBreakpoint-on-column-in-gcd-script.js
+   setBreakpoint-on-column-with-no-offsets.js
+-  setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
+   setBreakpoint-on-column-with-no-offsets-in-gcd-script.js
+   setBreakpoint-on-line.js
+   setBreakpoint-on-line-in-gcd-script.js
+   setBreakpoint-on-line-with-multiple-offsets.js
+   setBreakpoint-on-line-with-multiple-statements.js
+   setBreakpoint-on-line-with-no-offsets.js
+   setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
+   addons/web-extension/manifest.json
+@@ -215,19 +214,19 @@ reason = bug 937197
+ [test_client_request.js]
+ [test_symbols-01.js]
+ [test_symbols-02.js]
+ [test_get-executable-lines.js]
+ [test_get-executable-lines-source-map.js]
+ [test_xpcshell_debugging.js]
+ support-files = xpcshell_debugging_script.js
+ [test_setBreakpoint-at-the-beginning-of-a-line.js]
++[test_setBreakpoint-at-the-end-of-a-line.js]
+ [test_setBreakpoint-on-column.js]
+ [test_setBreakpoint-on-column-in-gcd-script.js]
+-[test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js]
+ [test_setBreakpoint-on-line.js]
+ [test_setBreakpoint-on-line-in-gcd-script.js]
+ [test_setBreakpoint-on-line-with-multiple-offsets.js]
+ [test_setBreakpoint-on-line-with-multiple-statements.js]
+ [test_setBreakpoint-on-line-with-no-offsets.js]
+ [test_setBreakpoint-on-line-with-no-offsets-in-gcd-script.js]
+ [test_safe-getter.js]
+ [test_client_close.js]

+ 67 - 0
mozilla-release/patches/1440102-60a1.patch

@@ -0,0 +1,67 @@
+# HG changeset patch
+# User Julian Descottes <jdescottes@mozilla.com>
+# Date 1519309121 -3600
+# Node ID 195a3f9c9d2b3ec4d94c1cd9244d1241c62a224b
+# Parent  ac7e2ee701f90d1ac6338d94cad05e297568838c
+Bug 1440102 - increase timeout for browser_dbg-babel-scopes.js and reenable on win ccov;r=jlast
+
+MozReview-Commit-ID: 2by2m5WkPf
+
+diff --git a/devtools/client/debugger/new/test/mochitest/browser.ini b/devtools/client/debugger/new/test/mochitest/browser.ini
+--- a/devtools/client/debugger/new/test/mochitest/browser.ini
++++ b/devtools/client/debugger/new/test/mochitest/browser.ini
+@@ -113,17 +113,16 @@ support-files =
+   examples/script-mutate.js
+   examples/script-switching-02.js
+   examples/script-switching-01.js
+   examples/times2.js
+ 
+ [browser_dbg-asm.js]
+ [browser_dbg-async-stepping.js]
+ [browser_dbg-babel-scopes.js]
+-skip-if = (os == "win" && ccov) # bug 1438797
+ [browser_dbg-babel-stepping.js]
+ [browser_dbg-breaking.js]
+ [browser_dbg-breaking-from-console.js]
+ [browser_dbg-breakpoints.js]
+ [browser_dbg-breakpoints-toggle.js]
+ [browser_dbg-breakpoints-reloading.js]
+ [browser_dbg-breakpoints-cond.js]
+ [browser_dbg-browser-content-toolbox.js]
+diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-scopes.js b/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-scopes.js
+--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-scopes.js
++++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-scopes.js
+@@ -1,11 +1,14 @@
+ /* Any copyright is dedicated to the Public Domain.
+  * http://creativecommons.org/publicdomain/zero/1.0/ */
+ 
++// This test can be really slow on debug platforms and should be split
++requestLongerTimeout(4);
++
+ // Tests loading sourcemapped sources for Babel's compile output.
+ 
+ async function breakpointScopes(dbg, fixture, { line, column }, scopes) {
+   const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
+ 
+   const filename = `fixtures/${fixture}/input.js`;
+   await waitForSources(dbg, filename);
+ 
+@@ -81,18 +84,16 @@ async function assertScopes(dbg, items) 
+       is(getScopeLabel(dbg, i + 1), val);
+     }
+   }
+ 
+   is(getScopeLabel(dbg, items.length + 1), "Window");
+ }
+ 
+ add_task(async function() {
+-  requestLongerTimeout(3);
+-
+   await pushPref("devtools.debugger.features.map-scopes", true);
+ 
+   const dbg = await initDebugger("doc-babel.html");
+ 
+   await breakpointScopes(dbg, "for-of", { line: 5, column: 4 }, [
+     "For",
+     ["x", "1"],
+     "forOf",

File diff suppressed because it is too large
+ 462 - 0
mozilla-release/patches/1441635-1-61a1.patch


File diff suppressed because it is too large
+ 2202 - 0
mozilla-release/patches/1441635-2-61a1.patch


File diff suppressed because it is too large
+ 642 - 0
mozilla-release/patches/1445081-1-61a1.patch


File diff suppressed because it is too large
+ 2860 - 0
mozilla-release/patches/1445081-2-61a1.patch


File diff suppressed because it is too large
+ 1507 - 0
mozilla-release/patches/1445496-61a1.patch


+ 5 - 5
mozilla-release/patches/TOP-NOBUG-killtelemetry-debugger-25319.patch

@@ -1,13 +1,13 @@
 # HG changeset patch
 # User Ian Neal <iann_cvs@blueyonder.co.uk>
 # Date 1703010866 0
-# Parent  111c95db034fae2fa0d3b5804b55e5733bc66503
+# Parent  dfb6c07761b035161b9761f2218b3d381589b6cb
 No Bug - Kill telemetry code in debugger. r=me a=me
 
 diff --git a/devtools/client/debugger/new/debugger.js b/devtools/client/debugger/new/debugger.js
 --- a/devtools/client/debugger/new/debugger.js
 +++ b/devtools/client/debugger/new/debugger.js
-@@ -15348,18 +15348,16 @@ function _interopRequireDefault(obj) { r
+@@ -11239,18 +11239,16 @@ function _interopRequireDefault(obj) { r
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  
  /* This Source Code Form is subject to the terms of the Mozilla Public
@@ -26,7 +26,7 @@ diff --git a/devtools/client/debugger/new/debugger.js b/devtools/client/debugger
  
    const response = await client.sourceContents(id);
  
-@@ -15371,17 +15369,16 @@ async function loadSource(source, { sour
+@@ -11262,17 +11260,16 @@ async function loadSource(source, { sour
  }
  
  /**
@@ -44,7 +44,7 @@ diff --git a/devtools/client/debugger/new/debugger.js b/devtools/client/debugger
      }
  
      const id = source.get("id");
-@@ -15411,20 +15408,16 @@ function loadSourceText(source) {
+@@ -11302,20 +11299,16 @@ function loadSourceText(source) {
  
      if (!newSource.isWasm) {
        await parser.setSource(newSource);
@@ -62,6 +62,6 @@ diff --git a/devtools/client/debugger/new/debugger.js b/devtools/client/debugger
  
  /***/ }),
  
- /***/ 3227:
+ /***/ 1436:
  /***/ (function(module, exports, __webpack_require__) {
  

+ 14 - 1
mozilla-release/patches/series

@@ -5799,6 +5799,7 @@ TOP-1707096-91a1.patch
 1429121-2-59a1.patch
 1425273-2-59a1.patch
 1429908-59a1.patch
+1422061-59a1.patch
 1430855-59a1.patch
 1421389-59a1.patch
 1421225-60a1.patch
@@ -5827,6 +5828,7 @@ TOP-1707096-91a1.patch
 1436110-1-60a1.patch
 1436110-2-60a1.patch
 1436110-3-60a1.patch
+1436978-60a1.patch
 1434155-1-60a1.patch
 1434155-2-60a1.patch
 1403450-60a1.patch
@@ -5834,9 +5836,11 @@ TOP-1707096-91a1.patch
 1429803-1-60a1.patch
 1429803-2-60a1.patch
 1438014-60a1.patch
+1437828-60a1.patch
 1393609-60a1.patch
 1438489-60a1.patch
 1438797-60a1.patch
+1436151-60a1.patch
 1438463-60a1.patch
 1439371-60a1.patch
 1438930-60a1.patch
@@ -5847,6 +5851,7 @@ TOP-1707096-91a1.patch
 1434792-60a1.patch
 1439471-60a1.patch
 1428433-60a1.patch
+1440093-60a1.patch
 1439673-60a1.patch
 1439991-1-60a1.patch
 1439991-2-60a1.patch
@@ -5859,14 +5864,22 @@ TOP-1707096-91a1.patch
 1382606-60a1.patch
 1419350-1-60a1.patch
 1419350-2-60a1.patch
+1248498-60a1.patch
 1439839-60a1.patch
+1424154-60a1.patch
 1443121-60a1.patch
+1440102-60a1.patch
 1443193-60a1.patch
 1154874-60a1.patch
 1434855-1-60a1.patch
 1434855-2-60a1.patch
 1434885-60a1.patch
 1434849-60a1.patch
+1441635-1-61a1.patch
+1441635-2-61a1.patch
+1445081-1-61a1.patch
+1445081-2-61a1.patch
+1445496-61a1.patch
 1444594-61a1.patch
 1434848-68a1.patch
 TOP-NOBUG-killtelemetry-debugger-25319.patch
@@ -5883,4 +5896,4 @@ TOP-NOBUG-killtelemetry-debugger-25319.patch
 1420811-59a1.patch
 1432112-60a1.patch
 1432520-60a1.patch
-1431050-60a1.patch
+1431050-61a1.patch

Some files were not shown because too many files changed in this diff