tor-browser

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

browser_rules_pseudo_lock_options.js (6884B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Tests that the rule view pseudo lock options work properly.
      7 
      8 const {
      9  PSEUDO_CLASSES,
     10 } = require("resource://devtools/shared/css/constants.js");
     11 const nodeConstants = require("resource://devtools/shared/dom-node-constants.js");
     12 
     13 const TEST_URI = `
     14  <style type='text/css'>
     15    div {
     16      color: red;
     17    }
     18    div:hover {
     19      color: blue;
     20    }
     21    div:active {
     22      color: yellow;
     23    }
     24    div:focus {
     25      color: green;
     26    }
     27    div:focus-within {
     28      color: papayawhip;
     29    }
     30    div:visited {
     31      color: orange;
     32    }
     33    div:focus-visible {
     34      color: wheat;
     35    }
     36    div:target {
     37      color: crimson;
     38    }
     39    aside::after {
     40      content: "-";
     41    }
     42  </style>
     43  <div>test div</div>
     44  <aside>test pseudo</aside>
     45 `;
     46 
     47 add_task(async function () {
     48  await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
     49  const { inspector, view } = await openRuleView();
     50  await selectNode("div", inspector);
     51 
     52  info("Check that the toggle button exists");
     53  const button = inspector.panelDoc.getElementById("pseudo-class-panel-toggle");
     54  ok(button, "The pseudo-class panel toggle button exists");
     55  is(
     56    view.pseudoClassToggle,
     57    button,
     58    "The rule-view refers to the right element"
     59  );
     60  is(
     61    inspector.panelDoc.getElementById(button.getAttribute("aria-controls")),
     62    view.pseudoClassPanel,
     63    "The pseudo-class panel toggle button has valid aria-controls attribute"
     64  );
     65 
     66  await assertPseudoPanelClosed(view);
     67 
     68  info("Toggle the pseudo class panel open");
     69  view.pseudoClassToggle.click();
     70  await assertPseudoPanelOpened(view);
     71 
     72  info("Toggle each pseudo lock and check that the pseudo lock is added");
     73  for (const pseudo of PSEUDO_CLASSES) {
     74    await togglePseudoClass(inspector, view, pseudo);
     75    await assertPseudoAdded(inspector, view, pseudo, 3, 1);
     76    await togglePseudoClass(inspector, view, pseudo);
     77    await assertPseudoRemoved(inspector, view, 2);
     78  }
     79 
     80  info("Toggle all pseudo locks and check that the pseudo lock is added");
     81  await togglePseudoClass(inspector, view, ":hover");
     82  await togglePseudoClass(inspector, view, ":active");
     83  await togglePseudoClass(inspector, view, ":focus");
     84  await togglePseudoClass(inspector, view, ":target");
     85  await assertPseudoAdded(inspector, view, ":target", 6, 1);
     86  await assertPseudoAdded(inspector, view, ":focus", 6, 2);
     87  await assertPseudoAdded(inspector, view, ":active", 6, 3);
     88  await assertPseudoAdded(inspector, view, ":hover", 6, 4);
     89  await togglePseudoClass(inspector, view, ":hover");
     90  await togglePseudoClass(inspector, view, ":active");
     91  await togglePseudoClass(inspector, view, ":focus");
     92  await togglePseudoClass(inspector, view, ":target");
     93  await assertPseudoRemoved(inspector, view, 2);
     94 
     95  info(
     96    "Check that all pseudo locks are unchecked and disabled when selection is null"
     97  );
     98  await view.selectElement(null);
     99  assertPseudoClassCheckboxesState(view, false);
    100 
    101  info("Check that selecting an element again re-enable the checkboxes");
    102  await selectNode("aside", inspector);
    103  assertPseudoClassCheckboxesState(view, true);
    104 
    105  info(
    106    "Check that all pseudo locks are unchecked and disabled when a text node is selected"
    107  );
    108  const asideNodeFront = await getNodeFront("aside", inspector);
    109  const asideChildren = await inspector.walker.children(asideNodeFront);
    110  const [textNodeFront, afterNodeFront] = asideChildren.nodes;
    111  await selectNode(textNodeFront, inspector);
    112  // sanity check
    113  is(
    114    inspector.selection.nodeFront.nodeType,
    115    nodeConstants.TEXT_NODE,
    116    "We selected the text node"
    117  );
    118  assertPseudoClassCheckboxesState(view, false);
    119 
    120  info("Check that selecting an element again re-enable the checkboxes");
    121  await selectNode("aside", inspector);
    122  assertPseudoClassCheckboxesState(view, true);
    123 
    124  info(
    125    "Check that all pseudo locks are unchecked and disabled when a pseudo element is selected"
    126  );
    127  await selectNode(afterNodeFront, inspector);
    128  is(
    129    inspector.selection.nodeFront.displayName,
    130    "::after",
    131    "We selected the ::after pseudo element"
    132  );
    133  assertPseudoClassCheckboxesState(view, false);
    134 
    135  info("Toggle the pseudo class panel close");
    136  view.pseudoClassToggle.click();
    137  await assertPseudoPanelClosed(view);
    138 });
    139 
    140 async function togglePseudoClass(inspector, view, pseudoClass) {
    141  info(`Toggle the pseudo-class ${pseudoClass}, wait for it to be applied`);
    142  const onRefresh = inspector.once("rule-view-refreshed");
    143  const checkbox = getPseudoClassCheckbox(view, pseudoClass);
    144  if (checkbox) {
    145    checkbox.click();
    146  }
    147  await onRefresh;
    148 }
    149 
    150 function assertPseudoAdded(inspector, view, pseudoClass, numRules, childIndex) {
    151  info("Check that the rule view contains the pseudo-class rule");
    152  is(
    153    view.element.children.length,
    154    numRules,
    155    "Should have " + numRules + " rules."
    156  );
    157  is(
    158    getRuleViewRuleEditor(view, childIndex).rule.selectorText,
    159    "div" + pseudoClass,
    160    "rule view is showing " + pseudoClass + " rule"
    161  );
    162 }
    163 
    164 function assertPseudoRemoved(inspector, view, numRules) {
    165  info("Check that the rule view no longer contains the pseudo-class rule");
    166  is(
    167    view.element.children.length,
    168    numRules,
    169    "Should have " + numRules + " rules."
    170  );
    171  is(
    172    getRuleViewRuleEditor(view, 1).rule.selectorText,
    173    "div",
    174    "Second rule is div"
    175  );
    176 }
    177 
    178 function assertPseudoPanelOpened(view) {
    179  info("Check the opened state of the pseudo class panel");
    180  ok(!view.pseudoClassPanel.hidden, "Pseudo Class Panel Opened");
    181  is(
    182    view.pseudoClassToggle.getAttribute("aria-pressed"),
    183    "true",
    184    "The toggle button is pressed"
    185  );
    186 
    187  for (const pseudo of PSEUDO_CLASSES) {
    188    const checkbox = getPseudoClassCheckbox(view, pseudo);
    189    ok(!checkbox.disabled, `${pseudo} checkbox is not disabled`);
    190    is(
    191      checkbox.getAttribute("tabindex"),
    192      "0",
    193      `${pseudo} checkbox has a tabindex of 0`
    194    );
    195  }
    196 }
    197 
    198 function assertPseudoPanelClosed(view) {
    199  info("Check the closed state of the pseudo clas panel");
    200  ok(view.pseudoClassPanel.hidden, "Pseudo Class Panel Hidden");
    201  is(
    202    view.pseudoClassToggle.getAttribute("aria-pressed"),
    203    "false",
    204    "The toggle button is not pressed"
    205  );
    206 
    207  for (const pseudo of PSEUDO_CLASSES) {
    208    const checkbox = getPseudoClassCheckbox(view, pseudo);
    209    is(
    210      checkbox.getAttribute("tabindex"),
    211      "-1",
    212      `${pseudo} checkbox has a tabindex of -1`
    213    );
    214  }
    215 }
    216 
    217 function assertPseudoClassCheckboxesState(view, enabled) {
    218  for (const pseudo of PSEUDO_CLASSES) {
    219    const checkbox = getPseudoClassCheckbox(view, pseudo);
    220    if (enabled) {
    221      ok(!checkbox.disabled, `${pseudo} checkbox is not disabled`);
    222    } else {
    223      ok(
    224        !checkbox.checked && checkbox.disabled,
    225        `${pseudo} checkbox is unchecked and disabled`
    226      );
    227    }
    228  }
    229 }