tor-browser

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

head.js (7218B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 /* eslint no-unused-vars: [2, {"vars": "local"}] */
      4 
      5 "use strict";
      6 
      7 // Import the inspector's head.js first (which itself imports shared-head.js).
      8 Services.scriptloader.loadSubScript(
      9  "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
     10  this
     11 );
     12 
     13 var {
     14  CssRuleView,
     15 } = require("resource://devtools/client/inspector/rules/rules.js");
     16 var {
     17  getInplaceEditorForSpan: inplaceEditor,
     18 } = require("resource://devtools/client/shared/inplace-editor.js");
     19 const {
     20  getCssVariableColor,
     21 } = require("resource://devtools/client/shared/theme.js");
     22 
     23 const TEST_URL_ROOT =
     24  "http://example.com/browser/devtools/client/inspector/shared/test/";
     25 const TEST_URL_ROOT_SSL =
     26  "https://example.com/browser/devtools/client/inspector/shared/test/";
     27 const ROOT_TEST_DIR = getRootDirectory(gTestPath);
     28 const STYLE_INSPECTOR_L10N = new LocalizationHelper(
     29  "devtools/shared/locales/styleinspector.properties"
     30 );
     31 
     32 /**
     33 * The functions found below are here to ease test development and maintenance.
     34 * Most of these functions are stateless and will require some form of context
     35 * (the instance of the current toolbox, or inspector panel for instance).
     36 *
     37 * Most of these functions are async too and return promises.
     38 *
     39 * All tests should follow the following pattern:
     40 *
     41 * add_task(async function() {
     42 *   await addTab(TEST_URI);
     43 *   let {toolbox, inspector} = await openInspector();
     44 *   await inspector.sidebar.select(viewId);
     45 *   let view = inspector.getPanel(viewId).view;
     46 *   await selectNode("#test", inspector);
     47 *   await someAsyncTestFunction(view);
     48 * });
     49 *
     50 * add_task is the way to define the testcase in the test file. It accepts
     51 * a single argument: a function returning a promise (usually async function).
     52 *
     53 * There is no need to clean tabs up at the end of a test as this is done
     54 * automatically.
     55 *
     56 * It is advised not to store any references on the global scope. There
     57 * shouldn't be a need to anyway. Thanks to async functions, test steps, even
     58 * though asynchronous, can be described in a nice flat way, and
     59 * if/for/while/... control flow can be used as in sync code, making it
     60 * possible to write the outline of the test case all in add_task, and delegate
     61 * actual processing and assertions to other functions.
     62 */
     63 
     64 /* *********************************************
     65 * UTILS
     66 * *********************************************
     67 * General test utilities.
     68 * Add new tabs, open the toolbox and switch to the various panels, select
     69 * nodes, get node references, ...
     70 */
     71 
     72 /**
     73 * Polls a given function waiting for it to return true.
     74 *
     75 * @param {Function} validatorFn
     76 *        A validator function that returns a boolean.
     77 *        This is called every few milliseconds to check if the result is true.
     78 *        When it is true, the promise resolves.
     79 * @param {string} name
     80 *        Optional name of the test. This is used to generate
     81 *        the success and failure messages.
     82 * @return a promise that resolves when the function returned true or rejects
     83 * if the timeout is reached
     84 */
     85 function waitForSuccess(validatorFn, name = "untitled") {
     86  return new Promise(resolve => {
     87    function wait(validator) {
     88      if (validator()) {
     89        ok(true, "Validator function " + name + " returned true");
     90        resolve();
     91      } else {
     92        setTimeout(() => wait(validator), 200);
     93      }
     94    }
     95    wait(validatorFn);
     96  });
     97 }
     98 
     99 /**
    100 * Get the dataURL for the font family tooltip.
    101 *
    102 * @param {Window} win
    103 * @param {string} font
    104 *        The font family value.
    105 * @param {object} nodeFront
    106 *        The NodeActor that will used to retrieve the dataURL for the
    107 *        font family tooltip contents.
    108 */
    109 var getFontFamilyDataURL = async function (win, font, nodeFront) {
    110  const fillStyle = getCssVariableColor("--theme-body-color", win);
    111 
    112  const { data } = await nodeFront.getFontFamilyDataURL(font, fillStyle);
    113  const dataURL = await data.string();
    114  return dataURL;
    115 };
    116 
    117 /* *********************************************
    118 * RULE-VIEW
    119 * *********************************************
    120 * Rule-view related test utility functions
    121 * This object contains functions to get rules, get properties, ...
    122 */
    123 
    124 /**
    125 * Simulate a color change in a given color picker tooltip, and optionally wait
    126 * for a given element in the page to have its style changed as a result
    127 *
    128 * @param {RuleView} ruleView
    129 *        The related rule view instance
    130 * @param {SwatchColorPickerTooltip} colorPicker
    131 * @param {Array} newRgba
    132 *        The new color to be set [r, g, b, a]
    133 * @param {object} expectedChange
    134 *        Optional object that needs the following props:
    135 *          - {DOMNode} element The element in the page that will have its
    136 *            style changed.
    137 *          - {String} name The style name that will be changed
    138 *          - {String} value The expected style value
    139 * The style will be checked like so: getComputedStyle(element)[name] === value
    140 */
    141 var simulateColorPickerChange = async function (
    142  ruleView,
    143  colorPicker,
    144  newRgba,
    145  expectedChange
    146 ) {
    147  const onRuleViewChanged = ruleView.once("ruleview-changed");
    148  info("Getting the spectrum colorpicker object");
    149  const spectrum = await colorPicker.spectrum;
    150  info("Setting the new color");
    151  spectrum.rgb = newRgba;
    152  info("Applying the change");
    153  spectrum.updateUI();
    154  spectrum.onChange();
    155  info("Waiting for rule-view to update");
    156  await onRuleViewChanged;
    157 
    158  if (expectedChange) {
    159    info("Waiting for the style to be applied on the page");
    160    await waitForSuccess(() => {
    161      const { element, name, value } = expectedChange;
    162      return content.getComputedStyle(element)[name] === value;
    163    }, "Color picker change applied on the page");
    164  }
    165 };
    166 
    167 /* *********************************************
    168 * COMPUTED-VIEW
    169 * *********************************************
    170 * Computed-view related utility functions.
    171 * Allows to get properties, links, expand properties, ...
    172 */
    173 
    174 /**
    175 * Get references to the name and value span nodes corresponding to a given
    176 * property name in the computed-view
    177 *
    178 * @param {CssComputedView} view
    179 *        The instance of the computed view panel
    180 * @param {string} name
    181 *        The name of the property to retrieve
    182 * @return an object {nameSpan, valueSpan}
    183 */
    184 function getComputedViewProperty(view, name) {
    185  let prop;
    186  for (const property of view.styleDocument.querySelectorAll(
    187    ".computed-property-view"
    188  )) {
    189    const nameSpan = property.querySelector(".computed-property-name");
    190    const valueSpan = property.querySelector(".computed-property-value");
    191 
    192    if (nameSpan.firstChild.textContent === name) {
    193      prop = { nameSpan, valueSpan };
    194      break;
    195    }
    196  }
    197  return prop;
    198 }
    199 
    200 /**
    201 * Get the text value of the property corresponding to a given name in the
    202 * computed-view
    203 *
    204 * @param {CssComputedView} view
    205 *        The instance of the computed view panel
    206 * @param {string} name
    207 *        The name of the property to retrieve
    208 * @return {string} The property value
    209 */
    210 function getComputedViewPropertyValue(view, name, propertyName) {
    211  return getComputedViewProperty(view, name, propertyName).valueSpan
    212    .textContent;
    213 }