tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_rules_selector-highlighter_02.js (3542B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test that the selector highlighter is shown when clicking on a selector icon
      7 // in the rule-view
      8 
      9 const TEST_URI = `
     10  <style type="text/css">
     11    body {
     12      background: red;
     13    }
     14    p {
     15      color: white;
     16    }
     17 
     18    @scope (.scope-root) to (.scope-limit) {
     19      .b {
     20        background-color: hotpink;
     21      }
     22    }
     23 
     24    :where(.b) {
     25      background-color: gold;
     26    }
     27  </style>
     28  <p>Testing the selector highlighter</p>
     29  <aside class="for-scope">
     30    <div class="scope-root">
     31      <article class="b in-scope">article in scope</article>
     32      <h2 class="b in-scope">h2 in scope</h2>
     33      <div class="scope-limit">
     34        <code class="b outside-scope">code after scope limit</code>
     35      </div>
     36    </div>
     37    <section class="b outside-scope">section outside scope</section>
     38  </aside>
     39 `;
     40 
     41 add_task(async function () {
     42  await pushPref("layout.css.at-scope.enabled", true);
     43 
     44  await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
     45  const { inspector, view } = await openRuleView();
     46  let data;
     47 
     48  info("Clicking once on the body selector highlighter icon");
     49  data = await clickSelectorIcon(view, "body");
     50  ok(data.isShown, "The highlighter is shown");
     51 
     52  info("Clicking once again on the body selector highlighter icon");
     53  data = await clickSelectorIcon(view, "body");
     54  ok(!data.isShown, "The highlighter is hidden");
     55 
     56  info("Checking that the right NodeFront reference and options are passed");
     57  await selectNode("p", inspector);
     58  data = await clickSelectorIcon(view, "p");
     59 
     60  is(
     61    data.nodeFront.tagName,
     62    "P",
     63    "The right NodeFront is passed to the highlighter"
     64  );
     65  is(
     66    data.options.selector,
     67    "p",
     68    "The right selector option is passed to the highlighter"
     69  );
     70  info("Hide the highlighter for the `p` selector");
     71  await clickSelectorIcon(view, "p");
     72 
     73  info("Check that the highlighter works for rules in @scope");
     74  await selectNode("article.in-scope", inspector);
     75 
     76  await clickSelectorIcon(view, ".b");
     77 
     78  // Here we want to check that the selector highlighter is shown for article.b.in-scope and
     79  // h2.b.in-scope, but not code.b.outside-scope, nor section.b.outside-scope.
     80  // The event we get from the highlighter doesn't really indicate which elements the highlighter
     81  // is shown for, so we need to check the highlighter markup directly
     82  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
     83    const doc = content.document;
     84 
     85    // Highlighters are rendered in the shadow DOM, let's get the shadow roots first
     86    const roots = doc.getConnectedShadowRoots();
     87    const highlightedInfobarContent = roots
     88      .map(
     89        root =>
     90          root.querySelector(
     91            ".highlighter-container.box-model #box-model-infobar-container"
     92          )?.textContent
     93      )
     94      .filter(text => !!text)
     95      // The order of highlighter elements in the DOM tree isn't guaranteed,
     96      // let's sort the selector texts.
     97      .sort();
     98 
     99    is(
    100      highlightedInfobarContent.length,
    101      2,
    102      "2 selector highlighters are displayed"
    103    );
    104    if (highlightedInfobarContent.length != 2) {
    105      return;
    106    }
    107 
    108    is(
    109      highlightedInfobarContent[0],
    110      "article.b.in-scope",
    111      "The first highlighter is displayed for the first node in scope"
    112    );
    113 
    114    is(
    115      highlightedInfobarContent[1],
    116      "h2.b.in-scope",
    117      "The second highlighter is displayed for the second node in scope"
    118    );
    119  });
    120 });