Bug 876277 - Cleanup debugger location changes, sources switching and sources cache tests, r=past
authorVictor Porof <vporof@mozilla.com>
Fri, 13 Sep 2013 16:23:18 +0300
changeset 147089 5f626c9dd0660bbbd145616119b884dcab404a37
parent 147088 39471a71749473661a0093050cf993fc2c962125
child 147090 862a066d90d573b13f3157b4fd286061496bb29a
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerspast
bugs876277
milestone26.0a1
Bug 876277 - Cleanup debugger location changes, sources switching and sources cache tests, r=past
browser/devtools/debugger/test/browser_dbg_editor-mode.js
browser/devtools/debugger/test/browser_dbg_location-changes-01-simple.js
browser/devtools/debugger/test/browser_dbg_location-changes-02-blank.js
browser/devtools/debugger/test/browser_dbg_location-changes-03-new.js
browser/devtools/debugger/test/browser_dbg_location-changes-04-breakpoint.js
browser/devtools/debugger/test/browser_dbg_location-changes-blank.js
browser/devtools/debugger/test/browser_dbg_location-changes-bp.js
browser/devtools/debugger/test/browser_dbg_location-changes-new.js
browser/devtools/debugger/test/browser_dbg_location-changes.js
browser/devtools/debugger/test/browser_dbg_propertyview-01.js
browser/devtools/debugger/test/browser_dbg_scripts-sorting.js
browser/devtools/debugger/test/browser_dbg_scripts-switching-01.js
browser/devtools/debugger/test/browser_dbg_scripts-switching-02.js
browser/devtools/debugger/test/browser_dbg_scripts-switching-03.js
browser/devtools/debugger/test/browser_dbg_scripts-switching.js
browser/devtools/debugger/test/browser_dbg_sources-cache.js
browser/devtools/debugger/test/browser_dbg_sources-labels.js
browser/devtools/debugger/test/browser_dbg_sources-sorting.js
browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
rename from browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
rename to browser/devtools/debugger/test/browser_dbg_editor-mode.js
--- a/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
+++ b/browser/devtools/debugger/test/browser_dbg_editor-mode.js
@@ -1,145 +1,93 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure that updating the editor mode sets the right highlighting engine,
- * and script URIs with extra query parameters also get the right engine.
+ * and source URIs with extra query parameters also get the right engine.
  */
 
-const TAB_URL = EXAMPLE_URL + "browser_dbg_update-editor-mode.html";
-
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var gSources = null;
+const TAB_URL = EXAMPLE_URL + "doc_editor-mode.html";
 
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
-  let testStarted = false;
-  let resumed = false;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources;
 
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
-    resumed = true;
-
-    gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
-
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      executeSoon(startTest);
-    });
-
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
-  });
-
-  function onScriptShown(aEvent) {
-    scriptShown = aEvent.detail.url.indexOf("test-editor-mode") != -1;
-    executeSoon(startTest);
-  }
-
-  function startTest()
-  {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
-      testStarted = true;
-      Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
-    }
-  }
-}
-
-function testScriptsDisplay() {
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
-
-  is(gSources.itemCount, 3,
-    "Found the expected number of scripts.");
-
-  is(gDebugger.editor.getMode(), SourceEditor.MODES.TEXT,
-     "Found the expected editor mode.");
-
-  ok(gDebugger.editor.getText().search(/debugger/) != -1,
-    "The correct script was loaded initially.");
-
-  gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("switching-01.js") != -1) {
-      gDebugger.removeEventListener(aEvent.type, _onEvent);
-      testSwitchPaused1();
-    }
-  });
 
-  let url = gDebuggee.document.querySelector("script").src;
-  gDebugger.DebuggerView.Sources.selectedValue = url;
-}
-
-function testSwitchPaused1()
-{
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
-
-  is(gSources.itemCount, 3,
-    "Found the expected number of scripts.");
-
-  ok(gDebugger.editor.getText().search(/debugger/) == -1,
-    "The second script is no longer displayed.");
-
-  ok(gDebugger.editor.getText().search(/firstCall/) != -1,
-    "The first script is displayed.");
-
-  is(gDebugger.editor.getMode(), SourceEditor.MODES.JAVASCRIPT,
-     "Found the expected editor mode.");
+    waitForSourceAndCaretAndScopes(gPanel, "code_test-editor-mode", 5)
+      .then(testInitialSource)
+      .then(testSwitch1)
+      .then(testSwitch2)
+      .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
 
-  gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("update-editor-mode") != -1) {
-      gDebugger.removeEventListener(aEvent.type, _onEvent);
-      testSwitchPaused2();
-    }
-  });
-
-  let label = "browser_dbg_update-editor-mode.html";
-  gDebugger.DebuggerView.Sources.selectedLabel = label;
-}
-
-function testSwitchPaused2()
-{
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
-
-  is(gSources.itemCount, 3,
-    "Found the expected number of scripts.");
-
-  ok(gDebugger.editor.getText().search(/firstCall/) == -1,
-    "The first script is no longer displayed.");
-
-  ok(gDebugger.editor.getText().search(/debugger/) == -1,
-    "The second script is no longer displayed.");
-
-  ok(gDebugger.editor.getText().search(/banana/) != -1,
-    "The third script is displayed.");
-
-  is(gDebugger.editor.getMode(), SourceEditor.MODES.HTML,
-     "Found the expected editor mode.");
-
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    closeDebuggerAndFinish();
+    gDebuggee.firstCall();
   });
 }
 
+function testInitialSource() {
+  is(gSources.itemCount, 3,
+    "Found the expected number of sources.");
+
+  is(gEditor.getMode(), SourceEditor.MODES.TEXT,
+    "Found the expected editor mode.");
+  is(gEditor.getText().search(/firstCall/), -1,
+    "The first source is not displayed.");
+  is(gEditor.getText().search(/debugger/), 141,
+    "The second source is displayed.");
+  is(gEditor.getText().search(/banana/), -1,
+    "The third source is not displayed.");
+
+  let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
+  gSources.selectedLabel = "code_script-switching-01.js";
+  return finished;
+}
+
+function testSwitch1() {
+  is(gSources.itemCount, 3,
+    "Found the expected number of sources.");
+
+  is(gEditor.getMode(), SourceEditor.MODES.JAVASCRIPT,
+    "Found the expected editor mode.");
+  is(gEditor.getText().search(/firstCall/), 118,
+    "The first source is displayed.");
+  is(gEditor.getText().search(/debugger/), -1,
+    "The second source is not displayed.");
+  is(gEditor.getText().search(/banana/), -1,
+    "The third source is not displayed.");
+
+  let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
+  gSources.selectedLabel = "doc_editor-mode.html";
+  return finished;
+}
+
+function testSwitch2() {
+  is(gSources.itemCount, 3,
+    "Found the expected number of sources.");
+
+  is(gEditor.getMode(), SourceEditor.MODES.HTML,
+    "Found the expected editor mode.");
+  is(gEditor.getText().search(/firstCall/), -1,
+    "The first source is not displayed.");
+  is(gEditor.getText().search(/debugger/), -1,
+    "The second source is not displayed.");
+  is(gEditor.getText().search(/banana/), 443,
+    "The third source is displayed.");
+}
+
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
   gSources = null;
 });
rename from browser/devtools/debugger/test/browser_dbg_location-changes.js
rename to browser/devtools/debugger/test/browser_dbg_location-changes-01-simple.js
--- a/browser/devtools/debugger/test/browser_dbg_location-changes.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-01-simple.js
@@ -1,69 +1,78 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure that changing the tab location URL works.
  */
 
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
+const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
 
-function test()
-{
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources, gFrames;
+
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
+    gFrames = gDebugger.DebuggerView.StackFrames;
 
-    testSimpleCall();
+    waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
+    gDebuggee.simpleCall();
   });
 }
 
-function testSimpleCall() {
-  gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-    Services.tm.currentThread.dispatch({
-      run: function() {
-        var frames = gDebugger.DebuggerView.StackFrames.widget._list,
-            childNodes = frames.childNodes;
+function performTest() {
+  is(gDebugger.gThreadClient.state, "paused",
+    "Should only be getting stack frames while paused.");
 
-        is(gDebugger.DebuggerController.activeThread.state, "paused",
-          "Should only be getting stack frames while paused.");
+  is(gFrames.itemCount, 1,
+    "Should have only one frame.");
+
+  is(gSources.itemCount, 1,
+    "Found the expected number of entries in the sources widget.");
 
-        is(frames.querySelectorAll(".dbg-stackframe").length, 1,
-          "Should have only one frame.");
-
-        is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
-          "All children should be frames.");
+  isnot(gSources.selectedLabel, null,
+    "There should be a selected source label.");
+  isnot(gSources.selectedValue, null,
+    "There should be a selected source value.");
+  isnot(gEditor.getText().length, 0,
+    "The source editor should have some text displayed.");
+  isnot(gEditor.getText(), gDebugger.L10N.getStr("loadingText"),
+    "The source editor text should not be 'Loading...'");
 
-        testLocationChange();
-      }
-    }, 0);
+  is(gSources.widget.getAttribute("label"), "doc_recursion-stack.html",
+    "The sources widget should have a correct label attribute.");
+  is(gSources.widget.getAttribute("tooltiptext"), "example.com test",
+    "The sources widget should have a correct tooltip text attribute.");
+
+  is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice-container").length, 0,
+    "The sources widget should not display any notice at this point (1).");
+  is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice").length, 0,
+    "The sources widget should not display any notice at this point (2).");
+  is(gDebugger.document.querySelector(".side-menu-widget-empty-notice > label"), null,
+    "The sources widget should not display a notice at this point (3).");
+
+  gDebugger.gThreadClient.resume(() => {
+    testLocationChange();
   });
-
-  gDebuggee.simpleCall();
 }
 
-function testLocationChange()
-{
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
-      ok(true, "tabNavigated event was fired.");
-      info("Still attached to the tab.");
-
-      closeDebuggerAndFinish();
-    });
-    gDebugger.DebuggerController.client.activeTab.navigateTo(TAB1_URL);
+function testLocationChange() {
+  navigateActiveTabTo(gPanel, "about:blank", gDebugger.EVENTS.SOURCES_ADDED).then(() => {
+    closeDebuggerAndFinish(gPanel);
   });
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
+  gSources = null;
+  gFrames = null;
 });
rename from browser/devtools/debugger/test/browser_dbg_location-changes-blank.js
rename to browser/devtools/debugger/test/browser_dbg_location-changes-02-blank.js
--- a/browser/devtools/debugger/test/browser_dbg_location-changes-blank.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-02-blank.js
@@ -1,108 +1,71 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Make sure that changing the tab location URL to a page with no scripts works.
+ * Make sure that changing the tab location URL to a page with no sources works.
  */
 
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
+const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
 
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources, gFrames;
 
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
+    gFrames = gDebugger.DebuggerView.StackFrames;
 
-    gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-      let url = aEvent.detail.url;
-      if (url.indexOf("browser_dbg_stack") != -1) {
-        scriptShown = true;
-        gDebugger.removeEventListener(aEvent.type, _onEvent);
-        runTest();
-      }
-    });
-
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      runTest();
-    });
-
+    waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(testLocationChange);
     gDebuggee.simpleCall();
   });
-
-  function runTest()
-  {
-    if (scriptShown && framesAdded) {
-      Services.tm.currentThread.dispatch({ run: testSimpleCall }, 0);
-    }
-  }
 }
 
-function testSimpleCall() {
-  var frames = gDebugger.DebuggerView.StackFrames.widget._list,
-      childNodes = frames.childNodes;
-
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
-
-  is(frames.querySelectorAll(".dbg-stackframe").length, 1,
-    "Should have only one frame.");
+function testLocationChange() {
+  navigateActiveTabTo(gPanel, "about:blank", gDebugger.EVENTS.SOURCES_ADDED).then(() => {
+    isnot(gDebugger.gThreadClient.state, "paused",
+      "Should not be paused after a tab navigation.");
 
-  is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
-    "All children should be frames.");
+    is(gFrames.itemCount, 0,
+      "Should have no frames.");
 
-  isnot(gDebugger.DebuggerView.Sources.selectedValue, null,
-    "There should be a selected script.");
-  isnot(gDebugger.editor.getText().length, 0,
-    "The source editor should have some text displayed.");
-  isnot(gDebugger.editor.getText(), gDebugger.L10N.getStr("loadingText"),
-    "The source editor text should not be 'Loading...'");
-
-  testLocationChange();
-}
+    is(gSources.itemCount, 0,
+      "Found no entries in the sources widget.");
 
-function testLocationChange()
-{
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
-      ok(true, "tabNavigated event was fired.");
-      info("Still attached to the tab.");
-
-      gDebugger.addEventListener("Debugger:AfterSourcesAdded", function _onEvent(aEvent) {
-        gDebugger.removeEventListener(aEvent.type, _onEvent);
+    is(gSources.selectedLabel, "",
+      "There should be no selected source label.");
+    is(gSources.selectedValue, "",
+      "There should be no selected source value.");
+    is(gEditor.getText().length, 0,
+      "The source editor should not have any text displayed.");
 
-        is(gDebugger.DebuggerView.Sources.selectedValue, "",
-          "There should be no selected script.");
-        is(gDebugger.editor.getText().length, 0,
-          "The source editor not have any text displayed.");
+    is(gSources.widget.getAttribute("label"), gDebugger.L10N.getStr("noSourcesText"),
+      "The sources widget should display a notice that there are no sources availalble.");
+    is(gSources.widget.getAttribute("tooltiptext"), "",
+      "The sources widget shouldn't have any tooltip text attribute when there are no sources available.");
 
-        let menulist = gDebugger.DebuggerView.Sources.widget;
-        let noScripts = gDebugger.L10N.getStr("noSourcesText");
-        is(menulist.getAttribute("label"), noScripts,
-          "The menulist should display a notice that there are no scripts availalble.");
-        is(menulist.getAttribute("tooltiptext"), "",
-          "The menulist shouldn't have any tooltip text attributed when there are no scripts available.");
+    is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice-container").length, 1,
+      "The sources widget should now display a notice (1).");
+    is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice").length, 1,
+      "The sources widget should now display a notice (2).");
+    is(gDebugger.document.querySelector(".side-menu-widget-empty-notice").getAttribute("value"),
+       gSources.widget.getAttribute("label"),
+      "The sources widget should now display a notice (3).");
 
-        closeDebuggerAndFinish();
-      });
-    });
-    gDebugger.DebuggerController.client.activeTab.navigateTo("about:blank");
+    closeDebuggerAndFinish(gPanel);
   });
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
+  gSources = null;
+  gFrames = null;
 });
rename from browser/devtools/debugger/test/browser_dbg_location-changes-new.js
rename to browser/devtools/debugger/test/browser_dbg_location-changes-03-new.js
--- a/browser/devtools/debugger/test/browser_dbg_location-changes-new.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-03-new.js
@@ -1,109 +1,73 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Make sure that changing the tab location URL to a page with other scripts works.
+ * Make sure that changing the tab location URL to a page with other sources works.
  */
 
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
+const TAB_URL_1 = EXAMPLE_URL + "doc_recursion-stack.html";
+const TAB_URL_2 = EXAMPLE_URL + "doc_iframes.html";
 
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources, gFrames;
 
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL_1).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
+    gFrames = gDebugger.DebuggerView.StackFrames;
 
-    gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-      let url = aEvent.detail.url;
-      if (url.indexOf("browser_dbg_stack") != -1) {
-        scriptShown = true;
-        gDebugger.removeEventListener(aEvent.type, _onEvent);
-        runTest();
-      }
-    });
-
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      runTest();
-    });
-
+    waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(testLocationChange);
     gDebuggee.simpleCall();
   });
-
-  function runTest()
-  {
-    if (scriptShown && framesAdded) {
-      Services.tm.currentThread.dispatch({ run: testSimpleCall }, 0);
-    }
-  }
 }
 
-function testSimpleCall() {
-  var frames = gDebugger.DebuggerView.StackFrames.widget._list,
-      childNodes = frames.childNodes;
-
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
-
-  is(frames.querySelectorAll(".dbg-stackframe").length, 1,
-    "Should have only one frame.");
+function testLocationChange() {
+  navigateActiveTabTo(gPanel, TAB_URL_2, gDebugger.EVENTS.SOURCES_ADDED).then(() => {
+    isnot(gDebugger.gThreadClient.state, "paused",
+      "Should not be paused after a tab navigation.");
 
-  is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
-    "All children should be frames.");
+    is(gFrames.itemCount, 0,
+      "Should have no frames.");
 
-  isnot(gDebugger.DebuggerView.Sources.selectedValue, null,
-    "There should be a selected script.");
-  isnot(gDebugger.editor.getText().length, 0,
-    "The source editor should have some text displayed.");
-  isnot(gDebugger.editor.getText(), gDebugger.L10N.getStr("loadingText"),
-    "The source editor text should not be 'Loading...'");
-
-  testLocationChange();
-}
+    is(gSources.itemCount, 1,
+      "Found the expected number of entries in the sources widget.");
 
-function testLocationChange()
-{
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
-      ok(true, "tabNavigated event was fired.");
-      info("Still attached to the tab.");
-
-      gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-        gDebugger.removeEventListener(aEvent.type, _onEvent);
+    is(gSources.selectedLabel, "doc_inline-debugger-statement.html",
+      "There should be a selected source label.");
+    is(gSources.selectedValue, EXAMPLE_URL + "doc_inline-debugger-statement.html",
+      "There should be a selected source value.");
+    isnot(gEditor.getText().length, 0,
+      "The source editor should have some text displayed.");
+    is(gEditor.getText(), gDebugger.L10N.getStr("loadingText"),
+      "The source editor text should not be 'Loading...'");
 
-        isnot(gDebugger.DebuggerView.Sources.selectedValue, null,
-          "There should be a selected script.");
-        isnot(gDebugger.editor.getText().length, 0,
-          "The source editor should have some text displayed.");
+    is(gSources.widget.getAttribute("label"), "doc_inline-debugger-statement.html",
+      "The sources widget should have a correct label attribute.");
+    is(gSources.widget.getAttribute("tooltiptext"), "example.com test",
+      "The sources widget should have a correct tooltip text attribute.");
 
-        let menulist = gDebugger.DebuggerView.Sources.widget;
-        let noScripts = gDebugger.L10N.getStr("noSourcesText");
-        isnot(menulist.getAttribute("label"), noScripts,
-          "The menulist should not display a notice that there are no scripts availalble.");
-        isnot(menulist.getAttribute("tooltiptext"), "",
-          "The menulist should have a tooltip text attributed.");
+    is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice-container").length, 0,
+      "The sources widget should not display any notice at this point (1).");
+    is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice").length, 0,
+      "The sources widget should not display any notice at this point (2).");
+    is(gDebugger.document.querySelector(".side-menu-widget-empty-notice > label"), null,
+      "The sources widget should not display a notice at this point (3).");
 
-        closeDebuggerAndFinish();
-      });
-    });
-    let newLocation = EXAMPLE_URL + "browser_dbg_iframes.html";
-    gDebugger.DebuggerController.client.activeTab.navigateTo(newLocation);
+    closeDebuggerAndFinish(gPanel);
   });
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
+  gSources = null;
+  gFrames = null;
 });
rename from browser/devtools/debugger/test/browser_dbg_location-changes-bp.js
rename to browser/devtools/debugger/test/browser_dbg_location-changes-04-breakpoint.js
--- a/browser/devtools/debugger/test/browser_dbg_location-changes-bp.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-04-breakpoint.js
@@ -1,163 +1,197 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure that reloading a page with a breakpoint set does not cause it to
  * fire more than once.
  */
 
-const TAB_URL = EXAMPLE_URL + "test-location-changes-bp.html";
-const SCRIPT_URL = EXAMPLE_URL + "test-location-changes-bp.js";
+const TAB_URL = EXAMPLE_URL + "doc_included-script.html";
+const SOURCE_URL = EXAMPLE_URL + "code_location-changes.js";
 
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var sourcesShown = false;
-var tabNavigated = false;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources;
 
-function test()
-{
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
 
-    testAddBreakpoint();
+    waitForSourceAndCaretAndScopes(gPanel, ".html", 17).then(addBreakpoint);
+    gDebuggee.runDebuggerStatement();
   });
 }
 
-function testAddBreakpoint()
-{
-  let controller = gDebugger.DebuggerController;
-  controller.activeThread.addOneTimeListener("framesadded", function() {
-    Services.tm.currentThread.dispatch({ run: function() {
-
-      var frames = gDebugger.DebuggerView.StackFrames.widget._list;
+function addBreakpoint() {
+  waitForSourceAndCaret(gPanel, ".js", 5).then(() => {
+    ok(true,
+      "Switched to the desired function when adding a breakpoint " +
+      "but not passing { noEditorUpdate: true } as an option.");
 
-      is(controller.activeThread.state, "paused",
-         "The debugger statement was reached.");
-
-      is(frames.querySelectorAll(".dbg-stackframe").length, 1,
-         "Should have one frame.");
-
-      gPane.addBreakpoint({ url: SCRIPT_URL, line: 5 }, testResume);
-    }}, 0);
+    testResume();
   });
 
-  gDebuggee.runDebuggerStatement();
-}
-
-function testResume()
-{
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "The breakpoint wasn't hit yet.");
-
-  let thread = gDebugger.DebuggerController.activeThread;
-  thread.addOneTimeListener("resumed", function() {
-    thread.addOneTimeListener("paused", function() {
-      executeSoon(testBreakpointHit);
-    });
-
-    EventUtils.sendMouseEvent({ type: "click" },
-      content.document.querySelector("button"));
-  });
-
-  thread.resume();
+  gPanel.addBreakpoint({ url: SOURCE_URL, line: 5 });
 }
 
-function testBreakpointHit()
-{
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "The breakpoint was hit.");
+function testResume() {
+  is(gDebugger.gThreadClient.state, "paused",
+    "The breakpoint wasn't hit yet (1).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (1).");
+  ok(isCaretPos(gPanel, 5),
+    "The source editor caret position is incorrect (1).");
 
-  let thread = gDebugger.DebuggerController.activeThread;
-  thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
-    thread.addOneTimeListener("resumed", function() {
-      executeSoon(testReloadPage);
-    });
-
-    is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
-    isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
-    thread.resume();
-  });
-
-  thread.resume();
+  gDebugger.gThreadClient.resume(testClick);
 }
 
-function testReloadPage()
-{
-  let controller = gDebugger.DebuggerController;
-  controller._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
-    tabNavigated = true;
-    ok(true, "tabNavigated event was fired.");
-    info("Still attached to the tab.");
-    clickAgain();
-  });
-
-  gDebugger.addEventListener("Debugger:SourceShown", function onSourcesShown() {
-    sourcesShown = true;
-    gDebugger.removeEventListener("Debugger:SourceShown", onSourcesShown);
-    clickAgain();
-  });
-
-  gDebugger.DebuggerController.client.activeTab.reload();
-}
+function testClick() {
+  isnot(gDebugger.gThreadClient.state, "paused",
+    "The breakpoint wasn't hit yet (2).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (2).");
+  ok(isCaretPos(gPanel, 5),
+    "The source editor caret position is incorrect (2).");
 
-function clickAgain()
-{
-  if (!sourcesShown || !tabNavigated) {
-    return;
-  }
-
-  let controller = gDebugger.DebuggerController;
-  controller.activeThread.addOneTimeListener("paused", function(aEvent, aPacket) {
+  gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
     is(aPacket.why.type, "breakpoint",
-       "The breakpoint was hit.");
+      "Execution has advanced to the breakpoint.");
+    isnot(aPacket.why.type, "debuggerStatement",
+      "The breakpoint was hit before the debugger statement.");
 
-    let thread = gDebugger.DebuggerController.activeThread;
-    thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
-      thread.addOneTimeListener("resumed", function() {
-        executeSoon(closeDebuggerAndFinish);
-      });
-
-      is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
-      isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
-      thread.resume();
-    });
-
-    thread.resume();
+    afterBreakpointHit();
   });
 
   EventUtils.sendMouseEvent({ type: "click" },
-    content.document.querySelector("button"));
+    gDebuggee.document.querySelector("button"),
+    gDebuggee);
+}
+
+function afterBreakpointHit() {
+  is(gDebugger.gThreadClient.state, "paused",
+    "The breakpoint was hit (3).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (3).");
+  ok(isCaretPos(gPanel, 5),
+    "The source editor caret position is incorrect (3).");
+
+  gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
+    is(aPacket.why.type, "debuggerStatement",
+      "Execution has advanced to the next line.");
+    isnot(aPacket.why.type, "breakpoint",
+      "No ghost breakpoint was hit.");
+
+    ensureCaretAt(gPanel, 6, 1, true).then(afterDebuggerStatementHit);
+  });
+
+  gDebugger.gThreadClient.resume();
+}
+
+function afterDebuggerStatementHit() {
+  is(gDebugger.gThreadClient.state, "paused",
+    "The debugger statement was hit (4).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (4).");
+  ok(isCaretPos(gPanel, 6),
+    "The source editor caret position is incorrect (4).");
+
+  reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN)
+    .then(() => ensureThreadClientState(gPanel, "resumed"))
+    .then(() => testClickAgain());
+}
+
+function testClickAgain() {
+  isnot(gDebugger.gThreadClient.state, "paused",
+    "The breakpoint wasn't hit yet (5).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (5).");
+  ok(isCaretPos(gPanel, 1),
+    "The source editor caret position is incorrect (5).");
+
+  gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
+    is(aPacket.why.type, "breakpoint",
+      "Execution has advanced to the breakpoint.");
+    isnot(aPacket.why.type, "debuggerStatement",
+      "The breakpoint was hit before the debugger statement.");
+
+    ensureCaretAt(gPanel, 5, 1, true).then(afterBreakpointHitAgain);
+  });
+
+  EventUtils.sendMouseEvent({ type: "click" },
+    gDebuggee.document.querySelector("button"),
+    gDebuggee);
 }
 
-function testBreakpointHitAfterReload()
-{
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "The breakpoint was hit.");
+function afterBreakpointHitAgain() {
+  is(gDebugger.gThreadClient.state, "paused",
+    "The breakpoint was hit (6).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (6).");
+  ok(isCaretPos(gPanel, 5),
+    "The source editor caret position is incorrect (6).");
 
-  let thread = gDebugger.DebuggerController.activeThread;
-  thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
-    thread.addOneTimeListener("resumed", function() {
-      executeSoon(closeDebuggerAndFinish);
-    });
+  gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
+    is(aPacket.why.type, "debuggerStatement",
+      "Execution has advanced to the next line.");
+    isnot(aPacket.why.type, "breakpoint",
+      "No ghost breakpoint was hit.");
 
-    is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
-    isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
-    thread.resume();
+    ensureCaretAt(gPanel, 6, 1, true).then(afterDebuggerStatementHitAgain);
   });
 
-  thread.resume();
+  gDebugger.gThreadClient.resume();
+}
+
+function afterDebuggerStatementHitAgain() {
+  is(gDebugger.gThreadClient.state, "paused",
+    "The debugger statement was hit (7).");
+  is(gSources.selectedValue, SOURCE_URL,
+    "The currently shown source is incorrect (7).");
+  ok(isCaretPos(gPanel, 6),
+    "The source editor caret position is incorrect (7).");
+
+  showSecondSource();
+}
+
+function showSecondSource() {
+  gDebugger.once(gDebugger.EVENTS.SOURCE_SHOWN, () => {
+    is(gEditor.getText().indexOf("debugger"), 447,
+      "The correct source is shown in the source editor.")
+    is(gEditor.getBreakpoints().length, 0,
+      "No breakpoints should be shown for the second source.");
+
+    ensureCaretAt(gPanel, 1, 1, true).then(showFirstSourceAgain);
+  });
+
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    gDebugger.document.querySelectorAll(".side-menu-widget-item-contents")[1],
+    gDebugger);
+}
+
+function showFirstSourceAgain() {
+  gDebugger.once(gDebugger.EVENTS.SOURCE_SHOWN, () => {
+    is(gEditor.getText().indexOf("debugger"), 148,
+      "The correct source is shown in the source editor.")
+    is(gEditor.getBreakpoints().length, 1,
+      "One breakpoint should be shown for the first source.");
+
+    ensureCaretAt(gPanel, 6, 1, true).then(() => resumeDebuggerThenCloseAndFinish(gPanel));
+  });
+
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+    gDebugger.document.querySelectorAll(".side-menu-widget-item-contents")[0],
+    gDebugger);
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
+  gSources = null;
 });
rename from browser/devtools/debugger/test/browser_dbg_scripts-switching.js
rename to browser/devtools/debugger/test/browser_dbg_scripts-switching-01.js
--- a/browser/devtools/debugger/test/browser_dbg_scripts-switching.js
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-switching-01.js
@@ -1,178 +1,184 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Make sure that switching the displayed script in the UI works as advertised.
+ * Make sure that switching the displayed source in the UI works as advertised.
  */
 
-const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
-
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var gSources = null;
+const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
 
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
-  let resumed = false;
-  let testStarted = false;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources;
 
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
-    resumed = true;
-
-    gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
-
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      executeSoon(startTest);
-    });
-
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
-  });
-
-  function onScriptShown(aEvent)
-  {
-    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
-    executeSoon(startTest);
-  }
-
-  function startTest()
-  {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
-      testStarted = true;
-      Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
-    }
-  }
-}
-
-function testScriptsDisplay() {
-  gSources = gDebugger.DebuggerView.Sources;
-
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
-
-  is(gSources.itemCount, 2,
-    "Found the expected number of scripts.");
-
-  for (let i = 0; i < gSources.itemCount; i++) {
-    info("label: " + i + " " + gSources.getItemAtIndex(i).target.getAttribute("label"));
-  }
-
-  let label1 = "test-script-switching-01.js";
-  let label2 = "test-script-switching-02.js";
-
-  ok(gDebugger.DebuggerView.Sources.containsValue(EXAMPLE_URL +
-    label1), "First script url is incorrect.");
-  ok(gDebugger.DebuggerView.Sources.containsValue(EXAMPLE_URL +
-    label2), "Second script url is incorrect.");
-
-  ok(gDebugger.DebuggerView.Sources.containsLabel(
-    label1), "First script label is incorrect.");
-  ok(gDebugger.DebuggerView.Sources.containsLabel(
-    label2), "Second script label is incorrect.");
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
 
-  ok(gDebugger.DebuggerView.Sources.selectedItem,
-    "There should be a selected item in the sources pane.");
-  is(gDebugger.DebuggerView.Sources.selectedLabel,
-    label2, "The selected label is the sources pane is incorrect.");
-  is(gDebugger.DebuggerView.Sources.selectedValue, EXAMPLE_URL +
-    label2, "The selected value is the sources pane is incorrect.");
-
-  ok(gDebugger.editor.getText().search(/debugger/) != -1,
-    "The correct script was loaded initially.");
-
-  is(gDebugger.editor.getDebugLocation(), 5,
-     "editor debugger location is correct.");
-
-  gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-01.js") != -1) {
-      gDebugger.removeEventListener(aEvent.type, _onEvent);
-      testSwitchPaused();
-    }
-  });
-
-  gDebugger.DebuggerView.Sources.selectedValue = EXAMPLE_URL + label1;
-}
-
-function testSwitchPaused()
-{
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
+    waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6)
+      .then(testSourcesDisplay)
+      .then(testSwitchPaused1)
+      .then(testSwitchPaused2)
+      .then(testSwitchRunning)
+      .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
 
-  let label1 = "test-script-switching-01.js";
-  let label2 = "test-script-switching-02.js";
-
-  ok(gDebugger.DebuggerView.Sources.selectedItem,
-    "There should be a selected item in the sources pane.");
-  is(gDebugger.DebuggerView.Sources.selectedLabel,
-    label1, "The selected label is the sources pane is incorrect.");
-  is(gDebugger.DebuggerView.Sources.selectedValue, EXAMPLE_URL +
-    label1, "The selected value is the sources pane is incorrect.");
-
-  ok(gDebugger.editor.getText().search(/debugger/) == -1,
-    "The second script is no longer displayed.");
-
-  ok(gDebugger.editor.getText().search(/firstCall/) != -1,
-    "The first script is displayed.");
-
-  is(gDebugger.editor.getDebugLocation(), -1,
-    "Editor debugger location has been cleared.");
-
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-      let url = aEvent.detail.url;
-      if (url.indexOf("-02.js") != -1) {
-        gDebugger.removeEventListener(aEvent.type, _onEvent);
-        testSwitchRunning();
-      }
-    });
-
-    gDebugger.DebuggerView.Sources.selectedValue = EXAMPLE_URL + label2;
+    gDebuggee.firstCall();
   });
 }
 
-function testSwitchRunning()
-{
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
+let gLabel1 = "code_script-switching-01.js";
+let gLabel2 = "code_script-switching-02.js";
+
+function testSourcesDisplay() {
+  let deferred = promise.defer();
+
+  is(gSources.itemCount, 2,
+    "Found the expected number of sources.");
+
+  ok(gSources.containsValue(EXAMPLE_URL + gLabel1),
+    "First source url is incorrect.");
+  ok(gSources.containsValue(EXAMPLE_URL + gLabel2),
+    "Second source url is incorrect.");
+
+  ok(gSources.containsLabel(gLabel1),
+    "First source label is incorrect.");
+  ok(gSources.containsLabel(gLabel2),
+    "Second source label is incorrect.");
 
-  let label1 = "test-script-switching-01.js";
-  let label2 = "test-script-switching-02.js";
+  ok(gSources.selectedItem,
+    "There should be a selected item in the sources pane.");
+  is(gSources.selectedLabel, gLabel2,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel2,
+    "The selected value is the sources pane is incorrect.");
+
+  is(gEditor.getText().search(/firstCall/), -1,
+    "The first source is not displayed.");
+  is(gEditor.getText().search(/debugger/), 172,
+    "The second source is displayed.");
+
+  ok(isCaretPos(gPanel, 6),
+    "Editor caret location is correct.");
 
-  ok(gDebugger.DebuggerView.Sources.selectedItem,
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    is(gEditor.getDebugLocation(), 5,
+      "Editor debugger location is correct.");
+
+    waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
+    gSources.selectedIndex = 0;
+  });
+
+  return deferred.promise;
+}
+
+function testSwitchPaused1() {
+  let deferred = promise.defer();
+
+  ok(gSources.selectedItem,
     "There should be a selected item in the sources pane.");
-  is(gDebugger.DebuggerView.Sources.selectedLabel,
-    label2, "The selected label is the sources pane is incorrect.");
-  is(gDebugger.DebuggerView.Sources.selectedValue, EXAMPLE_URL +
-    label2, "The selected value is the sources pane is incorrect.");
+  is(gSources.selectedLabel, gLabel1,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel1,
+    "The selected value is the sources pane is incorrect.");
+
+  is(gEditor.getText().search(/firstCall/), 118,
+    "The first source is displayed.");
+  is(gEditor.getText().search(/debugger/), -1,
+    "The second source is not displayed.");
+
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    ok(isCaretPos(gPanel, 1),
+      "Editor caret location is correct.");
+    is(gEditor.getDebugLocation(), -1,
+      "Editor debugger location is correct.");
 
-  ok(gDebugger.editor.getText().search(/debugger/) != -1,
-    "The second script is displayed again.");
+    waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
+    gSources.selectedIndex = 1;
+  });
+
+  return deferred.promise;
+}
+
+function testSwitchPaused2() {
+  let deferred = promise.defer();
+
+  ok(gSources.selectedItem,
+    "There should be a selected item in the sources pane.");
+  is(gSources.selectedLabel, gLabel2,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel2,
+    "The selected value is the sources pane is incorrect.");
+
+  is(gEditor.getText().search(/firstCall/), -1,
+    "The first source is not displayed.");
+  is(gEditor.getText().search(/debugger/), 172,
+    "The second source is displayed.");
 
-  ok(gDebugger.editor.getText().search(/firstCall/) == -1,
-    "The first script is no longer displayed.");
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    ok(isCaretPos(gPanel, 6),
+      "Editor caret location is correct.");
+    is(gEditor.getDebugLocation(), 5,
+      "Editor debugger location is correct.");
+
+    // Step out three times.
+    waitForThreadEvents(gPanel, "paused").then(() => {
+      waitForThreadEvents(gPanel, "paused").then(() => {
+        waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
+        gDebugger.gThreadClient.stepOut();
+      });
+      gDebugger.gThreadClient.stepOut();
+    });
+    gDebugger.gThreadClient.stepOut();
+  });
+
+  return deferred.promise;
+}
+
+function testSwitchRunning() {
+  let deferred = promise.defer();
 
-  is(gDebugger.editor.getDebugLocation(), -1,
-    "Editor debugger location is still -1.");
+  ok(gSources.selectedItem,
+    "There should be a selected item in the sources pane.");
+  is(gSources.selectedLabel, gLabel1,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel1,
+    "The selected value is the sources pane is incorrect.");
+
+  is(gEditor.getText().search(/firstCall/), 118,
+    "The first source is displayed.");
+  is(gEditor.getText().search(/debugger/), -1,
+    "The second source is not displayed.");
 
-  closeDebuggerAndFinish();
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    ok(isCaretPos(gPanel, 5),
+      "Editor caret location is correct.");
+    is(gEditor.getDebugLocation(), 4,
+      "Editor debugger location is correct.");
+
+    deferred.resolve();
+  });
+
+  return deferred.promise;
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
   gSources = null;
+  gLabel1 = null;
+  gLabel2 = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_scripts-switching-02.js
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-switching-02.js
@@ -1,175 +1,186 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Make sure that switching the displayed script in the UI works as advertised
- * when urls are escaped.
+ * Make sure that switching the displayed source in the UI works as advertised.
  */
 
-const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching-02.html";
-
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var gSources = null;
+const TAB_URL = EXAMPLE_URL + "doc_script-switching-02.html";
 
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
-  let resumed = false;
-  let testStarted = false;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources;
 
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
-    resumed = true;
-
-    gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
 
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      executeSoon(startTest);
-    });
+    waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6)
+      .then(testSourcesDisplay)
+      .then(testSwitchPaused1)
+      .then(testSwitchPaused2)
+      .then(testSwitchRunning)
+      .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
 
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
+    gDebuggee.firstCall();
   });
-
-  function onScriptShown(aEvent)
-  {
-    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
-    executeSoon(startTest);
-  }
-
-  function startTest()
-  {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
-      testStarted = true;
-      Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
-    }
-  }
 }
 
-function testScriptsDisplay() {
-  gSources = gDebugger.DebuggerView.Sources;
+let gLabel1 = "code_script-switching-01.js";
+let gLabel2 = "code_script-switching-02.js";
+let gParams = "?foo=bar,baz|lol";
 
-  is(gDebugger.DebuggerController.activeThread.state, "paused",
-    "Should only be getting stack frames while paused.");
+function testSourcesDisplay() {
+  let deferred = promise.defer();
 
   is(gSources.itemCount, 2,
-    "Found the expected number of scripts.");
-
-  for (let i = 0; i < gSources.itemCount; i++) {
-    info("label: " + i + " " + gSources.getItemAtIndex(i).target.getAttribute("label"));
-  }
-
-  let label1 = "test-script-switching-01.js";
-  let label2 = "test-script-switching-02.js";
-  let params = "?foo=bar,baz|lol";
+    "Found the expected number of sources.");
 
-  ok(gDebugger.DebuggerView.Sources.containsValue(EXAMPLE_URL +
-    label1), "First script url is incorrect.");
-  ok(gDebugger.DebuggerView.Sources.containsValue(EXAMPLE_URL +
-    label2 + params), "Second script url is incorrect.");
+  ok(gSources.containsValue(EXAMPLE_URL + gLabel1),
+    "First source url is incorrect.");
+  ok(gSources.containsValue(EXAMPLE_URL + gLabel2 + gParams),
+    "Second source url is incorrect.");
 
-  ok(gDebugger.DebuggerView.Sources.containsLabel(
-    label1), "First script label is incorrect.");
-  ok(gDebugger.DebuggerView.Sources.containsLabel(
-    label2), "Second script label is incorrect.");
+  ok(gSources.containsLabel(gLabel1),
+    "First source label is incorrect.");
+  ok(gSources.containsLabel(gLabel2),
+    "Second source label is incorrect.");
 
-  ok(gDebugger.DebuggerView.Sources.selectedItem,
+  ok(gSources.selectedItem,
     "There should be a selected item in the sources pane.");
-  is(gDebugger.DebuggerView.Sources.selectedLabel,
-    label2, "The selected label is the sources pane is incorrect.");
-  is(gDebugger.DebuggerView.Sources.selectedValue, EXAMPLE_URL +
-    label2 + params, "The selected value is the sources pane is incorrect.");
-
-  ok(gDebugger.editor.getText().search(/debugger/) != -1,
-    "The correct script was loaded initially.");
+  is(gSources.selectedLabel, gLabel2,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel2 + gParams,
+    "The selected value is the sources pane is incorrect.");
 
-  is(gDebugger.editor.getDebugLocation(), 5,
-    "Editor debugger location is correct.");
+  is(gEditor.getText().search(/firstCall/), -1,
+    "The first source is not displayed.");
+  is(gEditor.getText().search(/debugger/), 172,
+    "The second source is displayed.");
+
+  ok(isCaretPos(gPanel, 6),
+    "Editor caret location is correct.");
 
-  gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-01.js") != -1) {
-      gDebugger.removeEventListener(aEvent.type, _onEvent);
-      testSwitch1();
-    }
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    is(gEditor.getDebugLocation(), 5,
+      "Editor debugger location is correct.");
+
+    waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
+    gSources.selectedLabel = gLabel1;
   });
 
-  gDebugger.DebuggerView.Sources.selectedValue = EXAMPLE_URL + label1;
+  return deferred.promise;
 }
 
-function testSwitch1() {
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
-
-  let label1 = "test-script-switching-01.js";
-  let label2 = "test-script-switching-02.js";
-  let params = "?foo=bar,baz|lol";
+function testSwitchPaused1() {
+  let deferred = promise.defer();
 
-  ok(gDebugger.DebuggerView.Sources.selectedItem,
+  ok(gSources.selectedItem,
     "There should be a selected item in the sources pane.");
-  is(gDebugger.DebuggerView.Sources.selectedLabel,
-    label1, "The selected label is the sources pane is incorrect.");
-  is(gDebugger.DebuggerView.Sources.selectedValue, EXAMPLE_URL +
-    label1, "The selected value is the sources pane is incorrect.");
+  is(gSources.selectedLabel, gLabel1,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel1,
+    "The selected value is the sources pane is incorrect.");
 
-  ok(gDebugger.editor.getText().search(/debugger/) == -1,
-    "The second script is no longer displayed.");
-
-  ok(gDebugger.editor.getText().search(/firstCall/) != -1,
-    "The first script is displayed.");
+  is(gEditor.getText().search(/firstCall/), 118,
+    "The first source is displayed.");
+  is(gEditor.getText().search(/debugger/), -1,
+    "The second source is not displayed.");
 
-  is(gDebugger.editor.getDebugLocation(), -1,
-    "Editor debugger location has been cleared.");
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    ok(isCaretPos(gPanel, 1),
+      "Editor caret location is correct.");
+    is(gEditor.getDebugLocation(), -1,
+      "Editor debugger location is correct.");
 
-  gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-02.js") != -1) {
-      gDebugger.removeEventListener(aEvent.type, _onEvent);
-      testSwitch2();
-    }
+    waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
+    gSources.selectedLabel = gLabel2;
   });
 
-  gDebugger.DebuggerView.Sources.selectedValue = EXAMPLE_URL + label2 + params;
+  return deferred.promise;
 }
 
-function testSwitch2() {
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
+function testSwitchPaused2() {
+  let deferred = promise.defer();
 
-  let label1 = "test-script-switching-01.js";
-  let label2 = "test-script-switching-02.js";
-  let params = "?foo=bar,baz|lol";
-
-  ok(gDebugger.DebuggerView.Sources.selectedItem,
+  ok(gSources.selectedItem,
     "There should be a selected item in the sources pane.");
-  is(gDebugger.DebuggerView.Sources.selectedLabel,
-    label2, "The selected label is the sources pane is incorrect.");
-  is(gDebugger.DebuggerView.Sources.selectedValue, EXAMPLE_URL +
-    label2 + params, "The selected value is the sources pane is incorrect.");
+  is(gSources.selectedLabel, gLabel2,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel2 + gParams,
+    "The selected value is the sources pane is incorrect.");
+
+  is(gEditor.getText().search(/firstCall/), -1,
+    "The first source is not displayed.");
+  is(gEditor.getText().search(/debugger/), 172,
+    "The second source is displayed.");
+
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    ok(isCaretPos(gPanel, 6),
+      "Editor caret location is correct.");
+    is(gEditor.getDebugLocation(), 5,
+      "Editor debugger location is correct.");
+
+    // Step out three times.
+    waitForThreadEvents(gPanel, "paused").then(() => {
+      waitForThreadEvents(gPanel, "paused").then(() => {
+        waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
+        gDebugger.gThreadClient.stepOut();
+      });
+      gDebugger.gThreadClient.stepOut();
+    });
+    gDebugger.gThreadClient.stepOut();
+  });
 
-  ok(gDebugger.editor.getText().search(/debugger/) != -1,
-    "The correct script was loaded initially.");
+  return deferred.promise;
+}
+
+function testSwitchRunning() {
+  let deferred = promise.defer();
+
+  ok(gSources.selectedItem,
+    "There should be a selected item in the sources pane.");
+  is(gSources.selectedLabel, gLabel1,
+    "The selected label is the sources pane is incorrect.");
+  is(gSources.selectedValue, EXAMPLE_URL + gLabel1,
+    "The selected value is the sources pane is incorrect.");
 
-  is(gDebugger.editor.getDebugLocation(), 5,
-    "Editor debugger location is correct.");
+  is(gEditor.getText().search(/firstCall/), 118,
+    "The first source is displayed.");
+  is(gEditor.getText().search(/debugger/), -1,
+    "The second source is not displayed.");
 
-  closeDebuggerAndFinish();
+  // The editor's debug location takes a tick to update.
+  executeSoon(() => {
+    ok(isCaretPos(gPanel, 5),
+      "Editor caret location is correct.");
+    is(gEditor.getDebugLocation(), 4,
+      "Editor debugger location is correct.");
+
+    deferred.resolve();
+  });
+
+  return deferred.promise;
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gEditor = null;
   gSources = null;
+  gLabel1 = null;
+  gLabel2 = null;
+  gParams = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_scripts-switching-03.js
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-switching-03.js
@@ -1,60 +1,52 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Make sure that the Debugger-View error loading source text is correct
+ * Make sure that the DebuggerView error loading source text is correct.
  */
 
-const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
+const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
 
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var gView = null;
-var gL10N = null;
+let gTab, gDebuggee, gPanel, gDebugger;
+let gView, gEditor, gL10N;
 
-function test()
-{
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane){
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
     gView = gDebugger.DebuggerView;
+    gEditor = gDebugger.DebuggerView.editor;
     gL10N = gDebugger.L10N;
 
-    gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
+    waitForSourceShown(gPanel, "-01.js")
+      .then(showBogusSource)
+      .then(testDebuggerLoadingError)
+      .then(() => closeDebuggerAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
   });
 }
 
-function onScriptShown(aEvent)
-{
-  gView.editorSource = { url: "http://example.com/fake.js", actor: "fake.actor" };
-  gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
-  gDebugger.addEventListener("Debugger:SourceErrorShown", onScriptErrorShown);
-}
-
-function onScriptErrorShown(aEvent)
-{
-  gDebugger.removeEventListener("Debugger:SourceErrorShown", onScriptErrorShown);
-  testDebuggerLoadingError();
+function showBogusSource() {
+  let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_ERROR_SHOWN);
+  gView._setEditorSource({ url: "http://example.com/fake.js", actor: "fake.actor" });
+  return finished;
 }
 
-function testDebuggerLoadingError()
-{
-  ok(gDebugger.editor.getText().search(new RegExp(gL10N.getStr("errorLoadingText")) != -1),
+function testDebuggerLoadingError() {
+  ok(gEditor.getText().contains(gL10N.getStr("errorLoadingText")),
     "The valid error loading message is displayed.");
-  closeDebuggerAndFinish();
 }
 
-registerCleanupFunction(function()
-{
-  removeTab(gTab);
-  gPane = null;
+registerCleanupFunction(function() {
   gTab = null;
+  gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
   gView = null;
-  gDebuggee = null;
+  gEditor = null;
   gL10N = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_sources-cache.js
+++ b/browser/devtools/debugger/test/browser_dbg_sources-cache.js
@@ -1,119 +1,115 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const TAB_URL = EXAMPLE_URL + "browser_dbg_function-search-01.html";
-
 /**
  * Tests if the sources cache knows how to cache sources when prompted.
  */
 
-let gPane = null;
-let gTab = null;
-let gDebuggee = null;
-let gDebugger = null;
-let gEditor = null;
-let gSources = null;
-let gControllerSources = null;
-let gPrevLabelsCache = null;
-let gPrevGroupsCache = null;
-const TOTAL_SOURCES = 3;
+const TAB_URL = EXAMPLE_URL + "doc_function-search.html";
+const TOTAL_SOURCES = 4;
 
-requestLongerTimeout(2);
+let gTab, gDebuggee, gPanel, gDebugger;
+let gEditor, gSources, gControllerSources;
+let gPrevLabelsCache, gPrevGroupsCache;
 
-function test()
-{
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gEditor = gDebugger.DebuggerView.editor;
+    gSources = gDebugger.DebuggerView.Sources;
+    gControllerSources = gDebugger.DebuggerController.SourceScripts;
+    gPrevLabelsCache = gDebugger.SourceUtils._labelsCache;
+    gPrevGroupsCache = gDebugger.SourceUtils._groupsCache;
 
-    gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
-      gDebugger.removeEventListener(aEvent.type, _onEvent);
-      Services.tm.currentThread.dispatch({ run: testSourcesCache }, 0);
-    });
+    waitForSourceShown(gPanel, "-01.js")
+      .then(initialChecks)
+      .then(getTextForSourcesAndCheckIntegrity)
+      .then(performReloadAndTestState)
+      .then(() => closeDebuggerAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
   });
 }
 
-function testSourcesCache()
-{
-  gEditor = gDebugger.DebuggerView.editor;
-  gSources = gDebugger.DebuggerView.Sources;
-  gControllerSources = gDebugger.DebuggerController.SourceScripts;
-
+function initialChecks() {
   ok(gEditor.getText().contains("First source!"),
     "Editor text contents appears to be correct.");
-  is(gSources.selectedLabel, "test-function-search-01.js",
+  is(gSources.selectedLabel, "code_function-search-01.js",
     "The currently selected label in the sources container is correct.");
-  ok(gSources.selectedValue.contains("test-function-search-01.js"),
+  ok(gSources.selectedValue.contains("code_function-search-01.js"),
     "The currently selected value in the sources container appears to be correct.");
 
   is(gSources.itemCount, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " sources present in the sources list.");
   is(gSources.visibleItems.length, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " sources visible in the sources list.");
   is(gSources.labels.length, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " labels stored in the sources container model.")
   is(gSources.values.length, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " values stored in the sources container model.")
 
   info("Source labels: " + gSources.labels.toSource());
   info("Source values: " + gSources.values.toSource());
 
-  is(gSources.labels.sort()[0], "test-function-search-01.js",
+  is(gSources.labels[0], "code_function-search-01.js",
     "The first source label is correct.");
-  ok(gSources.values.sort()[0].contains("test-function-search-01.js"),
+  ok(gSources.values[0].contains("code_function-search-01.js"),
     "The first source value appears to be correct.");
 
-  is(gSources.labels.sort()[1], "test-function-search-02.js",
+  is(gSources.labels[1], "code_function-search-02.js",
     "The second source label is correct.");
-  ok(gSources.values.sort()[1].contains("test-function-search-02.js"),
+  ok(gSources.values[1].contains("code_function-search-02.js"),
     "The second source value appears to be correct.");
 
-  is(gSources.labels.sort()[2], "test-function-search-03.js",
+  is(gSources.labels[2], "code_function-search-03.js",
     "The third source label is correct.");
-  ok(gSources.values.sort()[2].contains("test-function-search-03.js"),
+  ok(gSources.values[2].contains("code_function-search-03.js"),
+    "The third source value appears to be correct.");
+
+  is(gSources.labels[3], "doc_function-search.html",
+    "The third source label is correct.");
+  ok(gSources.values[3].contains("doc_function-search.html"),
     "The third source value appears to be correct.");
 
   is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
-    "There should be " + TOTAL_SOURCES + " labels cached");
+    "There should be " + TOTAL_SOURCES + " labels cached.");
   is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
-    "There should be " + TOTAL_SOURCES + " groups cached");
+    "There should be " + TOTAL_SOURCES + " groups cached.");
+}
 
-  gPrevLabelsCache = gDebugger.SourceUtils._labelsCache;
-  gPrevGroupsCache = gDebugger.SourceUtils._groupsCache;
+function getTextForSourcesAndCheckIntegrity() {
+  return gControllerSources.getTextForSources(gSources.values).then(testCacheIntegrity);
+}
 
-  fetchSources(function() {
-    performReload(function() {
-      closeDebuggerAndFinish();
-    });
-  });
+function performReloadAndTestState() {
+  gDebugger.gTarget.once("will-navigate", testStateBeforeReload);
+  gDebugger.gTarget.once("navigate", testStateAfterReload);
+  return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
 }
 
-function fetchSources(callback) {
-  gControllerSources.getTextForSources(gSources.values).then((aSources) => {
-    testCacheIntegrity(aSources);
-    callback();
-  });
-}
+function testCacheIntegrity(aSources) {
+  for (let [url, contents] of aSources) {
+    // Sources of a debugee don't always finish fetching consecutively. D'uh.
+    let index = gSources.values.indexOf(url);
 
-function performReload(callback) {
-  gDebugger.DebuggerController._target.once("will-navigate", testStateBeforeReload);
-  gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
-    ok(true, "tabNavigated event was fired.");
-    info("Still attached to the tab.");
+    ok(index >= 0 && index <= TOTAL_SOURCES,
+      "Found a source url cached correctly (" + index + ").");
+    ok(contents.contains(
+      ["First source!", "Second source!", "Third source!", "Peanut butter jelly time!"][index]),
+      "Found a source's text contents cached correctly (" + index + ").");
 
-    testStateAfterReload();
-    callback();
-  });
-
-  gDebugger.DebuggerController.client.activeTab.reload();
+    info("Cached source url at " + index + ": " + url);
+    info("Cached source text at " + index + ": " + contents);
+  }
 }
 
 function testStateBeforeReload() {
   is(gSources.itemCount, 0,
     "There should be no sources present in the sources list during reload.");
   is(gDebugger.SourceUtils._labelsCache, gPrevLabelsCache,
     "The labels cache has been refreshed during reload and no new objects were created.");
   is(gDebugger.SourceUtils._groupsCache, gPrevGroupsCache,
@@ -128,38 +124,19 @@ function testStateAfterReload() {
   is(gSources.itemCount, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " sources present in the sources list.");
   is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " labels cached after reload.");
   is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
     "There should be " + TOTAL_SOURCES + " groups cached after reload.");
 }
 
-function testCacheIntegrity(aCache) {
-  for (let source of aCache) {
-    let [url, contents] = source;
-
-    // Sources of a debugee don't always finish fetching consecutively. D'uh.
-    let index = url.match(/test-function-search-0(\d)/).pop();
-
-    ok(index >= 1 && index <= TOTAL_SOURCES,
-      "Found a source url cached correctly (" + index + ")");
-    ok(contents.contains(
-      ["First source!", "Second source!", "Third source!"][index - 1]),
-      "Found a source's text contents cached correctly (" + index + ")");
-
-    info("Cached source url at " + index + ": " + url);
-    info("Cached source text at " + index + ": " + contents);
-  }
-}
-
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
   gEditor = null;
   gSources = null;
   gControllerSources = null;
   gPrevLabelsCache = null;
   gPrevGroupsCache = null;
 });
rename from browser/devtools/debugger/test/browser_dbg_propertyview-01.js
rename to browser/devtools/debugger/test/browser_dbg_sources-labels.js
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_sources-labels.js
@@ -1,56 +1,39 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests that urls are correctly shortened to unique labels.
  */
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
+
+const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
 
 function test() {
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+  let gTab, gDebuggee, gPanel, gDebugger;
+  let gSources, gUtils;
+
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
-
-    testSimpleCall();
-  });
-}
-
-function testSimpleCall() {
-  gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-    Services.tm.currentThread.dispatch({ run: function() {
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gSources = gDebugger.DebuggerView.Sources;
+    gUtils = gDebugger.SourceUtils;
 
-      testlabelshortening();
-    }}, 0);
-  });
-
-  gDebuggee.simpleCall();
-}
+    let ellipsis = gPanel.panelWin.L10N.ellipsis;
+    let nananana = new Array(20).join(NaN);
 
-function testlabelshortening() {
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    let sv = gDebugger.SourceUtils;
-    let vs = gDebugger.DebuggerView.Sources;
-    let ss = gDebugger.DebuggerController.SourceScripts;
-    vs.empty();
-    vs.widget.removeEventListener("select", vs._onScriptsChange, false);
-
-    is(sv.trimUrlQuery("a/b/c.d?test=1&random=4#reference"), "a/b/c.d",
+    let someUrl = "a/b/c.d?test=1&random=4#reference";
+    let shortenedUrl = "a/b/c.d";
+    is(gUtils.trimUrlQuery(someUrl), shortenedUrl,
       "Trimming the url query isn't done properly.");
 
-    let ellipsis = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString);
-    let nanana = new Array(20).join(NaN);
-
-    let superLargeLabel = new Array(100).join("Beer can in Jamaican sounds like Bacon!");
-    let trimmedLargeLabel = sv.trimUrlLength(superLargeLabel, 1234);
+    let largeLabel = new Array(100).join("Beer can in Jamaican sounds like Bacon!");
+    let trimmedLargeLabel = gUtils.trimUrlLength(largeLabel, 1234);
     is(trimmedLargeLabel.length, 1235,
       "Trimming large labels isn't done properly.");
     ok(trimmedLargeLabel.endsWith(ellipsis),
       "Trimming large labels should add an ellipsis at the end.");
 
     let urls = [
       { href: "http://some.address.com/random/", leaf: "subrandom/" },
       { href: "http://some.address.com/random/", leaf: "suprandom/?a=1" },
@@ -70,96 +53,109 @@ function testlabelshortening() {
       { href: "file://random/", leaf: "script_t1.js&a=1&b=2&c=3" },
       { href: "file://random/", leaf: "script_t2_1.js#id" },
       { href: "file://random/", leaf: "script_t2_2.js?a" },
       { href: "file://random/", leaf: "script_t2_3.js&b" },
       { href: "resource://random/", leaf: "script_t3_1.js#id?a=1&b=2" },
       { href: "resource://random/", leaf: "script_t3_2.js?a=1&b=2#id" },
       { href: "resource://random/", leaf: "script_t3_3.js&a=1&b=2#id" },
 
-      { href: nanana, leaf: "Batman!" + "{trim me, now and forevermore}" }
+      { href: nananana, leaf: "Batman!" + "{trim me, now and forevermore}" }
     ];
 
-    urls.forEach(function(url) {
-      executeSoon(function() {
-        let loc = url.href + url.leaf;
-        vs.push([sv.trimUrlLength(sv.getSourceLabel(loc)), loc], { forced: true });
-      });
-    });
+    is(gSources.itemCount, 1,
+      "Should contain the original source label in the sources widget.");
+    is(gSources.selectedIndex, 0,
+      "The first item in the sources widget should be selected (1).");
+    is(gSources.selectedLabel, "doc_recursion-stack.html",
+      "The first item in the sources widget should be selected (2).");
+    is(gSources.selectedValue, TAB_URL,
+      "The first item in the sources widget should be selected (3).");
 
-    executeSoon(function() {
-      info("Script labels:");
-      info(vs.labels.toSource());
+    gSources.empty();
 
-      info("Script locations:");
-      info(vs.values.toSource());
+    is(gSources.itemCount, 0,
+      "Should contain no items in the sources widget after emptying.");
+    is(gSources.selectedIndex, -1,
+      "No item in the sources widget should be selected (1).");
+    is(gSources.selectedLabel, "",
+      "No item in the sources widget should be selected (2).");
+    is(gSources.selectedValue, "",
+      "No item in the sources widget should be selected (3).");
 
-      urls.forEach(function(url) {
-        let loc = url.href + url.leaf;
-        if (url.dupe) {
-          ok(!vs.containsValue(loc), "Shouldn't contain script: " + loc);
-        } else {
-          ok(vs.containsValue(loc), "Should contain script: " + loc);
-        }
-      });
+    for (let { href, leaf } of urls) {
+      let url = href + leaf;
+      let label = gUtils.getSourceLabel(url);
+      let trimmedLabel = gUtils.trimUrlLength(label);
+      gSources.push([trimmedLabel, url]);
+    }
+
+    info("Source labels:");
+    info(gSources.labels.toSource());
 
-      ok(vs.containsLabel("random/subrandom/"),
-        "Script (0) label is incorrect.");
-      ok(vs.containsLabel("random/suprandom/?a=1"),
-        "Script (1) label is incorrect.");
-      ok(vs.containsLabel("random/?a=1"),
-        "Script (2) label is incorrect.");
-      ok(vs.containsLabel("page.html"),
-        "Script (3) label is incorrect.");
+    info("Source locations:");
+    info(gSources.values.toSource());
+
+    for (let { href, leaf, dupe } of urls) {
+      let url = href + leaf;
+      if (dupe) {
+        ok(!gSources.containsValue(url), "Shouldn't contain source: " + url);
+      } else {
+        ok(gSources.containsValue(url), "Should contain source: " + url);
+      }
+    }
 
-      ok(vs.containsLabel("script.js"),
-        "Script (4) label is incorrect.");
-      ok(vs.containsLabel("random/script.js"),
-        "Script (5) label is incorrect.");
-      ok(vs.containsLabel("random/x/script.js"),
-        "Script (6) label is incorrect.");
-      ok(vs.containsLabel("script.js?a=1"),
-        "Script (7) label is incorrect.");
+    ok(gSources.containsLabel("random/subrandom/"),
+      "Source (0) label is incorrect.");
+    ok(gSources.containsLabel("random/suprandom/?a=1"),
+      "Source (1) label is incorrect.");
+    ok(gSources.containsLabel("random/?a=1"),
+      "Source (2) label is incorrect.");
+    ok(gSources.containsLabel("page.html"),
+      "Source (3) label is incorrect.");
+
+    ok(gSources.containsLabel("script.js"),
+      "Source (4) label is incorrect.");
+    ok(gSources.containsLabel("random/script.js"),
+      "Source (5) label is incorrect.");
+    ok(gSources.containsLabel("random/x/script.js"),
+      "Source (6) label is incorrect.");
+    ok(gSources.containsLabel("script.js?a=1"),
+      "Source (7) label is incorrect.");
 
-      ok(vs.containsLabel("script_t1.js"),
-        "Script (8) label is incorrect.");
-      ok(vs.containsLabel("script_t2_1.js"),
-        "Script (9) label is incorrect.");
-      ok(vs.containsLabel("script_t2_2.js"),
-        "Script (10) label is incorrect.");
-      ok(vs.containsLabel("script_t2_3.js"),
-        "Script (11) label is incorrect.");
-      ok(vs.containsLabel("script_t3_1.js"),
-        "Script (12) label is incorrect.");
-      ok(vs.containsLabel("script_t3_2.js"),
-        "Script (13) label is incorrect.");
-      ok(vs.containsLabel("script_t3_3.js"),
-        "Script (14) label is incorrect.");
+    ok(gSources.containsLabel("script_t1.js"),
+      "Source (8) label is incorrect.");
+    ok(gSources.containsLabel("script_t2_1.js"),
+      "Source (9) label is incorrect.");
+    ok(gSources.containsLabel("script_t2_2.js"),
+      "Source (10) label is incorrect.");
+    ok(gSources.containsLabel("script_t2_3.js"),
+      "Source (11) label is incorrect.");
+    ok(gSources.containsLabel("script_t3_1.js"),
+      "Source (12) label is incorrect.");
+    ok(gSources.containsLabel("script_t3_2.js"),
+      "Source (13) label is incorrect.");
+    ok(gSources.containsLabel("script_t3_3.js"),
+      "Source (14) label is incorrect.");
+
+    ok(gSources.containsLabel(nananana + "Batman!" + ellipsis),
+      "Source (15) label is incorrect.");
 
-      ok(vs.containsLabel(nanana + "Batman!" + ellipsis),
-        "Script (15) label is incorrect.");
-
-      is(vs.itemCount, urls.filter(function(url) !url.dupe).length,
-        "Didn't get the correct number of scripts in the list.");
+    is(gSources.itemCount, urls.filter(({ dupe }) => !dupe).length,
+      "Didn't get the correct number of sources in the list.");
 
-      is(vs.getItemByValue("http://some.address.com/random/subrandom/").label, "random/subrandom/",
-        "Scripts.getItemByValue isn't functioning properly (0).");
-      is(vs.getItemByValue("http://some.address.com/random/suprandom/?a=1").label, "random/suprandom/?a=1",
-        "Scripts.getItemByValue isn't functioning properly (1).");
+    is(gSources.getItemByValue("http://some.address.com/random/subrandom/").label,
+      "random/subrandom/",
+      "gSources.getItemByValue isn't functioning properly (0).");
+    is(gSources.getItemByValue("http://some.address.com/random/suprandom/?a=1").label,
+      "random/suprandom/?a=1",
+      "gSources.getItemByValue isn't functioning properly (1).");
 
-      is(vs.getItemByLabel("random/subrandom/").value, "http://some.address.com/random/subrandom/",
-        "Scripts.getItemByLabel isn't functioning properly (0).");
-      is(vs.getItemByLabel("random/suprandom/?a=1").value, "http://some.address.com/random/suprandom/?a=1",
-        "Scripts.getItemByLabel isn't functioning properly (1).");
+    is(gSources.getItemByLabel("random/subrandom/").value,
+      "http://some.address.com/random/subrandom/",
+      "gSources.getItemByLabel isn't functioning properly (0).");
+    is(gSources.getItemByLabel("random/suprandom/?a=1").value,
+      "http://some.address.com/random/suprandom/?a=1",
+      "gSources.getItemByLabel isn't functioning properly (1).");
 
-
-      closeDebuggerAndFinish();
-    });
+    closeDebuggerAndFinish(gPanel);
   });
 }
-
-registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
-  gTab = null;
-  gDebuggee = null;
-  gDebugger = null;
-});
rename from browser/devtools/debugger/test/browser_dbg_scripts-sorting.js
rename to browser/devtools/debugger/test/browser_dbg_sources-sorting.js
--- a/browser/devtools/debugger/test/browser_dbg_scripts-sorting.js
+++ b/browser/devtools/debugger/test/browser_dbg_sources-sorting.js
@@ -1,124 +1,113 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests that urls are correctly sorted when added to the sources widget.
  */
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
+
+const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
+
+let gTab, gDebuggee, gPanel, gDebugger;
+let gSources, gUtils;
 
 function test() {
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.panelWin;
-
-    testSimpleCall();
-  });
-}
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gSources = gDebugger.DebuggerView.Sources;
+    gUtils = gDebugger.SourceUtils;
 
-function testSimpleCall() {
-  gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-    Services.tm.currentThread.dispatch({ run: function() {
-      resumeAndFinish();
-    }}, 0);
-  });
-
-  gDebuggee.simpleCall();
-}
-
-function resumeAndFinish() {
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    checkScriptsOrder();
-    addScriptAndCheckOrder(1, function() {
-      addScriptAndCheckOrder(2, function() {
-        addScriptAndCheckOrder(3, function() {
-          closeDebuggerAndFinish();
+    waitForSourceShown(gPanel, ".html").then(() => {
+      addSourceAndCheckOrder(1, () => {
+        addSourceAndCheckOrder(2, () => {
+          addSourceAndCheckOrder(3, () => {
+            closeDebuggerAndFinish(gPanel);
+          });
         });
       });
     });
   });
 }
 
-function addScriptAndCheckOrder(method, callback) {
-  let sv = gDebugger.SourceUtils;
-  let vs = gDebugger.DebuggerView.Sources;
-  vs.empty();
-  vs.widget.removeEventListener("select", vs._onScriptsChange, false);
+function addSourceAndCheckOrder(aMethod, aCallback) {
+  gSources.empty();
 
   let urls = [
     { href: "ici://some.address.com/random/", leaf: "subrandom/" },
     { href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
     { href: "san://interesting.address.gro/random/", leaf: "script.js" },
     { href: "si://interesting.address.moc/random/", leaf: "script.js" },
     { href: "si://interesting.address.moc/random/", leaf: "x/script.js" },
     { href: "si://interesting.address.moc/random/", leaf: "x/y/script.js?a=1" },
     { href: "si://interesting.address.moc/random/x/", leaf: "y/script.js?a=1&b=2" },
     { href: "si://interesting.address.moc/random/x/y/", leaf: "script.js?a=1&b=2&c=3" }
   ];
 
   urls.sort(function(a, b) {
     return Math.random() - 0.5;
   });
 
-  switch (method) {
+  switch (aMethod) {
     case 1:
-      urls.forEach(function(url) {
-        let loc = url.href + url.leaf;
-        vs.push([sv.getSourceLabel(loc), { url: loc }], { staged: true });
-      });
-      vs.commit({ sorted: true });
+      for (let { href, leaf } of urls) {
+        let url = href + leaf;
+        let label = gUtils.getSourceLabel(url);
+        gSources.push([label, url], { staged: true });
+      }
+      gSources.commit({ sorted: true });
       break;
 
     case 2:
-      urls.forEach(function(url) {
-        let loc = url.href + url.leaf;
-        vs.push([sv.getSourceLabel(loc), { url: loc }]);
-      });
+      for (let { href, leaf } of urls) {
+        let url = href + leaf;
+        let label = gUtils.getSourceLabel(url);
+        gSources.push([label, url], { staged: false });
+      }
       break;
 
     case 3:
       let i = 0
       for (; i < urls.length / 2; i++) {
-        let url = urls[i];
-        let loc = url.href + url.leaf;
-        vs.push([sv.getSourceLabel(loc), { url: loc }], { staged: true });
+        let { href, leaf } = urls[i];
+        let url = href + leaf;
+        let label = gUtils.getSourceLabel(url);
+        gSources.push([label, url], { staged: true });
       }
-      vs.commit({ sorted: true });
+      gSources.commit({ sorted: true });
 
       for (; i < urls.length; i++) {
-        let url = urls[i];
-        let loc = url.href + url.leaf;
-        vs.push([sv.getSourceLabel(loc), { url: loc }]);
+        let { href, leaf } = urls[i];
+        let url = href + leaf;
+        let label = gUtils.getSourceLabel(url);
+        gSources.push([label, url], { staged: false });
       }
       break;
   }
 
-  executeSoon(function() {
-    checkScriptsOrder(method);
-    callback();
-  });
+  checkSourcesOrder(aMethod);
+  aCallback();
 }
 
-function checkScriptsOrder(method) {
-  let labels = gDebugger.DebuggerView.Sources.labels;
-  let sorted = labels.reduce(function(prev, curr, index, array) {
-    return array[index - 1] < array[index];
+function checkSourcesOrder(aMethod) {
+  let labels = gSources.labels;
+  let sorted = labels.reduce(function(aPrev, aCurr, aIndex, aArray) {
+    return aArray[aIndex - 1] < aArray[aIndex];
   });
 
   ok(sorted,
-    "Using method " + method + ", " +
-    "the scripts weren't in the correct order: " + labels.toSource());
+    "Using method " + aMethod + ", " +
+    "the sources weren't in the correct order: " + labels.toSource());
 
   return sorted;
 }
 
 registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
   gTab = null;
   gDebuggee = null;
+  gPanel = null;
   gDebugger = null;
+  gSources = null;
+  gUtils = null;
 });