Bug 1359217 part 7 - Add test for getCSSStyleRules. r=heycam
authorXidorn Quan <me@upsuper.org>
Mon, 19 Jun 2017 15:45:43 +1000
changeset 364612 9b82992bcacb64e533fb2a626a885cc0ec25f77e
parent 364611 a06509631afb48c44fdbd7a32b625218894a9fce
child 364613 7f312f55453ffd8406f61341e4ec6dd0e49dea74
push id32049
push usercbook@mozilla.com
push dateMon, 19 Jun 2017 11:36:23 +0000
treeherdermozilla-central@26d62a1ac0e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1359217
milestone56.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 1359217 part 7 - Add test for getCSSStyleRules. r=heycam MozReview-Commit-ID: 85gaOcW7opN
layout/inspector/tests/file_getCSSStyleRules-alternate.html
layout/inspector/tests/file_getCSSStyleRules-default.html
layout/inspector/tests/getCSSStyleRules-1.css
layout/inspector/tests/getCSSStyleRules-2.css
layout/inspector/tests/mochitest.ini
layout/inspector/tests/test_getCSSStyleRules.html
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/file_getCSSStyleRules-alternate.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="alternate stylesheet" title="x" href="getCSSStyleRules-1.css">
+<unknowntagname></unknowntagname>
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/file_getCSSStyleRules-default.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="stylesheet" href="getCSSStyleRules-1.css">
+<unknowntagname></unknowntagname>
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/getCSSStyleRules-1.css
@@ -0,0 +1,3 @@
+unknowntagname {
+  z-index: 1;
+}
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/getCSSStyleRules-2.css
@@ -0,0 +1,3 @@
+unknowntagname {
+  z-index: 2;
+}
--- a/layout/inspector/tests/mochitest.ini
+++ b/layout/inspector/tests/mochitest.ini
@@ -14,16 +14,22 @@ support-files =
 [test_bug609549.xhtml]
 [test_bug806192.html]
 [test_bug856317.html]
 [test_bug877690.html]
 [test_bug1006595.html]
 [test_color_to_rgba.html]
 [test_css_property_is_shorthand.html]
 [test_css_property_is_valid.html]
+[test_getCSSStyleRules.html]
+support-files =
+  file_getCSSStyleRules-default.html
+  file_getCSSStyleRules-alternate.html
+  getCSSStyleRules-1.css
+  getCSSStyleRules-2.css
 [test_getCSSPseudoElementNames.html]
 [test_getRelativeRuleLine.html]
 [test_get_all_style_sheets.html]
 [test_is_valid_css_color.html]
 [test_isinheritableproperty.html]
 [test_parseStyleSheet.html]
 [test_parseStyleSheetImport.html]
 [test_selectormatcheselement.html]
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/test_getCSSStyleRules.html
@@ -0,0 +1,202 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for bug 1359217</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<iframe id="test"></iframe>
+<pre id="log">
+<script>
+/**
+ * This test checks that getCSSStyleRules returns correct style set in
+ * various cases. To avoid effects from UA sheets, most of the tests use
+ * an element with "unknowntagname".
+ */
+
+let iframe = document.getElementById("test");
+let domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
+                            .getService(SpecialPowers.Ci.inIDOMUtils);
+const nsIDOMCSSStyleRule = SpecialPowers.Ci["nsIDOMCSSStyleRule"];
+
+SimpleTest.waitForExplicitFinish();
+
+function* getStyleRules(elem) {
+  let rules = domUtils.getCSSStyleRules(elem);
+  for (let i = 0; i < rules.length; i++) {
+    yield SpecialPowers.unwrap(rules.GetElementAt(i)
+                               .QueryInterface(nsIDOMCSSStyleRule));
+  }
+}
+
+// This will check that value of z-index property declarations in the
+// rules from getCSSStyleRules matches the given content.
+function checkRules(doc, rulesContent, queryStr = "unknowntagname") {
+  let elem = doc.querySelector(queryStr);
+  let rules = [...getStyleRules(elem)];
+  is(rules.length, rulesContent.length, "Rule length should match");
+  if (rules.length != rulesContent.length) {
+    return;
+  }
+  for (let i = 0; i < rules.length; i++) {
+    let style = rules[i].style;
+    let expectation = rulesContent[i].toString();
+    is(style.length, 1, "Should contain only one declaration");
+    is(style.zIndex, expectation, "Should match expectation");
+  }
+}
+
+const tests = [
+  {
+    title: "Add new stylesheet",
+    async run(doc) {
+      checkRules(doc, [1]);
+      let link = doc.createElement("link");
+      link.rel = "stylesheet";
+      link.href = "getCSSStyleRules-2.css";
+      doc.head.appendChild(link);
+      // Check the rules synchronously when the stylesheet has not been
+      // loaded, there should still be no rule matches.
+      checkRules(doc, [1]);
+      await new Promise(resolve => { link.onload = resolve; });
+      checkRules(doc, [1, 2]);
+    },
+  },
+  {
+    title: "Remove stylesheet",
+    async run(doc) {
+      checkRules(doc, [1]);
+      doc.querySelector("link").remove();
+      checkRules(doc, []);
+    },
+  },
+  {
+    title: "Enable stylesheet",
+    async run(doc) {
+      // Set disabled flag before we invoke the utils.
+      let link = doc.querySelector("link");
+      link.sheet.disabled = true;
+      checkRules(doc, []);
+      link.sheet.disabled = false;
+      checkRules(doc, [1]);
+    },
+  },
+  {
+    title: "Disable stylesheet",
+    async run(doc) {
+      checkRules(doc, [1]);
+      doc.querySelector("link").sheet.disabled = true;
+      checkRules(doc, []);
+    },
+  },
+  {
+    title: "Change stylesheet set",
+    base: "alternate",
+    async run(doc) {
+      checkRules(doc, []);
+      doc.selectedStyleSheetSet = "x";
+      checkRules(doc, [1]);
+      doc.selectedStyleSheetSet = "";
+      checkRules(doc, []);
+    },
+  },
+  {
+    title: "Add and remove rules",
+    async run(doc) {
+      checkRules(doc, [1]);
+
+      let sheet = doc.querySelector("link").sheet;
+      info("Inserting style rule");
+      sheet.insertRule("unknowntagname { z-index: 3; }", 1);
+      checkRules(doc, [1, 3]);
+
+      info("Removing style rule");
+      sheet.deleteRule(0);
+      checkRules(doc, [3]);
+
+      info("Inserting media rule");
+      sheet.insertRule("@media all { unknowntagname { z-index: 4; } }", 1);
+      checkRules(doc, [3, 4]);
+
+      info("Inserting supports rule");
+      sheet.insertRule(
+        "@supports (z-index: 0) { unknowntagname { z-index: 5; } }", 1);
+      checkRules(doc, [3, 5, 4]);
+
+      info("Inserting import rule");
+      sheet.insertRule("@import url(getCSSStyleRules-2.css);", 0);
+      // There is no notification we can get when the associated style
+      // sheet gets loaded, so we have to query it.
+      while (true) {
+        try {
+          sheet.cssRules[0].styleSheet.cssRules;
+          break;
+        } catch (e) {
+          if (e.name == "InvalidAccessError") {
+            await new Promise(resolve => requestAnimationFrame(resolve));
+          } else {
+            throw e;
+          }
+        }
+      }
+      checkRules(doc, [2, 3, 5, 4]);
+
+      info("Removing supports rule");
+      sheet.deleteRule(2);
+      checkRules(doc, [2, 3, 4]);
+
+      info("Removing media rule");
+      sheet.deleteRule(2);
+      checkRules(doc, [2, 3]);
+
+      info("Removing import rule");
+      sheet.deleteRule(0);
+      checkRules(doc, [3]);
+    },
+  },
+  {
+    title: "Check UA sheets",
+    async run(doc) {
+      doc.querySelector("link").remove();
+      checkRules(doc, []);
+      let elem = doc.querySelector("unknowntagname");
+      elem.setAttribute("dir", "");
+      let seenUnicodeBidi = false;
+      for (let rule of getStyleRules(elem)) {
+        if (rule.style.unicodeBidi == "isolate") {
+          seenUnicodeBidi = true;
+          break;
+        }
+      }
+      ok(seenUnicodeBidi, "Should have unicode-bidi " +
+         "declaration from UA stylesheet html.css");
+    },
+  },
+];
+
+async function runTests() {
+  for (let i = 0; i < tests.length; i++) {
+    let test = tests[i];
+    info(`Test ${i}: ${test.title}`);
+    iframe.src = "about:blank";
+    if (!test.base) {
+      test.base = "default";
+    }
+    iframe.src = `file_getCSSStyleRules-${test.base}.html`;
+    await new Promise(resolve => { iframe.onload = resolve; });
+    try {
+      await test.run(iframe.contentDocument);
+    } catch (e) {
+      ok(false, "JavaScript error: " + e);
+    }
+  }
+  SimpleTest.finish();
+}
+
+runTests();
+
+</script>
+</pre>
+</body>
+</html>