tor-browser

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

head.js (6135B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /* All top-level definitions here are exports.  */
      5 /* eslint no-unused-vars: [2, {"vars": "local"}] */
      6 
      7 "use strict";
      8 
      9 Services.scriptloader.loadSubScript(
     10  "chrome://mochitests/content/browser/devtools/client/inspector/shared/test/head.js",
     11  this
     12 );
     13 
     14 const TEST_BASE =
     15  "chrome://mochitests/content/browser/devtools/client/styleeditor/test/";
     16 const TEST_BASE_HTTP =
     17  "http://example.com/browser/devtools/client/styleeditor/test/";
     18 const TEST_BASE_HTTPS =
     19  "https://example.com/browser/devtools/client/styleeditor/test/";
     20 const TEST_HOST = "mochi.test:8888";
     21 
     22 /**
     23 * Add a new test tab in the browser and load the given url.
     24 *
     25 * @param {string} url The url to be loaded in the new tab
     26 * @param {Window} win The window to add the tab to (default: current window).
     27 * @return a promise that resolves to the tab object when the url is loaded
     28 */
     29 var addTab = function (url, win) {
     30  info("Adding a new tab with URL: '" + url + "'");
     31 
     32  return new Promise(resolve => {
     33    const targetWindow = win || window;
     34    const targetBrowser = targetWindow.gBrowser;
     35 
     36    const tab = (targetBrowser.selectedTab = BrowserTestUtils.addTab(
     37      targetBrowser,
     38      url
     39    ));
     40    BrowserTestUtils.browserLoaded(targetBrowser.selectedBrowser).then(
     41      function () {
     42        info("URL '" + url + "' loading complete");
     43        resolve(tab);
     44      }
     45    );
     46  });
     47 };
     48 
     49 var navigateToAndWaitForStyleSheets = async function (url, ui, editorCount) {
     50  const onClear = ui.once("stylesheets-clear");
     51  await navigateTo(url);
     52  await onClear;
     53  await waitUntil(() => ui.editors.length === editorCount);
     54 };
     55 
     56 var reloadPageAndWaitForStyleSheets = async function (ui, editorCount) {
     57  info("Reloading the page.");
     58 
     59  const onClear = ui.once("stylesheets-clear");
     60  let count = 0;
     61  const onAllEditorAdded = new Promise(res => {
     62    const off = ui.on("editor-added", editor => {
     63      count++;
     64      info(`Received ${editor.friendlyName} (${count}/${editorCount})`);
     65      if (count == editorCount) {
     66        res();
     67        off();
     68      }
     69    });
     70  });
     71 
     72  await reloadBrowser();
     73  await onClear;
     74 
     75  await onAllEditorAdded;
     76  info("All expected editors added");
     77 };
     78 
     79 /**
     80 * Open the style editor for the current tab.
     81 */
     82 var openStyleEditor = async function (tab) {
     83  if (!tab) {
     84    tab = gBrowser.selectedTab;
     85  }
     86  const toolbox = await gDevTools.showToolboxForTab(tab, {
     87    toolId: "styleeditor",
     88  });
     89  const panel = toolbox.getPanel("styleeditor");
     90  const ui = panel.UI;
     91 
     92  return { toolbox, panel, ui };
     93 };
     94 
     95 /**
     96 * Creates a new tab in specified window navigates it to the given URL and
     97 * opens style editor in it.
     98 */
     99 var openStyleEditorForURL = async function (url, win) {
    100  const tab = await addTab(url, win);
    101  const result = await openStyleEditor(tab);
    102  result.tab = tab;
    103  return result;
    104 };
    105 
    106 /**
    107 * Send an async message to the frame script and get back the requested
    108 * computed style property.
    109 *
    110 * @param {string} selector
    111 *        The selector used to obtain the element.
    112 * @param {string} pseudo
    113 *        pseudo id to query, or null.
    114 * @param {string} name
    115 *        name of the property.
    116 */
    117 var getComputedStyleProperty = async function (args) {
    118  return SpecialPowers.spawn(
    119    gBrowser.selectedBrowser,
    120    [args],
    121    function ({ selector, pseudo, name }) {
    122      const element = content.document.querySelector(selector);
    123      const style = content.getComputedStyle(element, pseudo);
    124      return style.getPropertyValue(name);
    125    }
    126  );
    127 };
    128 
    129 /**
    130 * Wait for "at-rules-list-changed" events to settle on StyleEditorUI.
    131 * Returns a promise that resolves the number of events caught while waiting.
    132 *
    133 * @param {StyleEditorUI} ui
    134 *        Current StyleEditorUI on which at-rules-list-changed events should be fired.
    135 * @param {number} delay
    136 */
    137 function waitForManyEvents(ui, delay) {
    138  return new Promise(resolve => {
    139    let timer;
    140    let count = 0;
    141    const onEvent = () => {
    142      count++;
    143      clearTimeout(timer);
    144 
    145      // Wait for some time to catch subsequent events.
    146      timer = setTimeout(() => {
    147        // Remove the listener and resolve.
    148        ui.off("at-rules-list-changed", onEvent);
    149        resolve(count);
    150      }, delay);
    151    };
    152    ui.on("at-rules-list-changed", onEvent);
    153  });
    154 }
    155 
    156 /**
    157 * Creates a new style sheet in the Style Editor
    158 
    159 * @param {StyleEditorUI} ui
    160 *        Current StyleEditorUI on which to simulate pressing the + button.
    161 * @param {Window} panelWindow
    162 *        The panelWindow property of the current Style Editor panel.
    163 */
    164 function createNewStyleSheet(ui, panelWindow) {
    165  info("Creating a new stylesheet now");
    166 
    167  return new Promise(resolve => {
    168    ui.once("editor-added", editor => {
    169      editor.getSourceEditor().then(resolve);
    170    });
    171 
    172    waitForFocus(function () {
    173      // create a new style sheet
    174      const newButton = panelWindow.document.querySelector(
    175        ".style-editor-newButton"
    176      );
    177      ok(newButton, "'new' button exists");
    178 
    179      EventUtils.synthesizeMouseAtCenter(newButton, {}, panelWindow);
    180    }, panelWindow);
    181  });
    182 }
    183 
    184 /**
    185 * Returns the panel root element (StyleEditorUI._root)
    186 *
    187 * @param {StyleEditorPanel} panel
    188 * @returns {Element}
    189 */
    190 function getRootElement(panel) {
    191  return panel.panelWindow.document.getElementById("style-editor-chrome");
    192 }
    193 
    194 /**
    195 * Returns the panel context menu element
    196 *
    197 * @param {StyleEditorPanel} panel
    198 * @returns {Element}
    199 */
    200 function getContextMenuElement(panel) {
    201  return panel.panelWindow.document.getElementById("sidebar-context");
    202 }
    203 
    204 /**
    205 * Assert the number of rules displayed in UI
    206 *
    207 * @param {StyleSheetEditor} editor
    208 * @param {number} expected
    209 */
    210 async function assertRuleCount(editor, expected) {
    211  // The rule count is displayed via l10n.setArgs which only applies the value
    212  // asynchronously, so wait for it to be applied.
    213  const element = editor.summary.querySelector(".stylesheet-rule-count");
    214  await waitFor(() => {
    215    return parseInt(element.textContent, 10) === expected;
    216  });
    217  is(parseInt(element.textContent, 10), expected, "the rule count is correct");
    218 }