Bug 1106272 - Part 3: Test for the selector highlighter feature in the rule-view. r=miker
authorPatrick Brosset <pbrosset@mozilla.com>
Tue, 24 Mar 2015 15:57:33 +0100
changeset 266190 6ddf505a7c22ab788a91663a5cdb7bca7b23f469
parent 266189 bcfa33e0315c7d037b006c09540db2fe4cc7b3f0
child 266191 718d356434012dd3d4db320bc68be89266b023fa
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiker
bugs1106272
milestone39.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 1106272 - Part 3: Test for the selector highlighter feature in the rule-view. r=miker
browser/devtools/styleinspector/rule-view.js
browser/devtools/styleinspector/test/browser.ini
browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_01.js
browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_02.js
browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_03.js
browser/devtools/styleinspector/test/head.js
--- a/browser/devtools/styleinspector/rule-view.js
+++ b/browser/devtools/styleinspector/rule-view.js
@@ -1254,19 +1254,22 @@ CssRuleView.prototype = {
     }
     selectorIcon.classList.remove("highlighted");
 
     this.unhighlightSelector().then(() => {
       if (selector !== this.highlightedSelector) {
         this.highlightedSelector = selector;
         selectorIcon.classList.add("highlighted");
         this.lastSelectorIcon = selectorIcon;
-        this.highlightSelector(selector).catch(Cu.reportError);
+        this.highlightSelector(selector).then(() => {
+          this.emit("ruleview-selectorhighlighter-toggled", true);
+        }, Cu.reportError);
       } else {
         this.highlightedSelector = null;
+        this.emit("ruleview-selectorhighlighter-toggled", false);
       }
     }, Cu.reportError);
   },
 
   highlightSelector: Task.async(function*(selector) {
     let node = this.inspector.selection.nodeFront;
 
     let highlighter = yield this.getSelectorHighlighter();
--- a/browser/devtools/styleinspector/test/browser.ini
+++ b/browser/devtools/styleinspector/test/browser.ini
@@ -97,16 +97,17 @@ skip-if = (os == "win" && debug) || e10s
 [browser_ruleview_pseudo-element_02.js]
 skip-if = e10s # Bug 1090340
 [browser_ruleview_refresh-on-attribute-change_01.js]
 [browser_ruleview_refresh-on-attribute-change_02.js]
 [browser_ruleview_refresh-on-style-change.js]
 [browser_ruleview_select-and-copy-styles.js]
 [browser_ruleview_selector-highlighter_01.js]
 [browser_ruleview_selector-highlighter_02.js]
+[browser_ruleview_selector-highlighter_03.js]
 [browser_ruleview_style-editor-link.js]
 skip-if = e10s # bug 1040670 Cannot open inline styles in viewSourceUtils
 [browser_ruleview_urls-clickable.js]
 [browser_ruleview_user-agent-styles.js]
 [browser_ruleview_user-agent-styles-uneditable.js]
 [browser_ruleview_user-property-reset.js]
 [browser_styleinspector_context-menu-copy-color_01.js]
 [browser_styleinspector_context-menu-copy-color_02.js]
--- a/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_01.js
@@ -1,44 +1,34 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-// Test that the selector highlighter is created when hovering over a selector
-// in the rule view
+// Test that the selector highlighter is created when clicking on a selector
+// icon in the rule view.
 
 const PAGE_CONTENT = [
   '<style type="text/css">',
   '  body, p, td {',
   '    background: red;',
   '  }',
   '</style>',
   'Test the selector highlighter'
 ].join("\n");
 
-let TYPE = "SelectorHighlighter";
-
 add_task(function*() {
   yield addTab("data:text/html;charset=utf-8," + PAGE_CONTENT);
 
-  let {view: rView} = yield openRuleView();
-  let hs = rView.highlighters;
+  let {view} = yield openRuleView();
+  ok(!view.selectorHighlighter, "No selectorhighlighter exist in the rule-view");
 
-  ok(!hs.highlighters[TYPE], "No highlighter exists in the rule-view (1)");
-  ok(!hs.promises[TYPE], "No highlighter is being created in the rule-view (1)");
+  info("Clicking on a selector icon");
+  let icon = getRuleViewSelectorHighlighterIcon(view, "body, p, td");
 
-  info("Faking a mousemove NOT on a selector");
-  let {valueSpan} = getRuleViewProperty(rView, "body, p, td", "background");
-  hs._onMouseMove({target: valueSpan});
-  ok(!hs.highlighters[TYPE], "No highlighter exists in the rule-view (2)");
-  ok(!hs.promises[TYPE], "No highlighter is being created in the rule-view (2)");
+  let onToggled = view.once("ruleview-selectorhighlighter-toggled");
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  let isVisible = yield onToggled;
 
-  info("Faking a mousemove on the body selector");
-  let selectorContainer = getRuleViewSelector(rView, "body, p, td");
-  // The highlighter appears for individual selectors only
-  let bodySelector = selectorContainer.firstElementChild;
-  hs._onMouseMove({target: bodySelector});
-  ok(hs.promises[TYPE], "The highlighter is being initialized");
-  let h = yield hs.promises[TYPE];
-  is(h, hs.highlighters[TYPE], "The initialized highlighter is the right one");
+  ok(view.selectorHighlighter, "The selectorhighlighter instance was created");
+  ok(isVisible, "The toggle event says the highlighter is visible");
 });
--- a/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_02.js
@@ -1,15 +1,15 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-// Test that the selector highlighter is shown when hovering over a selector
+// Test that the selector highlighter is shown when clicking on a selector icon
 // in the rule-view
 
 // Note that in this test, we mock the highlighter front, merely testing the
 // behavior of the style-inspector UI for now
 
 const PAGE_CONTENT = [
   '<style type="text/css">',
   '  body {',
@@ -17,22 +17,20 @@ const PAGE_CONTENT = [
   '  }',
   '  p {',
   '    color: white;',
   '  }',
   '</style>',
   '<p>Testing the selector highlighter</p>'
 ].join("\n");
 
-const TYPE = "SelectorHighlighter";
-
 add_task(function*() {
   yield addTab("data:text/html;charset=utf-8," + PAGE_CONTENT);
 
-  let {inspector, view: rView} = yield openRuleView();
+  let {inspector, view} = yield openRuleView();
 
   // Mock the highlighter front to get the reference of the NodeFront
   let HighlighterFront = {
     isShown: false,
     nodeFront: null,
     options: null,
     show: function(nodeFront, options) {
       this.nodeFront = nodeFront;
@@ -42,44 +40,46 @@ add_task(function*() {
     hide: function() {
       this.nodeFront = null;
       this.options = null;
       this.isShown = false;
     }
   };
 
   // Inject the mock highlighter in the rule-view
-  rView.highlighters.promises[TYPE] = {
-    then: function(cb) {
-      cb(HighlighterFront);
-    }
-  };
+  view.selectorHighlighter = HighlighterFront;
 
-  let selectorSpan = getRuleViewSelector(rView, "body").firstElementChild;
+  let icon = getRuleViewSelectorHighlighterIcon(view, "body");
 
   info("Checking that the HighlighterFront's show/hide methods are called");
-  rView.highlighters._onMouseMove({target: selectorSpan});
+
+  info("Clicking once on the body selector highlighter icon");
+  yield clickSelectorIcon(icon, view);
   ok(HighlighterFront.isShown, "The highlighter is shown");
-  rView.highlighters._onMouseLeave();
+
+  info("Clicking once again on the body selector highlighter icon");
+  yield clickSelectorIcon(icon, view);
   ok(!HighlighterFront.isShown, "The highlighter is hidden");
 
   info("Checking that the right NodeFront reference and options are passed");
   yield selectNode("p", inspector);
-  selectorSpan = getRuleViewSelector(rView, "p").firstElementChild;
-  rView.highlighters._onMouseMove({target: selectorSpan});
+  icon = getRuleViewSelectorHighlighterIcon(view, "p");
+
+  yield clickSelectorIcon(icon, view);
   is(HighlighterFront.nodeFront.tagName, "P",
     "The right NodeFront is passed to the highlighter (1)");
   is(HighlighterFront.options.selector, "p",
     "The right selector option is passed to the highlighter (1)");
 
   yield selectNode("body", inspector);
-  selectorSpan = getRuleViewSelector(rView, "body").firstElementChild;
-  rView.highlighters._onMouseMove({target: selectorSpan});
+  icon = getRuleViewSelectorHighlighterIcon(view, "body");
+  yield clickSelectorIcon(icon, view);
   is(HighlighterFront.nodeFront.tagName, "BODY",
     "The right NodeFront is passed to the highlighter (2)");
   is(HighlighterFront.options.selector, "body",
     "The right selector option is passed to the highlighter (2)");
+});
 
-  info("Checking that the highlighter gets hidden when hovering somewhere else");
-  let {valueSpan} = getRuleViewProperty(rView, "body", "background");
-  rView.highlighters._onMouseMove({target: valueSpan});
-  ok(!HighlighterFront.isShown, "The highlighter is hidden");
-});
+function* clickSelectorIcon(icon, view) {
+  let onToggled = view.once("ruleview-selectorhighlighter-toggled");
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  yield onToggled;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_03.js
@@ -0,0 +1,84 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the selector highlighter toggling mechanism works correctly.
+
+// Note that in this test, we mock the highlighter front, merely testing the
+// behavior of the style-inspector UI for now
+
+const PAGE_CONTENT = [
+  '<style type="text/css">',
+  '  div {text-decoration: underline;}',
+  '  .node-1 {color: red;}',
+  '  .node-2 {color: green;}',
+  '</style>',
+  '<div class="node-1">Node 1</div>',
+  '<div class="node-2">Node 2</div>'
+].join("\n");
+
+add_task(function*() {
+  yield addTab("data:text/html;charset=utf-8," + PAGE_CONTENT);
+
+  let {inspector, view} = yield openRuleView();
+
+  // Mock the highlighter front.
+  let HighlighterFront = {
+    isShown: false,
+    show: function() {
+      this.isShown = true;
+    },
+    hide: function() {
+      this.isShown = false;
+    }
+  };
+
+  // Inject the mock highlighter in the rule-view
+  view.selectorHighlighter = HighlighterFront;
+
+  info("Select .node-1 and click on the .node-1 selector icon");
+  yield selectNode(".node-1", inspector);
+  let icon = getRuleViewSelectorHighlighterIcon(view, ".node-1");
+  yield clickSelectorIcon(icon, view);
+  ok(HighlighterFront.isShown, "The highlighter is shown");
+
+  info("With .node-1 still selected, click again on the .node-1 selector icon");
+  yield clickSelectorIcon(icon, view);
+  ok(!HighlighterFront.isShown, "The highlighter is now hidden");
+
+  info("With .node-1 still selected, click on the div selector icon");
+  icon = getRuleViewSelectorHighlighterIcon(view, "div");
+  yield clickSelectorIcon(icon, view);
+  ok(HighlighterFront.isShown, "The highlighter is shown again");
+
+  info("With .node-1 still selected, click again on the .node-1 selector icon");
+  icon = getRuleViewSelectorHighlighterIcon(view, ".node-1");
+  yield clickSelectorIcon(icon, view);
+  ok(HighlighterFront.isShown,
+    "The highlighter is shown again since the clicked selector was different");
+
+  info("Selecting .node-2");
+  yield selectNode(".node-2", inspector);
+  ok(HighlighterFront.isShown, "The highlighter is still shown after selection");
+
+  info("With .node-2 selected, click on the div selector icon");
+  icon = getRuleViewSelectorHighlighterIcon(view, "div");
+  yield clickSelectorIcon(icon, view);
+  ok(HighlighterFront.isShown,
+    "The highlighter is shown still since the selected was different");
+
+  info("Switching back to .node-1 and clicking on the div selector");
+  yield selectNode(".node-1", inspector);
+  icon = getRuleViewSelectorHighlighterIcon(view, "div");
+  yield clickSelectorIcon(icon, view);
+  ok(!HighlighterFront.isShown,
+    "The highlighter is hidden now that the same selector was clicked");
+});
+
+function* clickSelectorIcon(icon, view) {
+  let onToggled = view.once("ruleview-selectorhighlighter-toggled");
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  yield onToggled;
+}
--- a/browser/devtools/styleinspector/test/head.js
+++ b/browser/devtools/styleinspector/test/head.js
@@ -648,16 +648,28 @@ function getRuleViewPropertyValue(view, 
  * @return {DOMNode} The selector DOM element
  */
 function getRuleViewSelector(view, selectorText) {
   let rule = getRuleViewRule(view, selectorText);
   return rule.querySelector(".ruleview-selector, .ruleview-selector-matched");
 }
 
 /**
+ * Get a reference to the selectorhighlighter icon DOM element corresponding to
+ * a given selector in the rule-view
+ * @param {CssRuleView} view The instance of the rule-view panel
+ * @param {String} selectorText The selector in the rule-view to look for
+ * @return {DOMNode} The selectorhighlighter icon DOM element
+ */
+function getRuleViewSelectorHighlighterIcon(view, selectorText) {
+  let rule = getRuleViewRule(view, selectorText);
+  return rule.querySelector(".ruleview-selectorhighlighter");
+}
+
+/**
  * Simulate a color change in a given color picker tooltip, and optionally wait
  * for a given element in the page to have its style changed as a result
  * @param {SwatchColorPickerTooltip} colorPicker
  * @param {Array} newRgba The new color to be set [r, g, b, a]
  * @param {Object} expectedChange Optional object that needs the following props:
  *                 - {DOMNode} element The element in the page that will have its
  *                   style changed.
  *                 - {String} name The style name that will be changed