tor-browser

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

browser_toolbox_options_disable_buttons.js (7911B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 let TEST_URL =
      7  "data:text/html;charset=utf8,test for dynamically " +
      8  "registering and unregistering tools";
      9 
     10 // The frames button is only shown if the page has at least one iframe so we
     11 // need to add one to the test page.
     12 TEST_URL += '<iframe src="data:text/plain,iframe"></iframe>';
     13 // The error count button is only shown if there are errors on the page
     14 TEST_URL += '<script>console.error("err")</script>';
     15 
     16 var modifiedPrefs = [];
     17 registerCleanupFunction(() => {
     18  for (const pref of modifiedPrefs) {
     19    Services.prefs.clearUserPref(pref);
     20  }
     21 });
     22 
     23 const TOGGLE_BUTTONS = [
     24  "command-button-measure",
     25  "command-button-rulers",
     26  "command-button-responsive",
     27  "command-button-pick",
     28 ];
     29 
     30 add_task(async function test() {
     31  const tab = await addTab(TEST_URL);
     32  let toolbox = await gDevTools.showToolboxForTab(tab);
     33  const optionsPanelWin = await selectOptionsPanel(toolbox);
     34  await testToggleToolboxButtons(toolbox, optionsPanelWin);
     35  toolbox = await testPrefsAreRespectedWhenReopeningToolbox();
     36  await testButtonStateOnClick(toolbox);
     37 
     38  await toolbox.destroy();
     39 });
     40 
     41 async function selectOptionsPanel(toolbox) {
     42  info("Selecting the options panel");
     43 
     44  const onOptionsSelected = toolbox.once("options-selected");
     45  toolbox.selectTool("options");
     46  const optionsPanel = await onOptionsSelected;
     47  ok(true, "Options panel selected via selectTool method");
     48  return optionsPanel.panelWin;
     49 }
     50 
     51 async function testToggleToolboxButtons(toolbox, optionsPanelWin) {
     52  const checkNodes = [
     53    ...optionsPanelWin.document.querySelectorAll(
     54      "#enabled-toolbox-buttons-box input[type=checkbox]"
     55    ),
     56  ];
     57 
     58  // Filter out all the buttons which are not supported on the current target.
     59  // (DevTools Experimental Preferences etc...)
     60  const toolbarButtons = toolbox.toolbarButtons.filter(tool =>
     61    tool.isToolSupported(toolbox)
     62  );
     63 
     64  const visibleToolbarButtons = toolbarButtons.filter(tool => tool.isVisible);
     65 
     66  const toolbarButtonNodes = [
     67    ...toolbox.doc.querySelectorAll(".command-button"),
     68  ];
     69 
     70  is(
     71    checkNodes.length,
     72    toolbarButtons.length,
     73    "All of the buttons are toggleable."
     74  );
     75  is(
     76    visibleToolbarButtons.length,
     77    toolbarButtonNodes.length,
     78    "All of the DOM buttons are toggleable."
     79  );
     80 
     81  for (const tool of toolbarButtons) {
     82    const id = tool.id;
     83    const matchedCheckboxes = checkNodes.filter(node => node.id === id);
     84    const matchedButtons = toolbarButtonNodes.filter(
     85      button => button.id === id
     86    );
     87    if (tool.isVisible) {
     88      is(
     89        matchedCheckboxes.length,
     90        1,
     91        "There should be a single toggle checkbox for: " + id
     92      );
     93      is(
     94        matchedCheckboxes[0].nextSibling.textContent,
     95        tool.description,
     96        "The label for checkbox matches the tool definition."
     97      );
     98      is(
     99        matchedButtons.length,
    100        1,
    101        "There should be a DOM button for the visible: " + id
    102      );
    103 
    104      // The error count button title isn't its description
    105      if (id !== "command-button-errorcount") {
    106        is(
    107          matchedButtons[0].getAttribute("title"),
    108          tool.description,
    109          "The tooltip for button matches the tool definition."
    110        );
    111      }
    112 
    113      if (TOGGLE_BUTTONS.includes(id)) {
    114        is(
    115          matchedButtons[0].getAttribute("aria-pressed"),
    116          "false",
    117          `The aria-pressed attribute is set to false for ${id} button`
    118        );
    119      } else {
    120        is(
    121          matchedButtons[0].getAttribute("aria-pressed"),
    122          null,
    123          `The ${id} button does not have the aria-pressed attribute`
    124        );
    125      }
    126    } else {
    127      is(
    128        matchedButtons.length,
    129        0,
    130        "There should not be a DOM button for the invisible: " + id
    131      );
    132    }
    133  }
    134 
    135  // Store modified pref names so that they can be cleared on error.
    136  for (const tool of toolbarButtons) {
    137    const pref = tool.visibilityswitch;
    138    modifiedPrefs.push(pref);
    139  }
    140 
    141  // Try checking each checkbox, making sure that it changes the preference
    142  for (const node of checkNodes) {
    143    const tool = toolbarButtons.filter(
    144      commandButton => commandButton.id === node.id
    145    )[0];
    146    const isVisible = getBoolPref(tool.visibilityswitch);
    147 
    148    testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin);
    149    node.click();
    150    testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin);
    151 
    152    const isVisibleAfterClick = getBoolPref(tool.visibilityswitch);
    153 
    154    is(
    155      isVisible,
    156      !isVisibleAfterClick,
    157      "Clicking on the node should have toggled visibility preference for " +
    158        tool.visibilityswitch
    159    );
    160 
    161    if (isVisibleAfterClick) {
    162      const matchedButton = toolbox.doc.getElementById(tool.id);
    163      if (TOGGLE_BUTTONS.includes(tool.id)) {
    164        is(
    165          matchedButton.getAttribute("aria-pressed"),
    166          "false",
    167          `The aria-pressed attribute is set to false for ${tool.id} button`
    168        );
    169      } else {
    170        is(
    171          matchedButton.getAttribute("aria-pressed"),
    172          null,
    173          `The ${tool.id} button does not have the aria-pressed attribute`
    174        );
    175      }
    176    }
    177  }
    178 }
    179 
    180 async function testPrefsAreRespectedWhenReopeningToolbox() {
    181  info("Closing toolbox to test after reopening");
    182  await gDevTools.closeToolboxForTab(gBrowser.selectedTab);
    183 
    184  const toolbox = await gDevTools.showToolboxForTab(gBrowser.selectedTab);
    185  const optionsPanelWin = await selectOptionsPanel(toolbox);
    186 
    187  info("Toolbox has been reopened.  Checking UI state.");
    188  await testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin);
    189  return toolbox;
    190 }
    191 
    192 function testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin) {
    193  const checkNodes = [
    194    ...optionsPanelWin.document.querySelectorAll(
    195      "#enabled-toolbox-buttons-box input[type=checkbox]"
    196    ),
    197  ];
    198  const toolboxButtonNodes = [
    199    ...toolbox.doc.querySelectorAll(".command-button"),
    200  ];
    201 
    202  for (const tool of toolbox.toolbarButtons) {
    203    const isVisible = getBoolPref(tool.visibilityswitch);
    204 
    205    const button = toolboxButtonNodes.find(
    206      toolboxButton => toolboxButton.id === tool.id
    207    );
    208    is(!!button, isVisible, "Button visibility matches pref for " + tool.id);
    209 
    210    const check = checkNodes.filter(node => node.id === tool.id)[0];
    211    if (check) {
    212      is(
    213        check.checked,
    214        isVisible,
    215        "Checkbox should be selected based on current pref for " + tool.id
    216      );
    217    }
    218  }
    219 }
    220 
    221 async function testButtonStateOnClick(toolbox) {
    222  const toolboxButtons = ["#command-button-rulers", "#command-button-measure"];
    223  for (const toolboxButton of toolboxButtons) {
    224    const button = toolbox.doc.querySelector(toolboxButton);
    225    if (!button) {
    226      ok(false, `Couldn't find ${toolboxButton}`);
    227      continue;
    228    }
    229 
    230    const isChecked = waitUntil(() => button.classList.contains("checked"));
    231    is(
    232      button.getAttribute("aria-pressed"),
    233      "false",
    234      `${toolboxButton} has aria-pressed set to false when it's off`
    235    );
    236 
    237    button.click();
    238    await isChecked;
    239    ok(
    240      button.classList.contains("checked"),
    241      `Button for ${toolboxButton} can be toggled on`
    242    );
    243    is(
    244      button.getAttribute("aria-pressed"),
    245      "true",
    246      `${toolboxButton} has aria-pressed set to true when it's on`
    247    );
    248 
    249    const isUnchecked = waitUntil(() => !button.classList.contains("checked"));
    250    button.click();
    251    await isUnchecked;
    252    ok(
    253      !button.classList.contains("checked"),
    254      `Button for ${toolboxButton} can be toggled off`
    255    );
    256    is(
    257      button.getAttribute("aria-pressed"),
    258      "false",
    259      `aria-pressed is set back to false on ${toolboxButton} after it has been toggled off`
    260    );
    261  }
    262 }
    263 
    264 function getBoolPref(key) {
    265  try {
    266    return Services.prefs.getBoolPref(key);
    267  } catch (e) {
    268    return false;
    269  }
    270 }