summaryrefslogtreecommitdiffstats
path: root/devtools/client/sourceeditor/test/browser_editor_find_again.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/sourceeditor/test/browser_editor_find_again.js')
-rw-r--r--devtools/client/sourceeditor/test/browser_editor_find_again.js215
1 files changed, 215 insertions, 0 deletions
diff --git a/devtools/client/sourceeditor/test/browser_editor_find_again.js b/devtools/client/sourceeditor/test/browser_editor_find_again.js
new file mode 100644
index 000000000..f3d80095b
--- /dev/null
+++ b/devtools/client/sourceeditor/test/browser_editor_find_again.js
@@ -0,0 +1,215 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const {LocalizationHelper} = require("devtools/shared/l10n");
+const L10N = new LocalizationHelper("devtools/client/locales/sourceeditor.properties");
+
+const { OS } = Services.appinfo;
+
+// On linux, getting immediately the selection's range here fails, returning
+const FIND_KEY = L10N.getStr("find.key");
+const FINDNEXT_KEY = L10N.getStr("findNext.key");
+const FINDPREV_KEY = L10N.getStr("findPrev.key");
+// the replace's key with the appropriate modifiers based on OS
+const REPLACE_KEY = OS == "Darwin" ? L10N.getStr("replaceAllMac.key") : L10N.getStr("replaceAll.key");
+
+// values like it's not selected – even if the selection is visible.
+// For the record, setting the selection's range immediately doesn't have
+// any effect.
+// It's like the <input> is not ready yet.
+// Therefore, we trigger the UI focus event to the <input>, waiting for the
+// response.
+// Using a timeout could also work, but that is more precise, ensuring also
+// the execution of the listeners added to the <input>'s focus.
+const dispatchAndWaitForFocus = (target) => new Promise((resolve) => {
+ target.addEventListener("focus", function listener() {
+ target.removeEventListener("focus", listener);
+ resolve(target);
+ });
+
+ target.dispatchEvent(new UIEvent("focus"));
+});
+
+function openSearchBox(ed) {
+ let edDoc = ed.container.contentDocument;
+ let edWin = edDoc.defaultView;
+
+ let input = edDoc.querySelector("input[type=search]");
+ ok(!input, "search box closed");
+
+ // The editor needs the focus to properly receive the `synthesizeKey`
+ ed.focus();
+
+ synthesizeKeyShortcut(FINDNEXT_KEY, edWin);
+ input = edDoc.querySelector("input[type=search]");
+ ok(input, "find again command key opens the search box");
+}
+
+function testFindAgain(ed, inputLine, expectCursor, isFindPrev = false) {
+ let edDoc = ed.container.contentDocument;
+ let edWin = edDoc.defaultView;
+
+ let input = edDoc.querySelector("input[type=search]");
+ input.value = inputLine;
+
+ // Ensure the input has the focus before send the key – necessary on Linux,
+ // it seems that during the tests can be lost
+ input.focus();
+
+ if (isFindPrev) {
+ synthesizeKeyShortcut(FINDPREV_KEY, edWin);
+ } else {
+ synthesizeKeyShortcut(FINDNEXT_KEY, edWin);
+ }
+
+ ch(ed.getCursor(), expectCursor,
+ "find: " + inputLine + " expects cursor: " + expectCursor.toSource());
+}
+
+const testSearchBoxTextIsSelected = Task.async(function* (ed) {
+ let edDoc = ed.container.contentDocument;
+ let edWin = edDoc.defaultView;
+
+ let input = edDoc.querySelector("input[type=search]");
+ ok(input, "search box is opened");
+
+ // Ensure the input has the focus before send the key – necessary on Linux,
+ // it seems that during the tests can be lost
+ input.focus();
+
+ // Close search box
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
+
+ input = edDoc.querySelector("input[type=search]");
+ ok(!input, "search box is closed");
+
+ // Re-open the search box
+ synthesizeKeyShortcut(FIND_KEY, edWin);
+
+ input = edDoc.querySelector("input[type=search]");
+ ok(input, "find command key opens the search box");
+
+ yield dispatchAndWaitForFocus(input);
+
+ let { selectionStart, selectionEnd, value } = input;
+
+ ok(selectionStart === 0 && selectionEnd === value.length,
+ "search box's text is selected when re-opened");
+
+ // Removing selection
+ input.setSelectionRange(0, 0);
+
+ synthesizeKeyShortcut(FIND_KEY, edWin);
+
+ ({ selectionStart, selectionEnd } = input);
+
+ ok(selectionStart === 0 && selectionEnd === value.length,
+ "search box's text is selected when find key is pressed");
+
+ // Close search box
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
+});
+
+const testReplaceBoxTextIsSelected = Task.async(function* (ed) {
+ let edDoc = ed.container.contentDocument;
+ let edWin = edDoc.defaultView;
+
+ let input = edDoc.querySelector(".CodeMirror-dialog > input");
+ ok(!input, "dialog box with replace is closed");
+
+ // The editor needs the focus to properly receive the `synthesizeKey`
+ ed.focus();
+
+ synthesizeKeyShortcut(REPLACE_KEY, edWin);
+
+ input = edDoc.querySelector(".CodeMirror-dialog > input");
+ ok(input, "dialog box with replace is opened");
+
+ input.value = "line 5";
+
+ // Ensure the input has the focus before send the key – necessary on Linux,
+ // it seems that during the tests can be lost
+ input.focus();
+
+ yield dispatchAndWaitForFocus(input);
+
+ let { selectionStart, selectionEnd, value } = input;
+
+ ok(!(selectionStart === 0 && selectionEnd === value.length),
+ "Text in dialog box is not selected");
+
+ synthesizeKeyShortcut(REPLACE_KEY, edWin);
+
+ ({ selectionStart, selectionEnd } = input);
+
+ ok(selectionStart === 0 && selectionEnd === value.length,
+ "dialog box's text is selected when replace key is pressed");
+
+ // Close dialog box
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
+});
+
+add_task(function* () {
+ let { ed, win } = yield setup();
+
+ ed.setText([
+ "// line 1",
+ "// line 2",
+ "// line 3",
+ "// line 4",
+ "// line 5"
+ ].join("\n"));
+
+ yield promiseWaitForFocus();
+
+ openSearchBox(ed);
+
+ let testVectors = [
+ // Starting here expect data needs to get updated for length changes to
+ // "textLines" above.
+ ["line",
+ {line: 0, ch: 7}],
+ ["line",
+ {line: 1, ch: 8}],
+ ["line",
+ {line: 2, ch: 9}],
+ ["line",
+ {line: 3, ch: 10}],
+ ["line",
+ {line: 4, ch: 11}],
+ ["ne 3",
+ {line: 2, ch: 11}],
+ ["line 1",
+ {line: 0, ch: 9}],
+ // Testing find prev
+ ["line",
+ {line: 4, ch: 11},
+ true],
+ ["line",
+ {line: 3, ch: 10},
+ true],
+ ["line",
+ {line: 2, ch: 9},
+ true],
+ ["line",
+ {line: 1, ch: 8},
+ true],
+ ["line",
+ {line: 0, ch: 7},
+ true]
+ ];
+
+ for (let v of testVectors) {
+ yield testFindAgain(ed, ...v);
+ }
+
+ yield testSearchBoxTextIsSelected(ed);
+
+ yield testReplaceBoxTextIsSelected(ed);
+
+ teardown(ed, win);
+});