tor-browser

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

helper_style_attr_test_runner.js (4797B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /* eslint no-unused-vars: [2, {"vars": "local"}] */
      5 /* import-globals-from head.js */
      6 "use strict";
      7 
      8 /**
      9 * Perform an style attribute edition and autocompletion test in the test
     10 * url, for #node14. Test data should be an
     11 * array of arrays structured as follows :
     12 *  [
     13 *    what key to press,
     14 *    expected input box value after keypress,
     15 *    expected input.selectionStart,
     16 *    expected input.selectionEnd,
     17 *    is popup expected to be open ?
     18 *  ]
     19 *
     20 * The test will start by adding a new attribute on the node, and then send each
     21 * key specified in the testData. The last item of this array should leave the
     22 * new attribute editor, either by committing or cancelling the edit.
     23 *
     24 * @param {InspectorPanel} inspector
     25 * @param {Array} testData
     26 *        Array of arrays representing the characters to type for the new
     27 *        attribute as well as the expected state at each step
     28 */
     29 async function runStyleAttributeAutocompleteTests(inspector, testData) {
     30  info("Expand all markup nodes");
     31  await inspector.markup.expandAll();
     32 
     33  info("Select #node14");
     34  const container = await focusNode("#node14", inspector);
     35 
     36  info("Focus and open the new attribute inplace-editor");
     37  const attr = container.editor.newAttr;
     38  attr.focus();
     39  EventUtils.sendKey("return", inspector.panelWin);
     40  const editor = inplaceEditor(attr);
     41 
     42  for (let i = 0; i < testData.length; i++) {
     43    const data = testData[i];
     44 
     45    // Skip empty key.
     46    if (!data.length) {
     47      continue;
     48    }
     49 
     50    // Expect a markupmutation event at the last iteration since that's when the
     51    // attribute is actually created.
     52    const onMutation =
     53      i === testData.length - 1 ? inspector.once("markupmutation") : null;
     54 
     55    info(`Entering test data ${i}: ${data[0]}, expecting: [${data[1]}]`);
     56    await enterData(data, editor, inspector);
     57 
     58    info(`Test data ${i} entered. Checking state.`);
     59    await checkData(data, editor, inspector);
     60 
     61    await onMutation;
     62  }
     63 
     64  // Undoing the action will remove the new attribute, so make sure to wait for
     65  // the markupmutation event here again.
     66  const onMutation = inspector.once("markupmutation");
     67  while (inspector.markup.undo.canUndo()) {
     68    await undoChange(inspector);
     69  }
     70  await onMutation;
     71 }
     72 
     73 /**
     74 * Process a test data entry.
     75 *
     76 * @param {Array} data
     77 *        test data - click or key - to enter
     78 * @param {InplaceEditor} editor
     79 * @param {InspectorPanel} inspector
     80 * @return {Promise} promise that will resolve when the test data has been
     81 *         applied
     82 */
     83 function enterData(data, editor, inspector) {
     84  const key = data[0];
     85 
     86  if (/^click_[0-9]+$/.test(key)) {
     87    const suggestionIndex = parseInt(key.split("_")[1], 10);
     88    return clickOnSuggestion(suggestionIndex, editor);
     89  }
     90 
     91  return sendKey(key, editor, inspector);
     92 }
     93 
     94 function clickOnSuggestion(index, editor) {
     95  return new Promise(resolve => {
     96    info("Clicking on item " + index + " in the list");
     97    editor.once("after-suggest", () => executeSoon(resolve));
     98    editor.popup.list.childNodes[index].click();
     99  });
    100 }
    101 
    102 function sendKey(key, editor, inspector) {
    103  return new Promise(resolve => {
    104    if (/(down|left|right|back_space|return)/gi.test(key)) {
    105      info("Adding event listener for down|left|right|back_space|return keys");
    106      editor.input.addEventListener("keypress", function onKeypress() {
    107        if (editor.input) {
    108          editor.input.removeEventListener("keypress", onKeypress);
    109        }
    110        executeSoon(resolve);
    111      });
    112    } else {
    113      editor.once("after-suggest", () => executeSoon(resolve));
    114    }
    115 
    116    EventUtils.synthesizeKey(key, {}, inspector.panelWin);
    117  });
    118 }
    119 
    120 /**
    121 * Verify that the inplace editor is in the expected state for the provided
    122 * test data.
    123 */
    124 async function checkData(data, editor, inspector) {
    125  const [, completion, selStart, selEnd, popupOpen] = data;
    126 
    127  if (selEnd != -1) {
    128    is(editor.input.value, completion, "Completed value is correct");
    129    is(
    130      editor.input.selectionStart,
    131      selStart,
    132      "Selection start position is correct"
    133    );
    134    is(editor.input.selectionEnd, selEnd, "Selection end position is correct");
    135    is(
    136      editor.popup.isOpen,
    137      popupOpen,
    138      "Popup is " + (popupOpen ? "open" : "closed")
    139    );
    140  } else {
    141    const nodeFront = await getNodeFront("#node14", inspector);
    142    const container = getContainerForNodeFront(nodeFront, inspector);
    143    const attr = container.editor.attrElements
    144      .get("style")
    145      .querySelector(".editable");
    146    is(
    147      attr.textContent,
    148      completion,
    149      "Correct value is persisted after pressing Enter"
    150    );
    151  }
    152 }