tor-browser

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

browser_rules_user-agent-styles.js (6435B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Check that user agent styles are inspectable via rule view if
      7 // it is preffed on.
      8 
      9 var PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
     10 const { PrefObserver } = require("resource://devtools/client/shared/prefs.js");
     11 
     12 const TEST_URI = URL_ROOT + "doc_author-sheet.html";
     13 
     14 const TEST_DATA = [
     15  {
     16    selector: "blockquote",
     17    numUserRules: 1,
     18    numUARules: 0,
     19  },
     20  {
     21    selector: "pre",
     22    numUserRules: 1,
     23    numUARules: 0,
     24  },
     25  {
     26    selector: "input[type=range]",
     27    numUserRules: 1,
     28    numUARules: 0,
     29  },
     30  {
     31    selector: "input[type=number]",
     32    numUserRules: 1,
     33    numUARules: 0,
     34  },
     35  {
     36    selector: "input[type=color]",
     37    numUserRules: 1,
     38    numUARules: 0,
     39  },
     40  {
     41    selector: "input[type=text]",
     42    numUserRules: 1,
     43    numUARules: 0,
     44  },
     45  {
     46    selector: "progress",
     47    numUserRules: 1,
     48    numUARules: 0,
     49  },
     50  // Note that some tests below assume that the "a" selector is the
     51  // last test in TEST_DATA.
     52  {
     53    selector: "a",
     54    numUserRules: 3,
     55    numUARules: 0,
     56  },
     57 ];
     58 
     59 add_task(async function () {
     60  // Bug 1517210: GC heuristics are broken for this test, so that the test ends up
     61  // running out of memory if we don't force to reduce the GC side before/after the test.
     62  Cu.forceShrinkingGC();
     63 
     64  requestLongerTimeout(4);
     65 
     66  info("Starting the test with the pref set to true before toolbox is opened");
     67  await setUserAgentStylesPref(true);
     68 
     69  await addTab(TEST_URI);
     70  const { inspector, view } = await openRuleView();
     71 
     72  info("Making sure that UA styles are visible on initial load");
     73  await userAgentStylesVisible(inspector, view);
     74 
     75  info("Making sure that setting the pref to false hides UA styles");
     76  await setUserAgentStylesPref(false);
     77  await userAgentStylesNotVisible(inspector, view);
     78 
     79  info("Making sure that resetting the pref to true shows UA styles again");
     80  await setUserAgentStylesPref(true);
     81  await userAgentStylesVisible(inspector, view);
     82 
     83  info("Resetting " + PREF_UA_STYLES);
     84  Services.prefs.clearUserPref(PREF_UA_STYLES);
     85 
     86  // Bug 1517210: GC heuristics are broken for this test, so that the test ends up
     87  // running out of memory if we don't force to reduce the GC side before/after the test.
     88  Cu.forceShrinkingGC();
     89 });
     90 
     91 async function setUserAgentStylesPref(val) {
     92  info("Setting the pref " + PREF_UA_STYLES + " to: " + val);
     93 
     94  // Reset the pref and wait for PrefObserver to callback so UI
     95  // has a chance to get updated.
     96  const prefObserver = new PrefObserver("devtools.");
     97  const oncePrefChanged = new Promise(resolve => {
     98    prefObserver.on(PREF_UA_STYLES, onPrefChanged);
     99 
    100    function onPrefChanged() {
    101      prefObserver.off(PREF_UA_STYLES, onPrefChanged);
    102      resolve();
    103    }
    104  });
    105  Services.prefs.setBoolPref(PREF_UA_STYLES, val);
    106  await oncePrefChanged;
    107 }
    108 
    109 async function userAgentStylesVisible(inspector, view) {
    110  info("Making sure that user agent styles are currently visible");
    111 
    112  let userRules;
    113  let uaRules;
    114 
    115  for (const data of TEST_DATA) {
    116    await selectNode(data.selector, inspector);
    117    await compareAppliedStylesWithUI(inspector, view, "ua");
    118 
    119    userRules = view._elementStyle.rules.filter(rule => rule.editor.isEditable);
    120    uaRules = view._elementStyle.rules.filter(rule => !rule.editor.isEditable);
    121    is(userRules.length, data.numUserRules, "Correct number of user rules");
    122    Assert.greater(uaRules.length, data.numUARules, "Has UA rules");
    123  }
    124 
    125  ok(
    126    userRules.some(rule => rule.matchedSelectorIndexes.length === 1),
    127    "There is an inline style for element in user styles"
    128  );
    129 
    130  // These tests rely on the "a" selector being the last test in
    131  // TEST_DATA.
    132  ok(
    133    uaRules.some(rule => {
    134      const matchedSelectors = rule.matchedSelectorIndexes.map(
    135        index => rule.selector.selectors[index]
    136      );
    137      return matchedSelectors.includes(":any-link");
    138    }),
    139    "There is a rule for :any-link"
    140  );
    141  ok(
    142    uaRules.some(rule => {
    143      const matchedSelectors = rule.matchedSelectorIndexes.map(
    144        index => rule.selector.selectors[index]
    145      );
    146      return matchedSelectors.includes(":link");
    147    }),
    148    "There is a rule for :link"
    149  );
    150  ok(
    151    uaRules.some(rule => {
    152      return rule.matchedSelectorIndexes.length === 1;
    153    }),
    154    "Inline styles for ua styles"
    155  );
    156 }
    157 
    158 async function userAgentStylesNotVisible(inspector, view) {
    159  info("Making sure that user agent styles are not currently visible");
    160 
    161  let userRules;
    162  let uaRules;
    163 
    164  for (const data of TEST_DATA) {
    165    await selectNode(data.selector, inspector);
    166    await compareAppliedStylesWithUI(inspector, view);
    167 
    168    userRules = view._elementStyle.rules.filter(rule => rule.editor.isEditable);
    169    uaRules = view._elementStyle.rules.filter(rule => !rule.editor.isEditable);
    170    is(userRules.length, data.numUserRules, "Correct number of user rules");
    171    is(uaRules.length, data.numUARules, "No UA rules");
    172  }
    173 }
    174 
    175 async function compareAppliedStylesWithUI(inspector, view, filter) {
    176  info("Making sure that UI is consistent with pageStyle.getApplied");
    177 
    178  const pageStyle = inspector.selection.nodeFront.inspectorFront.pageStyle;
    179  let entries = await pageStyle.getApplied(inspector.selection.nodeFront, {
    180    inherited: true,
    181    matchedSelectors: true,
    182    filter,
    183  });
    184 
    185  // We may see multiple entries that map to a given rule; filter the
    186  // duplicates here to match what the UI does.
    187  const entryMap = new Map();
    188  for (const entry of entries) {
    189    entryMap.set(entry.rule, entry);
    190  }
    191  entries = [...entryMap.values()];
    192 
    193  const elementStyle = view._elementStyle;
    194  await waitFor(() => elementStyle.rules.length === entries.length);
    195  is(
    196    elementStyle.rules.length,
    197    entries.length,
    198    "Should have correct number of rules (" + entries.length + ")"
    199  );
    200 
    201  entries = entries.sort((a, b) => {
    202    return (a.pseudoElement || "z") > (b.pseudoElement || "z");
    203  });
    204 
    205  entries.forEach((entry, i) => {
    206    const elementStyleRule = elementStyle.rules[i];
    207    is(
    208      !!elementStyleRule.inherited,
    209      !!entry.inherited,
    210      "Same inherited (" + entry.inherited + ")"
    211    );
    212    is(
    213      elementStyleRule.isSystem,
    214      entry.isSystem,
    215      "Same isSystem (" + entry.isSystem + ")"
    216    );
    217    is(
    218      elementStyleRule.editor.isEditable,
    219      !entry.isSystem,
    220      "Editor isEditable opposite of UA (" + entry.isSystem + ")"
    221    );
    222  });
    223 }