summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/test/browser/browser_webconsole_reverse_search.js
blob: 67329335fbe4b722e5407d44e8f8ddbf6ee824c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Tests reverse search features.

"use strict";

const TEST_URI = `data:text/html,<!DOCTYPE html><meta charset=utf8>Test reverse search`;
const isMacOS = AppConstants.platform === "macosx";

add_task(async function () {
  const hud = await openNewTabAndConsole(TEST_URI);

  const jstermHistory = [
    `document`,
    `Dog = "Snoopy"`,
    `document
       .querySelectorAll("*")
       .forEach(()=>{})`,
    `document`,
    `"a" + "😎"`,
  ];

  // We have to wait for the same message twice in order to wait for the evaluation line
  // as well as the result line
  const onLastMessage = Promise.all([
    waitForMessageByType(hud, `"a" + "😎"`, ".command"),
    waitForMessageByType(hud, `"a😎"`, ".result"),
  ]);
  for (const input of jstermHistory) {
    execute(hud, input);
  }
  await onLastMessage;

  const initialValue = "initialValue";
  setInputValue(hud, initialValue);

  info("Check that the reverse search toolbar as the expected initial state");
  let reverseSearchElement = await openReverseSearch(hud);
  ok(
    reverseSearchElement,
    "Reverse search is displayed with a keyboard shortcut"
  );
  ok(
    !getReverseSearchInfoElement(hud),
    "The result info element is not displayed by default"
  );
  ok(
    !reverseSearchElement.querySelector(".search-result-button-prev") &&
      !reverseSearchElement.querySelector(".search-result-button-next"),
    "The results navigation buttons are not displayed by default"
  );
  is(
    getInputValue(hud),
    initialValue,
    "The jsterm value is not changed when opening reverse search"
  );
  is(isReverseSearchInputFocused(hud), true, "reverse search input is focused");

  EventUtils.sendString("d");
  let infoElement = await waitFor(() => getReverseSearchInfoElement(hud));
  is(
    infoElement.textContent,
    "3 of 3 results",
    "The reverse info has the expected text " +
      "— duplicated results (`document`) are coalesced"
  );

  const previousButton = reverseSearchElement.querySelector(
    ".search-result-button-prev"
  );
  const nextButton = reverseSearchElement.querySelector(
    ".search-result-button-next"
  );
  ok(previousButton, "Previous navigation button is now displayed");
  is(
    previousButton.title,
    `Previous result (${isMacOS ? "Ctrl + R" : "F9"})`,
    "Previous navigation button has expected title"
  );

  ok(nextButton, "Next navigation button is now displayed");
  is(
    nextButton.title,
    `Next result (${isMacOS ? "Ctrl + S" : "Shift + F9"})`,
    "Next navigation button has expected title"
  );
  is(getInputValue(hud), "document", "JsTerm has the expected input");
  is(
    hud.jsterm.autocompletePopup.isOpen,
    false,
    "Setting the input value did not trigger the autocompletion"
  );
  is(isReverseSearchInputFocused(hud), true, "reverse search input is focused");

  let onJsTermValueChanged = hud.jsterm.once("set-input-value");
  EventUtils.sendString("og");
  await onJsTermValueChanged;
  is(getInputValue(hud), `Dog = "Snoopy"`, "JsTerm input was updated");
  is(
    infoElement.textContent,
    "1 result",
    "The reverse info has the expected text"
  );
  ok(
    !reverseSearchElement.querySelector(".search-result-button-prev") &&
      !reverseSearchElement.querySelector(".search-result-button-next"),
    "The results navigation buttons are not displayed when there's only one result"
  );

  info("Check that the UI and results are updated when typing in the input");
  onJsTermValueChanged = hud.jsterm.once("set-input-value");
  EventUtils.sendString("g");
  await waitFor(() => reverseSearchElement.classList.contains("no-result"));
  is(
    getInputValue(hud),
    `Dog = "Snoopy"`,
    "JsTerm input was not updated since there's no results"
  );
  is(
    infoElement.textContent,
    "No results",
    "The reverse info has the expected text"
  );
  ok(
    !reverseSearchElement.querySelector(".search-result-button-prev") &&
      !reverseSearchElement.querySelector(".search-result-button-next"),
    "The results navigation buttons are not displayed when there's no result"
  );

  info("Check that Backspace updates the UI");
  EventUtils.synthesizeKey("KEY_Backspace");
  await waitFor(() => !reverseSearchElement.classList.contains("no-result"));
  is(
    infoElement.textContent,
    "1 result",
    "The reverse info has the expected text"
  );
  is(getInputValue(hud), `Dog = "Snoopy"`, "JsTerm kept its value");

  info("Check that Escape does not affect the jsterm value");
  EventUtils.synthesizeKey("KEY_Escape");
  await waitFor(() => !getReverseSearchElement(hud));
  is(
    getInputValue(hud),
    `Dog = "Snoopy"`,
    "Closing the input did not changed the JsTerm value"
  );
  is(isInputFocused(hud), true, "input is focused");

  info("Check that the search works with emojis");
  reverseSearchElement = await openReverseSearch(hud);
  onJsTermValueChanged = hud.jsterm.once("set-input-value");
  EventUtils.sendString("😎");
  infoElement = await waitFor(() => getReverseSearchInfoElement(hud));
  is(
    infoElement.textContent,
    "1 result",
    "The reverse info has the expected text"
  );

  info("Check that Enter evaluates the JsTerm and closes the UI");
  // We have to wait for the same message twice in order to wait for the evaluation line
  // as well as the result line
  const onMessage = Promise.all([
    waitForMessageByType(hud, `"a" + "😎"`, ".command"),
    waitForMessageByType(hud, `"a😎"`, ".result"),
  ]);
  const onReverseSearchClose = waitFor(() => !getReverseSearchElement(hud));
  EventUtils.synthesizeKey("KEY_Enter");
  await Promise.all([onMessage, onReverseSearchClose]);
  ok(
    true,
    "Enter evaluates what's in the JsTerm and closes the reverse search UI"
  );
});