tor-browser

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

browser_jsterm_completion_bracket.js (7836B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 // Tests that code completion works properly with `[`
      5 
      6 "use strict";
      7 
      8 const TEST_URI = `data:text/html;charset=utf8,<!DOCTYPE html><p>test [ completion.
      9  <script>
     10    window.testObject = Object.create(null, Object.getOwnPropertyDescriptors({
     11      bar: 0,
     12      dataTest: 1,
     13      "data-test": 2,
     14      'da"ta"test': 3,
     15      "da\`ta\`test": 4,
     16      "da'ta'test": 5,
     17      "DATA-TEST": 6,
     18      "DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d\\ud83d\\ude80_TEST": 7,
     19    }));
     20  </script>`;
     21 
     22 add_task(async function () {
     23  await pushPref("devtools.editor.autoclosebrackets", false);
     24  const hud = await openNewTabAndConsole(TEST_URI);
     25  await testInputs(hud, false);
     26  await testCompletionTextUpdateOnPopupNavigate(hud, false);
     27  await testAcceptCompletionExistingClosingBracket(hud);
     28 
     29  info("Test again with autoclosebracket set to true");
     30  await pushPref("devtools.editor.autoclosebrackets", true);
     31  const hudAutoclose = await openNewTabAndConsole(TEST_URI);
     32  await testInputs(hudAutoclose, true);
     33  await testCompletionTextUpdateOnPopupNavigate(hudAutoclose, true);
     34  await testAcceptCompletionExistingClosingBracket(hudAutoclose);
     35 });
     36 
     37 async function testInputs(hud, autocloseEnabled) {
     38  const tests = [
     39    {
     40      description: "Check that the popup is opened when typing `[`",
     41      input: "window.testObject[",
     42      expectedItems: [
     43        `"bar"`,
     44        `"da'ta'test"`,
     45        `"da\\"ta\\"test"`,
     46        `"da\`ta\`test"`,
     47        `"data-test"`,
     48        `"dataTest"`,
     49        `"DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST"`,
     50        `"DATA-TEST"`,
     51      ],
     52      expectedCompletionText: autocloseEnabled ? "" : `"bar"]`,
     53      expectedInputAfterCompletion: `window.testObject["bar"]`,
     54    },
     55    {
     56      description: "Test that the list can be filtered even without quote",
     57      input: "window.testObject[d",
     58      expectedItems: [
     59        `"da'ta'test"`,
     60        `"da\\"ta\\"test"`,
     61        `"da\`ta\`test"`,
     62        `"data-test"`,
     63        `"dataTest"`,
     64        `"DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST"`,
     65        `"DATA-TEST"`,
     66      ],
     67      expectedCompletionText: autocloseEnabled ? "" : `a'ta'test"]`,
     68      expectedInputAfterCompletion: `window.testObject["da'ta'test"]`,
     69    },
     70    {
     71      description: "Test filtering with quote and string",
     72      input: `window.testObject["d`,
     73      expectedItems: [
     74        `"da'ta'test"`,
     75        `"da\\"ta\\"test"`,
     76        `"da\`ta\`test"`,
     77        `"data-test"`,
     78        `"dataTest"`,
     79        `"DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST"`,
     80        `"DATA-TEST"`,
     81      ],
     82      expectedCompletionText: autocloseEnabled ? "" : `a'ta'test"]`,
     83      expectedInputAfterCompletion: `window.testObject["da'ta'test"]`,
     84    },
     85    {
     86      description: "Test filtering with simple quote and string",
     87      input: `window.testObject['d`,
     88      expectedItems: [
     89        `'da"ta"test'`,
     90        `'da\\'ta\\'test'`,
     91        `'da\`ta\`test'`,
     92        `'data-test'`,
     93        `'dataTest'`,
     94        `'DAT_\\\\a"\\'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST'`,
     95        `'DATA-TEST'`,
     96      ],
     97      expectedCompletionText: autocloseEnabled ? "" : `a"ta"test']`,
     98      expectedInputAfterCompletion: `window.testObject['da"ta"test']`,
     99    },
    100    {
    101      description: "Test filtering with template literal and string",
    102      input: "window.testObject[`d",
    103      expectedItems: [
    104        "`da'ta'test`",
    105        '`da"ta"test`',
    106        "`da\\`ta\\`test`",
    107        "`data-test`",
    108        "`dataTest`",
    109        "`DAT_\\\\a\"'\\`\\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST`",
    110        "`DATA-TEST`",
    111      ],
    112      expectedCompletionText: autocloseEnabled ? "" : "a'ta'test`]",
    113      expectedInputAfterCompletion: "window.testObject[`da'ta'test`]",
    114    },
    115    {
    116      description: "Test that filtering is case insensitive",
    117      input: "window.testObject[data-t",
    118      expectedItems: [`"data-test"`, `"DATA-TEST"`],
    119      expectedCompletionText: autocloseEnabled ? "" : `est"]`,
    120      expectedInputAfterCompletion: `window.testObject["data-test"]`,
    121    },
    122    {
    123      description:
    124        "Test that filtering without quote displays the popup when there's only 1 match",
    125      input: "window.testObject[DATA-",
    126      expectedItems: [`"DATA-TEST"`],
    127      expectedCompletionText: autocloseEnabled ? "" : `TEST"]`,
    128      expectedInputAfterCompletion: `window.testObject["DATA-TEST"]`,
    129    },
    130  ];
    131 
    132  for (const test of tests) {
    133    await testInput(hud, test);
    134  }
    135 }
    136 
    137 async function testInput(
    138  hud,
    139  {
    140    description,
    141    input,
    142    expectedItems,
    143    expectedCompletionText,
    144    expectedInputAfterCompletion,
    145  }
    146 ) {
    147  const { jsterm } = hud;
    148  const { autocompletePopup } = jsterm;
    149 
    150  info(`${description} - test popup opening`);
    151  const onPopUpOpen = autocompletePopup.once("popup-opened");
    152  EventUtils.sendString(input);
    153  await onPopUpOpen;
    154 
    155  ok(
    156    hasExactPopupLabels(autocompletePopup, expectedItems),
    157    `${description} - popup has expected item, in expected order`
    158  );
    159  checkInputCompletionValue(
    160    hud,
    161    expectedCompletionText,
    162    `${description} - completeNode has expected value`
    163  );
    164 
    165  info(`${description} - test accepting completion`);
    166  const onPopupClose = autocompletePopup.once("popup-closed");
    167  EventUtils.synthesizeKey("KEY_Tab");
    168  await onPopupClose;
    169  checkInputValueAndCursorPosition(
    170    hud,
    171    expectedInputAfterCompletion + "|",
    172    `${description} - input was completed as expected`
    173  );
    174  checkInputCompletionValue(hud, "", `${description} - completeNode is empty`);
    175 
    176  setInputValue(hud, "");
    177 }
    178 
    179 async function testCompletionTextUpdateOnPopupNavigate(hud, autocloseEnabled) {
    180  const { jsterm } = hud;
    181  const { autocompletePopup } = jsterm;
    182 
    183  info(
    184    "Test that navigating the popup list update the completionText as expected"
    185  );
    186  const onPopUpOpen = autocompletePopup.once("popup-opened");
    187  const input = `window.testObject[data`;
    188  EventUtils.sendString(input);
    189  await onPopUpOpen;
    190 
    191  ok(
    192    hasExactPopupLabels(autocompletePopup, [
    193      `"data-test"`,
    194      `"dataTest"`,
    195      `"DATA-TEST"`,
    196    ]),
    197    `popup has expected items, in expected order`
    198  );
    199  checkInputCompletionValue(
    200    hud,
    201    autocloseEnabled ? "" : `-test"]`,
    202    `completeNode has expected value`
    203  );
    204 
    205  EventUtils.synthesizeKey("KEY_ArrowDown");
    206  checkInputCompletionValue(
    207    hud,
    208    autocloseEnabled ? "" : `Test"]`,
    209    `completeNode has expected value`
    210  );
    211 
    212  EventUtils.synthesizeKey("KEY_ArrowDown");
    213  checkInputCompletionValue(
    214    hud,
    215    autocloseEnabled ? "" : `-TEST"]`,
    216    `completeNode has expected value`
    217  );
    218 
    219  const onPopupClose = autocompletePopup.once("popup-closed");
    220  EventUtils.synthesizeKey("KEY_Tab");
    221  await onPopupClose;
    222  checkInputValueAndCursorPosition(
    223    hud,
    224    `window.testObject["DATA-TEST"]|`,
    225    `input was completed as expected after navigating the popup`
    226  );
    227 }
    228 
    229 async function testAcceptCompletionExistingClosingBracket(hud) {
    230  const { jsterm } = hud;
    231  const { autocompletePopup } = jsterm;
    232 
    233  info(
    234    "Check that accepting completion when there's a closing bracket does not append " +
    235      "another closing bracket"
    236  );
    237  await setInputValueForAutocompletion(hud, "window.testObject[]", -1);
    238  const onPopUpOpen = autocompletePopup.once("popup-opened");
    239  EventUtils.sendString(`"b`);
    240  await onPopUpOpen;
    241  ok(
    242    hasExactPopupLabels(autocompletePopup, [`"bar"`]),
    243    `popup has expected item`
    244  );
    245 
    246  const onPopupClose = autocompletePopup.once("popup-closed");
    247  EventUtils.synthesizeKey("KEY_Tab");
    248  await onPopupClose;
    249  checkInputValueAndCursorPosition(
    250    hud,
    251    `window.testObject["bar"]|`,
    252    `input was completed as expected, without adding a closing bracket`
    253  );
    254 }