Backed out changeset d8ff6c1c6f3a (bug 1471764) for failing devtools' browser_markup_flex_display_badge.js in beta simulations. a=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 04 Sep 2018 18:21:03 +0300
changeset 482912 bdf475b97f93ba424342a184efeaf5f88f1340c5
parent 482878 7d542c1d11cd71d29efae6743780254d1db7c203
child 482914 dfc3b7ab9dff205f75792394117a73a7dd9d0a7f
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersbackout
bugs1471764
milestone63.0a1
backs outd8ff6c1c6f3a518e16ce458d97bee8e9e351c895
Backed out changeset d8ff6c1c6f3a (bug 1471764) for failing devtools' browser_markup_flex_display_badge.js in beta simulations. a=backout
devtools/.eslintrc.mochitests.js
devtools/client/inspector/computed/computed.js
devtools/client/inspector/flexbox/flexbox.js
devtools/client/inspector/grids/grid-inspector.js
devtools/client/inspector/grids/test/.eslintrc.js
devtools/client/inspector/markup/test/.eslintrc.js
devtools/client/inspector/markup/test/browser.ini
devtools/client/inspector/markup/test/browser_markup_flex_display_badge.js
devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js
devtools/client/inspector/markup/test/head.js
devtools/client/inspector/rules/rules.js
devtools/client/inspector/test/shared-head.js
devtools/client/shared/redux/middleware/test/.eslintrc.js
--- a/devtools/.eslintrc.mochitests.js
+++ b/devtools/.eslintrc.mochitests.js
@@ -6,17 +6,16 @@ module.exports = {
   // All globals made available in the test environment.
   "globals": {
     "DevToolsUtils": true,
     "gDevTools": true,
     "once": true,
     "synthesizeKeyFromKeyTag": true,
     "TargetFactory": true,
     "waitForTick": true,
-    "waitUntilState": true,
   },
 
   "parserOptions": {
     "ecmaFeatures": {
       "jsx": true,
     }
   },
 
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -1,21 +1,20 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const promise = require("promise");
-const flags = require("devtools/shared/flags");
 const ToolDefinitions = require("devtools/client/definitions").Tools;
 const CssLogic = require("devtools/shared/inspector/css-logic");
 const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
+const promise = require("promise");
 const OutputParser = require("devtools/client/shared/output-parser");
 const {PrefObserver} = require("devtools/client/shared/prefs");
 const {createChild} = require("devtools/client/inspector/shared/utils");
 const {gDevTools} = require("devtools/client/framework/devtools");
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 const {
   VIEW_NODE_SELECTOR_TYPE,
   VIEW_NODE_PROPERTY_TYPE,
@@ -179,30 +178,24 @@ function CssComputedView(inspector, docu
   this.shortcuts = new KeyShortcuts({ window: this.styleWindow });
   this._onShortcut = this._onShortcut.bind(this);
   this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event));
   this.shortcuts.on("Escape", event => this._onShortcut("Escape", event));
   this.styleDocument.addEventListener("copy", this._onCopy);
   this.styleDocument.addEventListener("mousedown", this.focusWindow);
   this.element.addEventListener("click", this._onClick);
   this.element.addEventListener("contextmenu", this._onContextMenu);
+  this.element.addEventListener("mousemove", () => {
+    this.addHighlightersToView();
+  }, { once: true });
   this.searchField.addEventListener("input", this._onFilterStyles);
   this.searchClearButton.addEventListener("click", this._onClearSearch);
   this.includeBrowserStylesCheckbox.addEventListener("input",
     this._onIncludeBrowserStyles);
 
-  if (flags.testing) {
-    // In tests, we start listening immediately to avoid having to simulate a mousemove.
-    this.highlighters.addToView(this);
-  } else {
-    this.element.addEventListener("mousemove", () => {
-      this.highlighters.addToView(this);
-    }, { once: true });
-  }
-
   this.searchClearButton.hidden = true;
 
   // No results text.
   this.noResults = this.styleDocument.getElementById("computed-no-results");
 
   // Refresh panel when color unit changed or pref for showing
   // original sources changes.
   this._handlePrefChange = this._handlePrefChange.bind(this);
@@ -735,16 +728,24 @@ CssComputedView.prototype = {
 
       clipboardHelper.copyString(text);
     } catch (e) {
       console.error(e);
     }
   },
 
   /**
+   * Adds the highlighters overlay to the computed view. This is called by the "mousemove"
+   * event handler and in shared-head.js when opening and selecting the computed view.
+   */
+  addHighlightersToView() {
+    this.highlighters.addToView(this);
+  },
+
+  /**
    * Destructor for CssComputedView.
    */
   destroy: function() {
     this._viewedElement = null;
     this._outputParser = null;
 
     this._prefObserver.off("devtools.defaultColorUnit", this._handlePrefChange);
     this._prefObserver.destroy();
--- a/devtools/client/inspector/flexbox/flexbox.js
+++ b/devtools/client/inspector/flexbox/flexbox.js
@@ -1,16 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { throttle } = require("devtools/client/inspector/shared/utils");
-const flags = require("devtools/shared/flags");
 
 const {
   clearFlexbox,
   toggleFlexItemShown,
   updateFlexbox,
   updateFlexboxColor,
   updateFlexboxHighlighted,
 } = require("./actions/flexbox");
@@ -58,26 +57,20 @@ class FlexboxInspector {
         "getCurrentFlexbox");
       this.layoutInspector = await this.walker.getLayoutInspector();
     } catch (e) {
       // These calls might fail if called asynchrously after the toolbox is finished
       // closing.
       return;
     }
 
-    if (flags.testing) {
-      // In tests, we start listening immediately to avoid having to simulate a mousemove.
+    this.document.addEventListener("mousemove", () => {
       this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden);
       this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown);
-    } else {
-      this.document.addEventListener("mousemove", () => {
-        this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden);
-        this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown);
-      }, { once: true });
-    }
+    }, { once: true });
 
     this.inspector.sidebar.on("select", this.onSidebarSelect);
 
     this.onSidebarSelect();
   }
 
   destroy() {
     if (this._highlighters) {
@@ -306,83 +299,105 @@ class FlexboxInspector {
    * with new flexbox data.
    *
    * @param  {FlexboxFront|Null} flexboxFront
    *         The FlexboxFront of the flex container for the current node selection.
    */
   async update(flexboxFront) {
     // Stop refreshing if the inspector or store is already destroyed or no node is
     // selected.
-    if (!this.inspector ||
-        !this.store ||
-        !this.inspector.selection.nodeFront ||
-        !this.hasGetCurrentFlexbox) {
+    if (!this.inspector || !this.store || !this.inspector.selection.nodeFront) {
+      return;
+    }
+
+    // Fetch the current flexbox if no flexbox front was passed into this update.
+    if (!flexboxFront) {
+      try {
+        if (!this.hasGetCurrentFlexbox) {
+          return;
+        }
+
+        flexboxFront = await this.layoutInspector.getCurrentFlexbox(
+          this.inspector.selection.nodeFront);
+      } catch (e) {
+        // This call might fail if called asynchrously after the toolbox is finished
+        // closing.
+        return;
+      }
+    }
+
+    // Clear the flexbox panel if there is no flex container for the current node
+    // selection.
+    if (!flexboxFront) {
+      try {
+        this.store.dispatch(clearFlexbox());
+      } catch (e) {
+        // This call might fail if called asynchrously after the toolbox is finished
+        // closing.
+      }
       return;
     }
 
-    try {
-      // Fetch the current flexbox if no flexbox front was passed into this update.
-      if (!flexboxFront) {
-        flexboxFront = await this.layoutInspector.getCurrentFlexbox(
-          this.inspector.selection.nodeFront);
-      }
+    let containerNodeFront = flexboxFront.containerNodeFront;
 
-      // Clear the flexbox panel if there is no flex container for the current node
-      // selection.
-      if (!flexboxFront) {
-        this.store.dispatch(clearFlexbox());
+    // If the FlexboxFront doesn't yet have access to the NodeFront for its container,
+    // then get it from the walker. This happens when the walker hasn't seen this
+    // particular DOM Node in the tree yet or when we are connected to an older server.
+    if (!containerNodeFront) {
+      try {
+        containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID,
+          ["containerEl"]);
+      } catch (e) {
+        // This call might fail if called asynchrously after the toolbox is finished
+        // closing.
         return;
       }
+    }
 
-      // If the FlexboxFront doesn't yet have access to the NodeFront for its container,
-      // then get it from the walker. This happens when the walker hasn't seen this
-      // particular DOM Node in the tree yet or when we are connected to an older server.
-      let containerNodeFront = flexboxFront.containerNodeFront;
-      if (!containerNodeFront) {
-        containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID,
-          ["containerEl"]);
-      }
+    const highlighted = this._highlighters &&
+      containerNodeFront == this.highlighters.flexboxHighlighterShown;
 
-      // Fetch the flex items for the given flex container and the flex item NodeFronts.
-      const flexItems = [];
-      const flexItemFronts = await flexboxFront.getFlexItems();
+    // Fetch the flex items for the given flex container and the flex item NodeFronts.
+    const flexItems = [];
+    const flexItemFronts = await flexboxFront.getFlexItems();
 
-      for (const flexItemFront of flexItemFronts) {
-        let itemNodeFront = flexItemFront.nodeFront;
-        if (!itemNodeFront) {
+    for (const flexItemFront of flexItemFronts) {
+      let itemNodeFront = flexItemFront.nodeFront;
+
+      if (!itemNodeFront) {
+        try {
           itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID,
             ["element"]);
+        } catch (e) {
+          // This call might fail if called asynchrously after the toolbox is finished
+          // closing.
+          return;
         }
-
-        flexItems.push({
-          actorID: flexItemFront.actorID,
-          shown: false,
-          flexItemSizing: flexItemFront.flexItemSizing,
-          nodeFront: itemNodeFront,
-          properties: flexItemFront.properties,
-        });
       }
 
-      const highlighted = this._highlighters &&
-        containerNodeFront == this.highlighters.flexboxHighlighterShown;
-      const currentUrl = this.inspector.target.url;
-      // Get the hostname, if there is no hostname, fall back on protocol
-      // ex: `data:` uri, and `about:` pages
-      const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
-      const customColors = await this.getCustomFlexboxColors();
-      const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
+      flexItems.push({
+        actorID: flexItemFront.actorID,
+        shown: false,
+        flexItemSizing: flexItemFront.flexItemSizing,
+        nodeFront: itemNodeFront,
+        properties: flexItemFront.properties,
+      });
+    }
 
-      this.store.dispatch(updateFlexbox({
-        actorID: flexboxFront.actorID,
-        color,
-        flexItems,
-        highlighted,
-        nodeFront: containerNodeFront,
-        properties: flexboxFront.properties,
-      }));
-    } catch (e) {
-      // This call might fail if called asynchrously after the toolbox is finished
-      // closing.
-    }
+    const currentUrl = this.inspector.target.url;
+    // Get the hostname, if there is no hostname, fall back on protocol
+    // ex: `data:` uri, and `about:` pages
+    const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
+    const customColors = await this.getCustomFlexboxColors();
+    const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
+
+    this.store.dispatch(updateFlexbox({
+      actorID: flexboxFront.actorID,
+      color,
+      flexItems,
+      highlighted,
+      nodeFront: containerNodeFront,
+      properties: flexboxFront.properties,
+    }));
   }
 }
 
 module.exports = FlexboxInspector;
--- a/devtools/client/inspector/grids/grid-inspector.js
+++ b/devtools/client/inspector/grids/grid-inspector.js
@@ -1,17 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const Services = require("Services");
 const { throttle } = require("devtools/client/inspector/shared/utils");
-const flags = require("devtools/shared/flags");
 
 const {
   updateGridColor,
   updateGridHighlighted,
   updateGrids,
 } = require("./actions/grids");
 const {
   updateShowGridAreas,
@@ -93,26 +92,20 @@ class GridInspector {
     try {
       this.layoutInspector = await this.inspector.walker.getLayoutInspector();
     } catch (e) {
       // This call might fail if called asynchrously after the toolbox is finished
       // closing.
       return;
     }
 
-    if (flags.testing) {
-      // In tests, we start listening immediately to avoid having to simulate a mousemove.
+    this.document.addEventListener("mousemove", () => {
       this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden);
       this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown);
-    } else {
-      this.document.addEventListener("mousemove", () => {
-        this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden);
-        this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown);
-      }, { once: true });
-    }
+    }, { once: true });
 
     this.inspector.sidebar.on("select", this.onSidebarSelect);
     this.inspector.on("new-root", this.onNavigate);
 
     this.onSidebarSelect();
   }
 
   /**
--- a/devtools/client/inspector/grids/test/.eslintrc.js
+++ b/devtools/client/inspector/grids/test/.eslintrc.js
@@ -1,6 +1,9 @@
 "use strict";
 
 module.exports = {
   // Extend from the shared list of defined globals for mochitests.
   "extends": "../../../../.eslintrc.mochitests.js",
+  "globals": {
+    "waitUntilState": true
+  }
 };
--- a/devtools/client/inspector/markup/test/.eslintrc.js
+++ b/devtools/client/inspector/markup/test/.eslintrc.js
@@ -1,6 +1,6 @@
 "use strict";
 
 module.exports = {
   // Extend from the shared list of defined globals for mochitests.
-  "extends": "../../../../.eslintrc.mochitests.js",
+  "extends": "../../../../.eslintrc.mochitests.js"
 };
--- a/devtools/client/inspector/markup/test/browser.ini
+++ b/devtools/client/inspector/markup/test/browser.ini
@@ -68,17 +68,16 @@ support-files =
   lib_react_dom_16.2.0_min.js
   lib_react_with_addons_15.3.1_min.js
   lib_react_with_addons_15.4.1.js
   react_external_listeners.js
   !/devtools/client/debugger/new/test/mochitest/helpers.js
   !/devtools/client/inspector/test/head.js
   !/devtools/client/inspector/test/shared-head.js
   !/devtools/client/shared/test/shared-head.js
-  !/devtools/client/shared/test/shared-redux-head.js
   !/devtools/client/shared/test/telemetry-test-helpers.js
   !/devtools/client/shared/test/test-actor.js
   !/devtools/client/shared/test/test-actor-registry.js
 
 [browser_markup_accessibility_focus_blur.js]
 skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keyboard Access setting is set to All Control in System Keyboard Preferences
 [browser_markup_accessibility_navigation.js]
 skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keyboard Access setting is set to All Control in System Keyboard Preferences
@@ -126,18 +125,16 @@ skip-if = true # Bug 1177550
 [browser_markup_events_react_development_15.4.1.js]
 [browser_markup_events_react_development_15.4.1_jsx.js]
 [browser_markup_events_react_production_15.3.1.js]
 [browser_markup_events_react_production_15.3.1_jsx.js]
 [browser_markup_events_react_production_16.2.0.js]
 [browser_markup_events_react_production_16.2.0_jsx.js]
 [browser_markup_events_source_map.js]
 [browser_markup_events-windowed-host.js]
-[browser_markup_flex_display_badge.js]
-[browser_markup_grid_display_badge.js]
 [browser_markup_links_01.js]
 [browser_markup_links_02.js]
 [browser_markup_links_03.js]
 [browser_markup_links_04.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_markup_links_05.js]
 [browser_markup_links_06.js]
deleted file mode 100644
--- a/devtools/client/inspector/markup/test/browser_markup_flex_display_badge.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests that the flex display badge toggles on the flexbox highlighter.
-
-const TEST_URI = `
-  <style type="text/css">
-    #flex {
-      display: flex;
-    }
-  </style>
-  <div id="flex"></div>
-`;
-
-const HIGHLIGHTER_TYPE = "FlexboxHighlighter";
-
-add_task(async function() {
-  await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
-  const { inspector } = await openLayoutView();
-  const { highlighters, store } = inspector;
-
-  info("Check the flex display badge is shown and not active.");
-  await selectNode("#flex", inspector);
-  const flexContainer = await getContainerForSelector("#flex", inspector);
-  const flexDisplayBadge = flexContainer.elt.querySelector(".markup-badge[data-display]");
-  ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active.");
-
-  info("Check the initial state of the flex highlighter.");
-  ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
-    "No flexbox highlighter exists in the highlighters overlay.");
-  ok(!highlighters.flexboxHighlighterShown, "No flexbox highlighter is shown.");
-
-  info("Toggling ON the flexbox highlighter from the flex display badge.");
-  const onHighlighterShown = highlighters.once("flexbox-highlighter-shown");
-  let onCheckboxChange = waitUntilState(store, state => state.flexbox.highlighted);
-  flexDisplayBadge.click();
-  await onHighlighterShown;
-  await onCheckboxChange;
-
-  info("Check the flexbox highlighter is created and flex display badge state.");
-  ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
-    "Flexbox highlighter is created in the highlighters overlay.");
-  ok(highlighters.flexboxHighlighterShown, "Flexbox highlighter is shown.");
-  ok(flexDisplayBadge.classList.contains("active"), "flex display badge is active.");
-
-  info("Toggling OFF the flexbox highlighter from the flex display badge.");
-  const onHighlighterHidden = highlighters.once("flexbox-highlighter-hidden");
-  onCheckboxChange = waitUntilState(store, state => !state.flexbox.highlighted);
-  flexDisplayBadge.click();
-  await onHighlighterHidden;
-  await onCheckboxChange;
-
-  ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active.");
-});
deleted file mode 100644
--- a/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests that the grid display badge toggles on the grid highlighter.
-
-const TEST_URI = `
-  <style type="text/css">
-    #grid {
-      display: grid;
-    }
-  </style>
-  <div id="grid"></div>
-`;
-
-const HIGHLIGHTER_TYPE = "CssGridHighlighter";
-
-add_task(async function() {
-  await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
-  const { inspector } = await openLayoutView();
-  const { highlighters, store } = inspector;
-
-  info("Check the grid display badge is shown and not active.");
-  await selectNode("#grid", inspector);
-  const gridContainer = await getContainerForSelector("#grid", inspector);
-  const gridDisplayBadge = gridContainer.elt.querySelector(".markup-badge[data-display]");
-  ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active.");
-
-  info("Check the initial state of the grid highlighter.");
-  ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
-    "No CSS grid highlighter exists in the highlighters overlay.");
-  ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
-
-  info("Toggling ON the CSS grid highlighter from the grid display badge.");
-  const onHighlighterShown = highlighters.once("grid-highlighter-shown");
-  let onCheckboxChange = waitUntilState(store, state =>
-    state.grids.length === 1 &&
-    state.grids[0].highlighted);
-  gridDisplayBadge.click();
-  await onHighlighterShown;
-  await onCheckboxChange;
-
-  info("Check the CSS grid highlighter is created and grid display badge state.");
-  ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
-    "CSS grid highlighter is created in the highlighters overlay.");
-  ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
-  ok(gridDisplayBadge.classList.contains("active"), "grid display badge is active.");
-
-  info("Toggling OFF the CSS grid highlighter from the grid display badge.");
-  const onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
-  onCheckboxChange = waitUntilState(store, state =>
-    state.grids.length == 1 &&
-    !state.grids[0].highlighted);
-  gridDisplayBadge.click();
-  await onHighlighterHidden;
-  await onCheckboxChange;
-
-  ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active.");
-});
--- a/devtools/client/inspector/markup/test/head.js
+++ b/devtools/client/inspector/markup/test/head.js
@@ -1,25 +1,21 @@
+
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 /* eslint no-unused-vars: [2, {"vars": "local"}] */
 /* import-globals-from ../../test/head.js */
 "use strict";
 
 // Import the inspector's head.js first (which itself imports shared-head.js).
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
   this);
 
-// Load the shared Redux helpers into this compartment.
-Services.scriptloader.loadSubScript(
-  "chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js",
-  this);
-
 var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor");
 var clipboard = require("devtools/shared/platform/clipboard");
 
 // If a test times out we want to see the complete log and not just the last few
 // lines.
 SimpleTest.requestCompleteLog();
 
 // Toggle this pref on to see all DevTools event communication. This is hugely
--- a/devtools/client/inspector/rules/rules.js
+++ b/devtools/client/inspector/rules/rules.js
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const promise = require("promise");
 const Services = require("Services");
-const flags = require("devtools/shared/flags");
 const {l10n} = require("devtools/shared/inspector/css-logic");
 const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
 const OutputParser = require("devtools/client/shared/output-parser");
 const {PrefObserver} = require("devtools/client/shared/prefs");
 const ElementStyle = require("devtools/client/inspector/rules/models/element-style");
 const Rule = require("devtools/client/inspector/rules/models/rule");
 const RuleEditor = require("devtools/client/inspector/rules/views/rule-editor");
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
@@ -147,34 +146,28 @@ function CssRuleView(inspector, document
   this.shortcuts = new KeyShortcuts({ window: this.styleWindow });
   this._onShortcut = this._onShortcut.bind(this);
   this.shortcuts.on("Escape", event => this._onShortcut("Escape", event));
   this.shortcuts.on("Return", event => this._onShortcut("Return", event));
   this.shortcuts.on("Space", event => this._onShortcut("Space", event));
   this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event));
   this.element.addEventListener("copy", this._onCopy);
   this.element.addEventListener("contextmenu", this._onContextMenu);
+  this.element.addEventListener("mousemove", () => {
+    this.addHighlightersToView();
+  }, { once: true });
   this.addRuleButton.addEventListener("click", this._onAddRule);
   this.searchField.addEventListener("input", this._onFilterStyles);
   this.searchClearButton.addEventListener("click", this._onClearSearch);
   this.pseudoClassToggle.addEventListener("click", this._onTogglePseudoClassPanel);
   this.classToggle.addEventListener("click", this._onToggleClassPanel);
   this.hoverCheckbox.addEventListener("click", this._onTogglePseudoClass);
   this.activeCheckbox.addEventListener("click", this._onTogglePseudoClass);
   this.focusCheckbox.addEventListener("click", this._onTogglePseudoClass);
 
-  if (flags.testing) {
-    // In tests, we start listening immediately to avoid having to simulate a mousemove.
-    this.highlighters.addToView(this);
-  } else {
-    this.element.addEventListener("mousemove", () => {
-      this.highlighters.addToView(this);
-    }, { once: true });
-  }
-
   this._handlePrefChange = this._handlePrefChange.bind(this);
   this._handleUAStylePrefChange = this._handleUAStylePrefChange.bind(this);
   this._handleDefaultColorUnitPrefChange =
     this._handleDefaultColorUnitPrefChange.bind(this);
 
   this._prefObserver = new PrefObserver("devtools.");
   this._prefObserver.on(PREF_UA_STYLES, this._handleUAStylePrefChange);
   this._prefObserver.on(PREF_DEFAULT_COLOR_UNIT, this._handleDefaultColorUnitPrefChange);
@@ -1639,16 +1632,24 @@ CssRuleView.prototype = {
                event.target === this.searchField &&
                this._onClearSearch()) {
       // Handle the search box's keypress event. If the escape key is pressed,
       // clear the search box field.
       event.preventDefault();
       event.stopPropagation();
     }
   },
+
+  /**
+   * Adds the highlighters overlay to the rule view. This is called by the "mousemove"
+   * event handler and in shared-head.js when opening and selecting the rule view.
+   */
+  addHighlightersToView() {
+    this.highlighters.addToView(this);
+  },
 };
 
 /**
  * Helper functions
  */
 
 /**
  * Walk up the DOM from a given node until a parent property holder is found.
--- a/devtools/client/inspector/test/shared-head.js
+++ b/devtools/client/inspector/test/shared-head.js
@@ -86,16 +86,19 @@ var openInspectorSidebarTab = async func
 function openRuleView() {
   return openInspector().then(data => {
     const view = data.inspector.getPanel("ruleview").view;
 
     // Replace the view to use a custom debounce function that can be triggered manually
     // through an additional ".flush()" property.
     view.debounce = manualDebounce();
 
+    // Adds the highlighters overlay in the rule view.
+    view.addHighlightersToView();
+
     return {
       toolbox: data.toolbox,
       inspector: data.inspector,
       testActor: data.testActor,
       view,
     };
   });
 }
@@ -105,16 +108,18 @@ function openRuleView() {
  * sidebar tab selected.
  *
  * @return a promise that resolves when the inspector is ready and the computed
  * view is visible and ready
  */
 function openComputedView() {
   return openInspectorSidebarTab("computedview").then(data => {
     const view = data.inspector.getPanel("computedview").computedView;
+    // Adds the highlighters overlay in the computed view.
+    view.addHighlightersToView();
 
     return {
       toolbox: data.toolbox,
       inspector: data.inspector,
       testActor: data.testActor,
       view,
     };
   });
@@ -155,29 +160,33 @@ function openLayoutView() {
 /**
  * Select the rule view sidebar tab on an already opened inspector panel.
  *
  * @param {InspectorPanel} inspector
  *        The opened inspector panel
  * @return {CssRuleView} the rule view
  */
 function selectRuleView(inspector) {
-  return inspector.getPanel("ruleview").view;
+  const view = inspector.getPanel("ruleview").view;
+  view.addHighlightersToView();
+  return view;
 }
 
 /**
  * Select the computed view sidebar tab on an already opened inspector panel.
  *
  * @param {InspectorPanel} inspector
  *        The opened inspector panel
  * @return {CssComputedView} the computed view
  */
 function selectComputedView(inspector) {
   inspector.sidebar.select("computedview");
-  return inspector.getPanel("computedview").computedView;
+  const view = inspector.getPanel("computedview").computedView;
+  view.addHighlightersToView();
+  return view;
 }
 
 /**
  * Select the layout view sidebar tab on an already opened inspector panel.
  *
  * @param  {InspectorPanel} inspector
  * @return {BoxModel} the box model
  */
--- a/devtools/client/shared/redux/middleware/test/.eslintrc.js
+++ b/devtools/client/shared/redux/middleware/test/.eslintrc.js
@@ -3,14 +3,15 @@
 module.exports = {
   // Extend from the shared list of defined globals for mochitests.
   "extends": "../../../../../.eslintrc.mochitests.js",
   "globals": {
     "run_test": true,
     "run_next_test": true,
     "equal": true,
     "do_print": true,
+    "waitUntilState": true
   },
   "rules": {
     // Stop giving errors for run_test
     "camelcase": "off"
   }
 };