tor-browser

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

browser_webconsole_telemetry_reverse_search.js (5145B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 // Tests that the console records the reverse search telemetry event with expected data
      5 // on open, navigate forward, navigate back and evaluate expression.
      6 
      7 "use strict";
      8 
      9 const { TelemetryTestUtils } = ChromeUtils.importESModule(
     10  "resource://testing-common/TelemetryTestUtils.sys.mjs"
     11 );
     12 
     13 const TEST_URI = `data:text/html,<!DOCTYPE html><meta charset=utf8>Test reverse_search telemetry event`;
     14 const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS;
     15 const isMacOS = AppConstants.platform === "macosx";
     16 
     17 add_task(async function () {
     18  // Let's reset the counts.
     19  Services.telemetry.clearEvents();
     20 
     21  // Ensure no events have been logged
     22  TelemetryTestUtils.assertNumberOfEvents(0);
     23 
     24  const hud = await openNewTabAndConsole(TEST_URI);
     25 
     26  info("Evaluate single line expressions");
     27  await keyboardExecuteAndWaitForResultMessage(hud, `"single line 1"`, "");
     28  await keyboardExecuteAndWaitForResultMessage(hud, `"single line 2"`, "");
     29  await keyboardExecuteAndWaitForResultMessage(hud, `"single line 3"`, "");
     30 
     31  info("Open editor mode");
     32  await toggleLayout(hud);
     33 
     34  info("Open reverse search from editor mode");
     35  hud.ui.outputNode
     36    .querySelector(".webconsole-editor-toolbar-reverseSearchButton")
     37    .click();
     38 
     39  info("Close reverse search");
     40  EventUtils.synthesizeKey("KEY_Escape");
     41 
     42  info("Open reverse search using keyboard shortcut");
     43  await openReverseSearch(hud);
     44 
     45  info("Send keys to reverse search");
     46  EventUtils.sendString("sin");
     47 
     48  info("Reverse search navigate next - keyboard");
     49  navigateReverseSearch("keyboard", "next", hud);
     50 
     51  info("Reverse search navigate previous - keyboard");
     52  navigateReverseSearch("keyboard", "previous", hud);
     53 
     54  info("Reverse search navigate next - mouse");
     55  navigateReverseSearch("mouse", "next", hud);
     56 
     57  info("Reverse search navigate previous - mouse");
     58  navigateReverseSearch("mouse", "previous", hud);
     59 
     60  info("Reverse search evaluate expression");
     61  const onMessage = waitForMessageByType(hud, "single line 3", ".result");
     62  EventUtils.synthesizeKey("KEY_Enter");
     63  await onMessage;
     64 
     65  info("Check reverse search telemetry");
     66  checkEventTelemetry([
     67    getTelemetryEventData("editor-toolbar-icon", { functionality: "open" }),
     68    getTelemetryEventData("keyboard", { functionality: "open" }),
     69    getTelemetryEventData("keyboard", { functionality: "navigate next" }),
     70    getTelemetryEventData("keyboard", { functionality: "navigate previous" }),
     71    getTelemetryEventData("click", { functionality: "navigate next" }),
     72    getTelemetryEventData("click", { functionality: "navigate previous" }),
     73    getTelemetryEventData(null, { functionality: "evaluate expression" }),
     74  ]);
     75 
     76  info("Revert to inline layout");
     77  await toggleLayout(hud);
     78 });
     79 
     80 function triggerPreviousResultShortcut() {
     81  if (isMacOS) {
     82    EventUtils.synthesizeKey("r", { ctrlKey: true });
     83  } else {
     84    EventUtils.synthesizeKey("VK_F9");
     85  }
     86 }
     87 
     88 function triggerNextResultShortcut() {
     89  if (isMacOS) {
     90    EventUtils.synthesizeKey("s", { ctrlKey: true });
     91  } else {
     92    EventUtils.synthesizeKey("VK_F9", { shiftKey: true });
     93  }
     94 }
     95 
     96 function clickPreviousButton(hud) {
     97  const reverseSearchElement = getReverseSearchElement(hud);
     98  if (!reverseSearchElement) {
     99    return;
    100  }
    101  const button = reverseSearchElement.querySelector(
    102    ".search-result-button-prev"
    103  );
    104  if (!button) {
    105    return;
    106  }
    107 
    108  button.click();
    109 }
    110 
    111 function clickNextButton(hud) {
    112  const reverseSearchElement = getReverseSearchElement(hud);
    113  if (!reverseSearchElement) {
    114    return;
    115  }
    116  const button = reverseSearchElement.querySelector(
    117    ".search-result-button-next"
    118  );
    119  if (!button) {
    120    return;
    121  }
    122  button.click();
    123 }
    124 
    125 function navigateReverseSearch(access, direction, hud) {
    126  if (access == "keyboard") {
    127    if (direction === "previous") {
    128      triggerPreviousResultShortcut();
    129    } else {
    130      triggerNextResultShortcut();
    131    }
    132  } else if (access === "mouse") {
    133    if (direction === "previous") {
    134      clickPreviousButton(hud);
    135    } else {
    136      clickNextButton(hud);
    137    }
    138  }
    139 }
    140 
    141 function getTelemetryEventData(value, extra) {
    142  return {
    143    timestamp: null,
    144    category: "devtools.main",
    145    method: "reverse_search",
    146    object: "webconsole",
    147    value,
    148    extra,
    149  };
    150 }
    151 
    152 function checkEventTelemetry(expectedData) {
    153  const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
    154  const events = snapshot.parent.filter(event => event[2] === "reverse_search");
    155 
    156  for (const [i, expected] of expectedData.entries()) {
    157    const [timestamp, category, method, object, value, extra] = events[i];
    158 
    159    Assert.greater(timestamp, 0, "timestamp is greater than 0");
    160    is(category, expected.category, "'category' is correct");
    161    is(method, expected.method, "'method' is correct");
    162    is(object, expected.object, "'object' is correct");
    163    is(value, expected.value, "'value' is correct");
    164    is(
    165      extra.functionality,
    166      expected.extra.functionality,
    167      "'functionality' is correct"
    168    );
    169    Assert.greater(Number(extra.session_id), 0, "'session_id' is correct");
    170  }
    171 }