Bug 663778 - Changes to tests for box model highlighter r=jwalker
authorMichael Ratcliffe <mratcliffe@mozilla.com>
Wed, 12 Mar 2014 14:01:31 +0000
changeset 173481 acf2659a7478ce41fdc64a57f942b42eecb63d99
parent 173480 fad8f0885e5b12fe4a66d453633365e84577377b
child 173482 436a9dfc6cb498b6b7ba26e76700ccf8a7504d8e
push id5677
push usermratcliffe@mozilla.com
push dateThu, 13 Mar 2014 22:29:17 +0000
treeherderfx-team@436a9dfc6cb4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalker
bugs663778
milestone30.0a1
Bug 663778 - Changes to tests for box model highlighter r=jwalker
browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js
browser/devtools/inspector/test/browser_inspector_basic_highlighter.js
browser/devtools/inspector/test/browser_inspector_breadcrumbs.js
browser/devtools/inspector/test/browser_inspector_bug_674871.js
browser/devtools/inspector/test/browser_inspector_bug_699308_iframe_navigation.js
browser/devtools/inspector/test/browser_inspector_highlighter.js
browser/devtools/inspector/test/browser_inspector_iframeTest.js
browser/devtools/inspector/test/browser_inspector_invalidate.js
browser/devtools/inspector/test/browser_inspector_scrolling.js
browser/devtools/inspector/test/browser_inspector_sidebarstate.js
browser/devtools/inspector/test/head.js
browser/devtools/markupview/test/browser_inspector_markup_navigation.js
browser/devtools/markupview/test/head.js
browser/devtools/scratchpad/test/browser_scratchpad_revert_to_saved.js
browser/devtools/webconsole/test/browser_console_variables_view_highlighter.js
browser/devtools/webconsole/test/browser_webconsole_autocomplete_in_debugger_stackframe.js
browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
browser/devtools/webconsole/test/browser_webconsole_output_01.js
browser/devtools/webconsole/test/browser_webconsole_output_03.js
browser/devtools/webconsole/test/browser_webconsole_view_source.js
browser/devtools/webconsole/test/head.js
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js
@@ -202,9 +202,10 @@ function testFunctionScope() {
     "Should have the right token class for 'foo'.");
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
   gDebugger = null;
+  gVariables = null;
 });
--- a/browser/devtools/inspector/test/browser_inspector_basic_highlighter.js
+++ b/browser/devtools/inspector/test/browser_inspector_basic_highlighter.js
@@ -19,65 +19,44 @@ function test() {
   }, true);
 
   content.location = "data:text/html;charset=utf-8,<h1>foo</h1><span>bar</span>";
 
   function setupTest() {
     openInspector((aInspector, aToolbox) => {
       toolbox = aToolbox;
       inspector = aInspector;
-      inspector.selection.setNode(doc.querySelector("h2"), null);
-      inspector.once("inspector-updated", runTests);
+      inspector.selection.setNode(doc.querySelector("span"), "test");
+      inspector.toolbox.once("highlighter-ready", runTests);
     });
   }
 
   function runTests() {
     Task.spawn(function() {
       yield hoverH1InMarkupView();
       yield assertH1Highlighted();
-      yield mouseLeaveMarkupView();
-      yield assertNoNodeHighlighted();
 
       finishUp();
     }).then(null, Cu.reportError);
   }
 
   function hoverH1InMarkupView() {
     let deferred = promise.defer();
+    let container = getContainerForRawNode(inspector.markup, doc.querySelector("h1"));
 
-    let container = getContainerForRawNode(inspector.markup, doc.querySelector("h1"));
-    EventUtils.synthesizeMouse(container.tagLine, 2, 2, {type: "mousemove"},
-      inspector.markup.doc.defaultView);
-    inspector.toolbox.once("node-highlight", deferred.resolve);
+    inspector.toolbox.once("highlighter-ready", deferred.resolve);
+    EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mousemove"},
+                                       inspector.markup.doc.defaultView);
 
     return deferred.promise;
   }
 
   function assertH1Highlighted() {
     ok(isHighlighting(), "The highlighter is shown on a markup container hover");
     is(getHighlitNode(), doc.querySelector("h1"), "The highlighter highlights the right node");
-    return promise.resolve();
-  }
-
-  function mouseLeaveMarkupView() {
-    let deferred = promise.defer();
-
-    // Find another element to mouseover over in order to leave the markup-view
-    let btn = toolbox.doc.querySelector(".toolbox-dock-button");
-
-    EventUtils.synthesizeMouse(btn, 2, 2, {type: "mousemove"},
-      toolbox.doc.defaultView);
-    executeSoon(deferred.resolve);
-
-    return deferred.promise;
-  }
-
-  function assertNoNodeHighlighted() {
-    ok(!isHighlighting(), "After the mouse left the markup view, the highlighter is hidden");
-    return promise.resolve();
   }
 
   function finishUp() {
     inspector = doc = toolbox = null;
     gBrowser.removeCurrentTab();
     finish();
   }
 }
--- a/browser/devtools/inspector/test/browser_inspector_breadcrumbs.js
+++ b/browser/devtools/inspector/test/browser_inspector_breadcrumbs.js
@@ -86,13 +86,13 @@ function test()
 
     let checkedButton = container.querySelector("button[checked]");
     let labelId = checkedButton.querySelector(".breadcrumbs-widget-item-id");
     let id = inspector.selection.node.id;
     is(labelId.textContent, "#" + id, "Node " + cursor + ": selection matches");
   }
 
   function finishUp() {
-    doc = nodes = null;
+    doc = nodes = inspector = null;
     gBrowser.removeCurrentTab();
     finish();
   }
 }
--- a/browser/devtools/inspector/test/browser_inspector_bug_674871.js
+++ b/browser/devtools/inspector/test/browser_inspector_bug_674871.js
@@ -59,36 +59,40 @@ function test()
   {
     inspector.toolbox.highlighterUtils.startPicker().then(() => {
       moveMouseOver(iframeNode, 1, 1, isTheIframeHighlighted);
     });
   }
 
   function isTheIframeHighlighted()
   {
-    let outlineRect = getHighlighterOutlineRect();
-    let iframeRect = iframeNode.getBoundingClientRect();
-    for (let dim of ["width", "height", "top", "left"]) {
-      is(Math.floor(outlineRect[dim]), Math.floor(iframeRect[dim]),
-         "Outline dimension is correct " + outlineRect[dim]);
-    }
+    let {p1, p2, p3, p4} = getBoxModelStatus().border.points;
+    let {top, right, bottom, left} = iframeNode.getBoundingClientRect();
+
+    is(top, p1.y, "iframeRect.top === boxModelStatus.p1.y");
+    is(top, p2.y, "iframeRect.top === boxModelStatus.p2.y");
+    is(right, p2.x, "iframeRect.right === boxModelStatus.p2.x");
+    is(right, p3.x, "iframeRect.right === boxModelStatus.p3.x");
+    is(bottom, p3.y, "iframeRect.bottom === boxModelStatus.p3.y");
+    is(bottom, p4.y, "iframeRect.bottom === boxModelStatus.p4.y");
+    is(left, p1.x, "iframeRect.left === boxModelStatus.p1.x");
+    is(left, p4.x, "iframeRect.left === boxModelStatus.p4.x");
 
     iframeNode.style.marginBottom = doc.defaultView.innerHeight + "px";
     doc.defaultView.scrollBy(0, 40);
 
     moveMouseOver(iframeNode, 40, 40, isTheIframeContentHighlighted);
   }
 
   function isTheIframeContentHighlighted()
   {
     is(getHighlitNode(), iframeBodyNode, "highlighter shows the right node");
 
-    // 184 == 200 + 11(border) + 13(padding) - 40(scroll)
-    let outlineRect = getHighlighterOutlineRect();
-    is(outlineRect.height, 184, "highlighter height");
+    let outlineRect = getSimpleBorderRect();
+    is(outlineRect.height, 200, "highlighter height");
 
     inspector.toolbox.highlighterUtils.stopPicker().then(() => {
       let target = TargetFactory.forTab(gBrowser.selectedTab);
       gDevTools.closeToolbox(target);
       finishUp();
     });
   }
 
--- a/browser/devtools/inspector/test/browser_inspector_bug_699308_iframe_navigation.js
+++ b/browser/devtools/inspector/test/browser_inspector_bug_699308_iframe_navigation.js
@@ -13,49 +13,44 @@ function test() {
       runInspectorTests();
     });
   }
 
   function showHighlighter(cb) {
     inspector.toolbox.highlighterUtils.startPicker().then(() => {
       EventUtils.synthesizeMouse(content.document.body, 1, 1,
         {type: "mousemove"}, content);
-      inspector.toolbox.once("picker-node-hovered", () => {
-        executeSoon(() => {
-          getHighlighterOutline().setAttribute("disable-transitions", "true");
-          cb();
-        });
-      });
+      inspector.toolbox.once("highlighter-ready", cb);
     });
   }
 
   function runInspectorTests() {
     iframe = content.document.querySelector("iframe");
     ok(iframe, "found the iframe element");
 
     showHighlighter(() => {
       ok(isHighlighting(), "Inspector is highlighting");
 
       iframe.addEventListener("load", onIframeLoad, false);
-
-      executeSoon(function() {
+      executeSoon(() => {
         iframe.contentWindow.location = "javascript:location.reload()";
       });
     });
   }
 
   function onIframeLoad() {
     if (++iframeLoads != 2) {
       executeSoon(function() {
         iframe.contentWindow.location = "javascript:location.reload()";
       });
       return;
     }
 
     iframe.removeEventListener("load", onIframeLoad, false);
+    info("Finished reloading iframe and inspector updated");
 
     ok(isHighlighting(), "Inspector is highlighting after iframe nav");
 
     checksAfterLoads = true;
 
     finishTest();
   }
 
--- a/browser/devtools/inspector/test/browser_inspector_highlighter.js
+++ b/browser/devtools/inspector/test/browser_inspector_highlighter.js
@@ -52,64 +52,59 @@ function createDocument() {
     inspector.selection.setNode(div, null);
     inspector.once("inspector-updated", () => {
       inspector.toolbox.highlighterUtils.startPicker().then(testMouseOverH1Highlights);
     });
   });
 }
 
 function testMouseOverH1Highlights() {
-  inspector.toolbox.once("picker-node-hovered", () => {
+  inspector.toolbox.once("highlighter-ready", () => {
     ok(isHighlighting(), "Highlighter is shown");
     is(getHighlitNode(), h1, "Highlighter's outline correspond to the selected node");
-    testOutlineDimensions();
+    testBoxModelDimensions();
   });
 
   EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
 }
 
-function testOutlineDimensions() {
+function testBoxModelDimensions() {
   let h1Dims = h1.getBoundingClientRect();
-  let h1Width = h1Dims.width;
-  let h1Height = h1Dims.height;
+  let h1Width = Math.ceil(h1Dims.width);
+  let h1Height = Math.ceil(h1Dims.height);
 
-  let outlineDims = getHighlighterOutlineRect();
-  let outlineWidth = outlineDims.width;
-  let outlineHeight = outlineDims.height;
+  let outlineDims = getSimpleBorderRect();
+  let outlineWidth = Math.ceil(outlineDims.width);
+  let outlineHeight = Math.ceil(outlineDims.height);
 
   // Disabled due to bug 716245
   is(outlineWidth, h1Width, "outline width matches dimensions of element (no zoom)");
   is(outlineHeight, h1Height, "outline height matches dimensions of element (no zoom)");
 
   // zoom the page by a factor of 2
   let contentViewer = gBrowser.selectedBrowser.docShell.contentViewer
                              .QueryInterface(Ci.nsIMarkupDocumentViewer);
   contentViewer.fullZoom = 2;
 
-  // We wait at least 500ms to make sure the highlighter is not "mutting" the
-  // resize event
-
-  window.setTimeout(function() {
-    // simulate the zoomed dimensions of the div element
-    let h1Dims = h1.getBoundingClientRect();
-    // There seems to be some very minor differences in the floats, so let's
-    // floor the values
-    let h1Width = Math.floor(h1Dims.width * contentViewer.fullZoom);
-    let h1Height = Math.floor(h1Dims.height * contentViewer.fullZoom);
+  // simulate the zoomed dimensions of the div element
+  let h1Dims = h1.getBoundingClientRect();
+  // There seems to be some very minor differences in the floats, so let's
+  // floor the values
+  let h1Width = Math.floor(h1Dims.width * contentViewer.fullZoom);
+  let h1Height = Math.floor(h1Dims.height * contentViewer.fullZoom);
 
-    let outlineDims = getHighlighterOutlineRect();
-    let outlineWidth = Math.floor(outlineDims.width);
-    let outlineHeight = Math.floor(outlineDims.height);
+  let outlineDims = getSimpleBorderRect();
+  let outlineWidth = Math.floor(outlineDims.width);
+  let outlineHeight = Math.floor(outlineDims.height);
 
-    // Disabled due to bug 716245
-    is(outlineWidth, h1Width, "outline width matches dimensions of element (zoomed)");
-    is(outlineHeight, h1Height, "outline height matches dimensions of element (zoomed)");
+  is(outlineWidth, h1Width, "outline width matches dimensions of element (zoomed)");
 
-    executeSoon(finishUp);
-  }, 500);
+  is(outlineHeight, h1Height, "outline height matches dimensions of element (zoomed)");
+
+  executeSoon(finishUp);
 }
 
 function finishUp() {
   inspector.toolbox.highlighterUtils.stopPicker().then(() => {
     doc = h1 = inspector = null;
     let target = TargetFactory.forTab(gBrowser.selectedTab);
     gDevTools.closeToolbox(target);
     gBrowser.removeCurrentTab();
--- a/browser/devtools/inspector/test/browser_inspector_iframeTest.js
+++ b/browser/devtools/inspector/test/browser_inspector_iframeTest.js
@@ -30,51 +30,50 @@ function createDocument() {
 
       div2 = iframe2.contentDocument.createElement('div');
       div2.textContent = 'nested div';
       iframe2.contentDocument.body.appendChild(div2);
 
       // Open the inspector, start the picker mode, and start the tests
       openInspector(aInspector => {
         inspector = aInspector;
-        inspector.toolbox.highlighterUtils.startPicker().then(runTests);
+        inspector.once("inspector-updated", () => {
+          inspector.toolbox.highlighterUtils.startPicker().then(runTests);
+        });
       });
     }, false);
 
     iframe2.src = 'data:text/html,nested iframe';
     iframe1.contentDocument.body.appendChild(iframe2);
   }, false);
 
   iframe1.src = 'data:text/html,little iframe';
   doc.body.appendChild(iframe1);
 }
 
 function moveMouseOver(aElement, cb) {
-  inspector.toolbox.once("picker-node-hovered", () => {
-    executeSoon(cb);
-  });
+  inspector.toolbox.once("picker-node-hovered", cb);
   EventUtils.synthesizeMouseAtCenter(aElement, {type: "mousemove"},
     aElement.ownerDocument.defaultView);
 }
 
 function runTests() {
   testDiv1Highlighter();
 }
 
 function testDiv1Highlighter() {
   moveMouseOver(div1, () => {
-    getHighlighterOutline().setAttribute("disable-transitions", "true");
-    is(getHighlitNode(), div1, "highlighter matches selection");
+    is(getHighlitNode(), div1, "highlighter matches selection of div1");
     testDiv2Highlighter();
   });
 }
 
 function testDiv2Highlighter() {
   moveMouseOver(div2, () => {
-    is(getHighlitNode(), div2, "highlighter matches selection");
+    is(getHighlitNode(), div2, "highlighter matches selection of div2");
     selectRoot();
   });
 }
 
 function selectRoot() {
   // Select the root document element to clear the breadcrumbs.
   inspector.selection.setNode(doc.documentElement, null);
   inspector.once("inspector-updated", selectIframe);
--- a/browser/devtools/inspector/test/browser_inspector_invalidate.js
+++ b/browser/devtools/inspector/test/browser_inspector_invalidate.js
@@ -8,34 +8,34 @@ function test() {
 
   function createDocument() {
     div = doc.createElement("div");
     div.setAttribute("style", "width: 100px; height: 100px; background:yellow;");
     doc.body.appendChild(div);
 
     openInspector(aInspector => {
       inspector = aInspector;
-      inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
+      inspector.once("inspector-updated", () => {
+        inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
+      });
     });
   }
 
   function runTest() {
-    let outline = getHighlighterOutline();
-    is(outline.style.width, "100px", "outline has the right width");
+    let rect = getSimpleBorderRect();
+    is(rect.width, 100, "outline has the right width");
 
     div.style.width = "200px";
-    function pollTest() {
-      if (outline.style.width == "100px") {
-        setTimeout(pollTest, 10);
-        return;
-      }
-      is(outline.style.width, "200px", "outline updated");
-      finishUp();
-    }
-    setTimeout(pollTest, 10);
+    inspector.toolbox.once("highlighter-ready", testRectWidth);
+  }
+
+  function testRectWidth() {
+    let rect = getSimpleBorderRect();
+    is(rect.width, 200, "outline updated");
+    finishUp();
   }
 
   function finishUp() {
     inspector.toolbox.highlighter.hideBoxModel().then(() => {
       doc = div = inspector = null;
       gBrowser.removeCurrentTab();
       finish();
     });
--- a/browser/devtools/inspector/test/browser_inspector_scrolling.js
+++ b/browser/devtools/inspector/test/browser_inspector_scrolling.js
@@ -28,44 +28,44 @@ function createDocument()
   iframe.src = "data:text/html,foo bar";
   doc.body.appendChild(iframe);
 }
 
 function inspectNode(aInspector)
 {
   inspector = aInspector;
 
-  inspector.once("inspector-updated", performScrollingTest);
-  executeSoon(function() {
-    inspector.selection.setNode(div, "");
-  });
+  let highlighter = inspector.toolbox.highlighter;
+  highlighter.showBoxModel(getNodeFront(div)).then(performScrollingTest);
 }
 
 function performScrollingTest()
 {
-  executeSoon(function() {
-    // FIXME: this will fail on retina displays. EventUtils will only scroll
-    // 25px down instead of 50.
-    EventUtils.synthesizeWheel(div, 10, 10,
-      { deltaY: 50.0, deltaMode: WheelEvent.DOM_DELTA_PIXEL },
-      iframe.contentWindow);
-  });
-
   gBrowser.selectedBrowser.addEventListener("scroll", function() {
     gBrowser.selectedBrowser.removeEventListener("scroll", arguments.callee,
       false);
+    let isRetina = devicePixelRatio === 2;
+    is(iframe.contentDocument.body.scrollTop,
+      isRetina ? 25 : 50, "inspected iframe scrolled");
 
-    is(iframe.contentDocument.body.scrollTop, 50, "inspected iframe scrolled");
+    finishUp();
+  }, false);
 
-    inspector = div = iframe = doc = null;
-    let target = TargetFactory.forTab(gBrowser.selectedTab);
-    gDevTools.closeToolbox(target);
-    gBrowser.removeCurrentTab();
-    finish();
-  }, false);
+  EventUtils.synthesizeWheel(div, 10, 10,
+    { deltaY: 50.0, deltaMode: WheelEvent.DOM_DELTA_PIXEL },
+    iframe.contentWindow);
+}
+
+function finishUp()
+{
+  inspector = div = iframe = doc = null;
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+  gDevTools.closeToolbox(target);
+  gBrowser.removeCurrentTab();
+  finish();
 }
 
 function test()
 {
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function() {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
--- a/browser/devtools/inspector/test/browser_inspector_sidebarstate.js
+++ b/browser/devtools/inspector/test/browser_inspector_sidebarstate.js
@@ -20,28 +20,29 @@ function inspectorRuleViewOpened()
 {
   is(inspector.sidebar.getCurrentTabID(), "ruleview", "Rule View is selected by default");
 
   // Select the computed view and turn off the inspector.
   inspector.sidebar.select("computedview");
 
   gDevTools.once("toolbox-destroyed", inspectorClosed);
   let target = TargetFactory.forTab(gBrowser.selectedTab);
-  gDevTools.getToolbox(target).destroy();
+  gDevTools.closeToolbox(target);
 }
 
 function inspectorClosed()
 {
   openInspector(function(panel) {
     inspector = panel;
+
     if (inspector.sidebar.getCurrentTabID()) {
-      // Default sidebar already selected.
+      info("Default sidebar already selected.")
       testNewDefaultTab();
     } else {
-      // Default sidebar still to be selected.
+      info("Default sidebar still to be selected, adding select listener.");
       inspector.sidebar.once("select", testNewDefaultTab);
     }
   });
 }
 
 function testNewDefaultTab()
 {
   is(inspector.sidebar.getCurrentTabID(), "computedview", "Computed view is selected by default.");
--- a/browser/devtools/inspector/test/head.js
+++ b/browser/devtools/inspector/test/head.js
@@ -28,16 +28,17 @@ let testDir = gTestPath.substr(0, gTestP
 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
 
 SimpleTest.registerCleanupFunction(() => {
   console.error("Here we are\n");
   let {DebuggerServer} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
   console.error("DebuggerServer open connections: " + Object.getOwnPropertyNames(DebuggerServer._connections).length);
 
   Services.prefs.clearUserPref("devtools.dump.emit");
+  Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
 });
 
 function openInspector(callback)
 {
   let target = TargetFactory.forTab(gBrowser.selectedTab);
   gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
     callback(toolbox.getCurrentPanel(), toolbox);
   }).then(null, console.error);
@@ -55,73 +56,128 @@ function getNodeFront(node)
   return inspector.walker.frontForRawNode(node);
 }
 
 function getHighlighter()
 {
   return gBrowser.selectedBrowser.parentNode.querySelector(".highlighter-container");
 }
 
-function getHighlighterOutline()
-{
-  let h = getHighlighter();
-  if (h) {
-    return h.querySelector(".highlighter-outline");
-  }
+function getSimpleBorderRect() {
+  let {p1, p2, p3, p4} = getBoxModelStatus().border.points;
+
+  return {
+    top: p1.y,
+    left: p1.x,
+    width: p2.x - p1.x,
+    height: p4.y - p1.y
+  };
+}
+
+function getBoxModelRoot() {
+  let highlighter = getHighlighter();
+  return highlighter.querySelector(".box-model-root");
 }
 
-function getHighlighterOutlineRect() {
-  let helper = new LayoutHelpers(window.content);
-  let outline = getHighlighterOutline();
+function getBoxModelStatus() {
+  let root = getBoxModelRoot();
+  let inspector = getActiveInspector();
+
+  return {
+    visible: !root.hasAttribute("hidden"),
+    currentNode: inspector.walker.currentNode,
+    margin: {
+      points: getPointsForRegion("margin"),
+      visible: isRegionHidden("margin")
+    },
+    border: {
+      points: getPointsForRegion("border"),
+      visible: isRegionHidden("border")
+    },
+    padding: {
+      points: getPointsForRegion("padding"),
+      visible: isRegionHidden("padding")
+    },
+    content: {
+      points: getPointsForRegion("content"),
+      visible: isRegionHidden("content")
+    },
+    guides: {
+      top: getGuideStatus("top"),
+      right: getGuideStatus("right"),
+      bottom: getGuideStatus("bottom"),
+      left: getGuideStatus("left")
+    }
+  };
+}
+
+function getGuideStatus(location) {
+  let root = getBoxModelRoot();
+  let guide = root.querySelector(".box-model-guide-" + location);
 
-  if (outline) {
-    let browserOffsetRect = helper.getDirtyRect(gBrowser.selectedBrowser);
-    let outlineRect = helper.getDirtyRect(outline);
-    outlineRect.top -= browserOffsetRect.top;
-    outlineRect.left -= browserOffsetRect.left;
+  return {
+    visible: !guide.hasAttribute("hidden"),
+    x1: guide.getAttribute("x1"),
+    y1: guide.getAttribute("y1"),
+    x2: guide.getAttribute("x2"),
+    y2: guide.getAttribute("y2")
+  };
+}
+
+function getPointsForRegion(region) {
+  let root = getBoxModelRoot();
+  let box = root.querySelector(".box-model-" + region);
+  let points = box.getAttribute("points").split(/[, ]/);
 
-    return outlineRect;
-  }
+  // We multiply each value by 1 to cast it into a number
+  return {
+    p1: {
+      x: parseFloat(points[0]),
+      y: parseFloat(points[1])
+    },
+    p2: {
+      x: parseFloat(points[2]),
+      y: parseFloat(points[3])
+    },
+    p3: {
+      x: parseFloat(points[4]),
+      y: parseFloat(points[5])
+    },
+    p4: {
+      x: parseFloat(points[6]),
+      y: parseFloat(points[7])
+    }
+  };
+}
+
+function isRegionHidden(region) {
+  let root = getBoxModelRoot();
+  let box = root.querySelector(".box-model-" + region);
+
+  return !box.hasAttribute("hidden");
 }
 
 function isHighlighting()
 {
-  let outline = getHighlighterOutline();
-  return outline && !outline.hasAttribute("hidden");
+  let root = getBoxModelRoot();
+  return !root.hasAttribute("hidden");
 }
 
 function getHighlitNode()
 {
   if (isHighlighting()) {
     let helper = new LayoutHelpers(window.content);
-    let outlineRect = getHighlighterOutlineRect();
-
-    let a = {
-      x: outlineRect.left,
-      y: outlineRect.top
-    };
+    let points = getBoxModelStatus().content.points;
+    let x = (points.p1.x + points.p2.x + points.p3.x + points.p4.x) / 4;
+    let y = (points.p1.y + points.p2.y + points.p3.y + points.p4.y) / 4;
 
-    let b = {
-      x: a.x + outlineRect.width,
-      y: a.y + outlineRect.height
-    };
-
-    let {x, y} = getMidPoint(a, b);
     return helper.getElementFromPoint(window.content.document, x, y);
   }
 }
 
-function getMidPoint(aPointA, aPointB)
-{
-  let pointC = {};
-  pointC.x = (aPointB.x - aPointA.x) / 2 + aPointA.x;
-  pointC.y = (aPointB.y - aPointA.y) / 2 + aPointA.y;
-  return pointC;
-}
-
 function computedView()
 {
   let sidebar = getActiveInspector().sidebar;
   let iframe = sidebar.tabbox.querySelector(".iframe-computedview");
   return iframe.contentWindow.computedView;
 }
 
 function computedViewTree()
--- a/browser/devtools/markupview/test/browser_inspector_markup_navigation.js
+++ b/browser/devtools/markupview/test/browser_inspector_markup_navigation.js
@@ -120,17 +120,17 @@ function test() {
       case "pagedown":
         EventUtils.synthesizeKey("VK_PAGE_DOWN", {});
         break;
       case "home":
         EventUtils.synthesizeKey("VK_HOME", {});
         break;
     }
 
-    inspector.markup._waitForChildren().then(() => executeSoon(function BIMNT_newNode() {
+    inspector.markup._waitForChildren().then(() => executeSoon(() => {
       let node = inspector.selection.node;
 
       if (className == "*comment*") {
         is(node.nodeType, Node.COMMENT_NODE, "[" + cursor + "] should be a comment after moving " + key);
       } else if (className == "*text*") {
         is(node.nodeType, Node.TEXT_NODE, "[" + cursor + "] should be text after moving " + key);
       } else if (className == "*doctype*") {
         is(node.nodeType, Node.DOCUMENT_TYPE_NODE, "[" + cursor + "] should be doctype after moving " + key);
--- a/browser/devtools/markupview/test/head.js
+++ b/browser/devtools/markupview/test/head.js
@@ -115,17 +115,17 @@ function selectNode(nodeOrSelector, insp
  * @param {InspectorPanel} inspector The instance of InspectorPanel currently loaded in the toolbox
  * @return a promise that resolves when the container is hovered and the higlighter
  * is shown on the corresponding node
  */
 function hoverContainer(nodeOrSelector, inspector) {
   info("Hovering over the markup-container for node " + nodeOrSelector);
   let highlit = inspector.toolbox.once("node-highlight");
   let container = getContainerForRawNode(inspector.markup, getNode(nodeOrSelector));
-  EventUtils.synthesizeMouse(container.tagLine, 2, 2, {type: "mousemove"},
+  EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mousemove"},
     inspector.markup.doc.defaultView);
   return highlit;
 }
 
 /**
  * Simulate a click on the markup-container (a line in the markup-view)
  * that corresponds to the node or selector passed.
  * @param {String|DOMNode} nodeOrSelector
@@ -143,33 +143,34 @@ function clickContainer(nodeOrSelector, 
   return updated;
 }
 
 /**
  * Checks if the highlighter is visible currently
  * @return {Boolean}
  */
 function isHighlighterVisible() {
-  let outline = gBrowser.selectedBrowser.parentNode.querySelector(".highlighter-container .highlighter-outline");
-  return outline && !outline.hasAttribute("hidden");
+  let highlighter = gBrowser.selectedBrowser.parentNode
+                            .querySelector(".highlighter-container .box-model-root");
+  return highlighter && !highlighter.hasAttribute("hidden");
 }
 
 /**
  * Simulate the mouse leaving the markup-view area
  * @param {InspectorPanel} inspector The instance of InspectorPanel currently loaded in the toolbox
  * @return a promise when done
  */
 function mouseLeaveMarkupView(inspector) {
   info("Leaving the markup-view area");
   let def = promise.defer();
 
   // Find another element to mouseover over in order to leave the markup-view
   let btn = inspector.toolbox.doc.querySelector(".toolbox-dock-button");
 
-  EventUtils.synthesizeMouse(btn, 2, 2, {type: "mousemove"},
+  EventUtils.synthesizeMouseAtCenter(btn, {type: "mousemove"},
     inspector.toolbox.doc.defaultView);
   executeSoon(def.resolve);
 
   return def.promise;
 }
 
 /**
  * Focus a given editable element, enter edit mode, set value, and commit
--- a/browser/devtools/scratchpad/test/browser_scratchpad_revert_to_saved.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_revert_to_saved.js
@@ -85,18 +85,17 @@ function testAfterSecondSave() {
 function testAfterSecondRevert() {
   // Check if the file's text got reverted
   is(gScratchpad.getText(), gFileContent + "\nalert(foo.toSource());",
      "The text reverted back to the changed saved text.");
   // The revert menu should be disabled again.
   ok(menu.hasAttribute("disabled"),
      "Revert menu entry is disabled after reverting to changed saved state.");
   gFile.remove(false);
-  gFile = null;
-  gScratchpad = null;
+  gFile = gScratchpad = menu = null;
   finish();
 }
 
 function createAndLoadTemporaryFile()
 {
   // Create a temporary file.
   gFile = FileUtils.getFile("TmpD", [gFileName]);
   gFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
--- a/browser/devtools/webconsole/test/browser_console_variables_view_highlighter.js
+++ b/browser/devtools/webconsole/test/browser_console_variables_view_highlighter.js
@@ -61,17 +61,17 @@ function onNodeListVviewFetched(aEvent, 
           clickOnDomNodeVariableAndAssertInspectorSelected(index);
         });
       });
 
       // Rather than trying to emulate a mouseenter event, let's call the
       // variable's highlightDomNode and see if it has the desired effect
       prop.highlightDomNode();
     } else {
-      finishTest();
+      finishUp();
     }
   }
 
   function clickOnDomNodeVariableAndAssertInspectorSelected(index) {
     let prop = props[index][1];
 
     // Make sure the inspector is initialized so we can listen to its events
     gToolbox.initInspector().then(() => {
@@ -84,8 +84,14 @@ function onNodeListVviewFetched(aEvent, 
           hoverOverDomNodeVariableAndAssertHighlighter(index + 1);
         });
       });
     });
   }
 
   hoverOverDomNodeVariableAndAssertHighlighter(0);
 }
+
+function finishUp() {
+  gWebConsole = gJSTerm = gVariablesView = gToolbox = null;
+
+  finishTest();
+}
--- a/browser/devtools/webconsole/test/browser_webconsole_autocomplete_in_debugger_stackframe.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_autocomplete_in_debugger_stackframe.js
@@ -209,17 +209,17 @@ function testCompletion(hud) {
   input.setSelectionRange(11, 11);
   jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
   yield undefined;
 
   newItems = popup.getItems();
   is(newItems.length, 0, "no items for foo2Obj[0]");
 
   testDriver = null;
-  executeSoon(finishTest);
+  executeSoon(finishUp);
   yield undefined;
 }
 
 function debuggerOpened(aResult)
 {
   let debuggerWin = aResult.panelWin;
   let debuggerController = debuggerWin.DebuggerController;
   let thread = debuggerController.activeThread;
@@ -232,8 +232,13 @@ function debuggerOpened(aResult)
   });
 }
 
 function onFramesAdded()
 {
   info("onFramesAdded, openConsole() now");
   executeSoon(() => openConsole(null, testNext));
 }
+
+function finishUp() {
+  testDriver = gStackframes = null;
+  finishTest();
+}
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -327,10 +327,15 @@ function popupHideAfterCompletionInText(
 
   ok(!popup.isOpen, "popup is not open");
   is(inputNode.value, "dump(window.testBug873250b)",
      "completion was successful after VK_TAB");
   is(inputNode.selectionStart, 26, "cursor location is correct");
   is(inputNode.selectionStart, inputNode.selectionEnd, "cursor location (confirmed)");
   ok(!completeNode.value, "completeNode is empty");
 
+  finishUp();
+}
+
+function finishUp() {
+  HUD = popup = jsterm = inputNode = completeNode = null;
   finishTest();
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -79,10 +79,15 @@ function testPropertyPanel()
     EventUtils.synthesizeMouse(anchor, 2, 2, {}, gHUD.iframeWindow);
   });
 }
 
 function onVariablesViewReady(aEvent, aView)
 {
   findVariableViewProperties(aView, [
     { name: "body", value: "<body>" },
-  ], { webconsole: gHUD }).then(finishTest);
+  ], { webconsole: gHUD }).then(finishUp);
 }
+
+function finishUp() {
+  gHUD = null;
+  finishTest();
+}
--- a/browser/devtools/webconsole/test/browser_webconsole_output_01.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_01.js
@@ -84,10 +84,15 @@ function test() {
     DebuggerServer.LONG_STRING_LENGTH = LONG_STRING_LENGTH;
     DebuggerServer.LONG_STRING_INITIAL_LENGTH = LONG_STRING_INITIAL_LENGTH;
   });
 
   Task.spawn(function*() {
     let {tab} = yield loadTab(TEST_URI);
     let hud = yield openConsole(tab);
     return checkOutputForInputs(hud, inputTests);
-  }).then(finishTest);
+  }).then(finishUp);
 }
+
+function finishUp() {
+  inputTests = null;
+  finishTest();
+}
--- a/browser/devtools/webconsole/test/browser_webconsole_output_03.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_03.js
@@ -153,11 +153,17 @@ let inputTests = [
 ];
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", function onLoad() {
     browser.removeEventListener("load", onLoad, true);
     openConsole().then((hud) => {
       return checkOutputForInputs(hud, inputTests);
-    }).then(finishTest);
+    }).then(finishUp);
   }, true);
 }
+
+function finishUp() {
+  inputTests = null;
+
+  finishTest();
+}
--- a/browser/devtools/webconsole/test/browser_webconsole_view_source.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_view_source.js
@@ -66,22 +66,19 @@ let observer = {
   observe: function(aSubject, aTopic, aData) {
     if (aTopic != "domwindowopened") {
       return;
     }
 
     ok(true, "the view source window was opened in response to clicking " +
        "the location node");
 
-    // executeSoon() is necessary to avoid crashing Firefox. See bug 611543.
-    executeSoon(function() {
-      aSubject.close();
-      ok(containsValueInvoked, "custom containsValue() was invoked");
-      Sources.containsValue = containsValue;
-      Sources = containsValue = null;
-      finishTest();
-    });
+    aSubject.close();
+    ok(containsValueInvoked, "custom containsValue() was invoked");
+    Sources.containsValue = containsValue;
+    Sources = containsValue = null;
+    finishTest();
   }
 };
 
 registerCleanupFunction(function() {
   Services.ww.unregisterNotification(observer);
 });
--- a/browser/devtools/webconsole/test/head.js
+++ b/browser/devtools/webconsole/test/head.js
@@ -293,17 +293,17 @@ function dumpMessageElement(aMessage)
                 "severity", aMessage.severity,
                 "repeats", repeats,
                 "clipboardText", aMessage.clipboardText,
                 "text", text);
 }
 
 function finishTest()
 {
-  browser = hudId = hud = filterBox = outputNode = cs = null;
+  browser = hudId = hud = filterBox = outputNode = cs = hudBox = null;
 
   dumpConsoles();
 
   let browserConsole = HUDService.getBrowserConsole();
   if (browserConsole) {
     if (browserConsole.jsterm) {
       browserConsole.jsterm.clearOutput(true);
     }