browser_webconsole_reverse_search.js (5931B)
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 5 // Tests reverse search features. 6 7 "use strict"; 8 9 const TEST_URI = `data:text/html,<!DOCTYPE html><meta charset=utf8>Test reverse search`; 10 const isMacOS = AppConstants.platform === "macosx"; 11 12 add_task(async function () { 13 const hud = await openNewTabAndConsole(TEST_URI); 14 15 const jstermHistory = [ 16 `document`, 17 `Dog = "Snoopy"`, 18 `document 19 .querySelectorAll("*") 20 .forEach(()=>{})`, 21 `document`, 22 `"a" + "😎"`, 23 ]; 24 25 // We have to wait for the same message twice in order to wait for the evaluation line 26 // as well as the result line 27 const onLastMessage = Promise.all([ 28 waitForMessageByType(hud, `"a" + "😎"`, ".command"), 29 waitForMessageByType(hud, `"a😎"`, ".result"), 30 ]); 31 for (const input of jstermHistory) { 32 execute(hud, input); 33 } 34 await onLastMessage; 35 36 const initialValue = "initialValue"; 37 setInputValue(hud, initialValue); 38 39 info("Check that the reverse search toolbar as the expected initial state"); 40 let reverseSearchElement = await openReverseSearch(hud); 41 ok( 42 reverseSearchElement, 43 "Reverse search is displayed with a keyboard shortcut" 44 ); 45 ok( 46 !getReverseSearchInfoElement(hud), 47 "The result info element is not displayed by default" 48 ); 49 ok( 50 !reverseSearchElement.querySelector(".search-result-button-prev") && 51 !reverseSearchElement.querySelector(".search-result-button-next"), 52 "The results navigation buttons are not displayed by default" 53 ); 54 is( 55 getInputValue(hud), 56 initialValue, 57 "The jsterm value is not changed when opening reverse search" 58 ); 59 is(isReverseSearchInputFocused(hud), true, "reverse search input is focused"); 60 61 EventUtils.sendString("d"); 62 let infoElement = await waitFor(() => getReverseSearchInfoElement(hud)); 63 is( 64 infoElement.textContent, 65 "3 of 3 results", 66 "The reverse info has the expected text " + 67 "— duplicated results (`document`) are coalesced" 68 ); 69 70 const previousButton = reverseSearchElement.querySelector( 71 ".search-result-button-prev" 72 ); 73 const nextButton = reverseSearchElement.querySelector( 74 ".search-result-button-next" 75 ); 76 ok(previousButton, "Previous navigation button is now displayed"); 77 is( 78 previousButton.title, 79 `Previous result (${isMacOS ? "Ctrl + R" : "F9"})`, 80 "Previous navigation button has expected title" 81 ); 82 83 ok(nextButton, "Next navigation button is now displayed"); 84 is( 85 nextButton.title, 86 `Next result (${isMacOS ? "Ctrl + S" : "Shift + F9"})`, 87 "Next navigation button has expected title" 88 ); 89 is(getInputValue(hud), "document", "JsTerm has the expected input"); 90 is( 91 hud.jsterm.autocompletePopup.isOpen, 92 false, 93 "Setting the input value did not trigger the autocompletion" 94 ); 95 is(isReverseSearchInputFocused(hud), true, "reverse search input is focused"); 96 97 let onJsTermValueChanged = hud.jsterm.once("set-input-value"); 98 EventUtils.sendString("og"); 99 await onJsTermValueChanged; 100 is(getInputValue(hud), `Dog = "Snoopy"`, "JsTerm input was updated"); 101 is( 102 infoElement.textContent, 103 "1 result", 104 "The reverse info has the expected text" 105 ); 106 ok( 107 !reverseSearchElement.querySelector(".search-result-button-prev") && 108 !reverseSearchElement.querySelector(".search-result-button-next"), 109 "The results navigation buttons are not displayed when there's only one result" 110 ); 111 112 info("Check that the UI and results are updated when typing in the input"); 113 onJsTermValueChanged = hud.jsterm.once("set-input-value"); 114 EventUtils.sendString("g"); 115 await waitFor(() => reverseSearchElement.classList.contains("no-result")); 116 is( 117 getInputValue(hud), 118 `Dog = "Snoopy"`, 119 "JsTerm input was not updated since there's no results" 120 ); 121 is( 122 infoElement.textContent, 123 "No results", 124 "The reverse info has the expected text" 125 ); 126 ok( 127 !reverseSearchElement.querySelector(".search-result-button-prev") && 128 !reverseSearchElement.querySelector(".search-result-button-next"), 129 "The results navigation buttons are not displayed when there's no result" 130 ); 131 132 info("Check that Backspace updates the UI"); 133 EventUtils.synthesizeKey("KEY_Backspace"); 134 await waitFor(() => !reverseSearchElement.classList.contains("no-result")); 135 is( 136 infoElement.textContent, 137 "1 result", 138 "The reverse info has the expected text" 139 ); 140 is(getInputValue(hud), `Dog = "Snoopy"`, "JsTerm kept its value"); 141 142 info("Check that Escape does not affect the jsterm value"); 143 EventUtils.synthesizeKey("KEY_Escape"); 144 await waitFor(() => !getReverseSearchElement(hud)); 145 is( 146 getInputValue(hud), 147 `Dog = "Snoopy"`, 148 "Closing the input did not changed the JsTerm value" 149 ); 150 is(isInputFocused(hud), true, "input is focused"); 151 152 info("Check that the search works with emojis"); 153 reverseSearchElement = await openReverseSearch(hud); 154 onJsTermValueChanged = hud.jsterm.once("set-input-value"); 155 EventUtils.sendString("😎"); 156 infoElement = await waitFor(() => getReverseSearchInfoElement(hud)); 157 is( 158 infoElement.textContent, 159 "1 result", 160 "The reverse info has the expected text" 161 ); 162 163 info("Check that Enter evaluates the JsTerm and closes the UI"); 164 // We have to wait for the same message twice in order to wait for the evaluation line 165 // as well as the result line 166 const onMessage = Promise.all([ 167 waitForMessageByType(hud, `"a" + "😎"`, ".command"), 168 waitForMessageByType(hud, `"a😎"`, ".result"), 169 ]); 170 const onReverseSearchClose = waitFor(() => !getReverseSearchElement(hud)); 171 EventUtils.synthesizeKey("KEY_Enter"); 172 await Promise.all([onMessage, onReverseSearchClose]); 173 ok( 174 true, 175 "Enter evaluates what's in the JsTerm and closes the reverse search UI" 176 ); 177 });