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 159996 5f626c9dd0660bbbd145616119b884dcab404a37
parent 159995 39471a71749473661a0093050cf993fc2c962125
child 159997 862a066d90d573b13f3157b4fd286061496bb29a
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspast
bugs876277
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;
 });