summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_caret_position.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/urlbar/tests/browser/browser_caret_position.js')
-rw-r--r--browser/components/urlbar/tests/browser/browser_caret_position.js359
1 files changed, 359 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/browser/browser_caret_position.js b/browser/components/urlbar/tests/browser/browser_caret_position.js
new file mode 100644
index 0000000000..35eee55efe
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_caret_position.js
@@ -0,0 +1,359 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const LARGE_DATA_URL =
+ "data:text/plain," + [...Array(1000)].map(() => "0123456789").join("");
+
+// Tests for the caret position after gURLBar.setURI().
+add_task(async function setURI() {
+ const testData = [
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: 0,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 20,
+ initialSelectionEnd: 20,
+ expectedSelectionStart: 20,
+ expectedSelectionEnd: 20,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 1,
+ initialSelectionEnd: 20,
+ expectedSelectionStart: 1,
+ expectedSelectionEnd: 20,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: "https://example.com/test".length,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: "https://example.com/test".length,
+ expectedSelectionEnd: "https://example.com/test".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: "https://example.com/test".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.org/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: 0,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.org/test",
+ initialSelectionStart: 20,
+ initialSelectionEnd: 20,
+ expectedSelectionStart: 20,
+ expectedSelectionEnd: 20,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.org/test",
+ initialSelectionStart: 1,
+ initialSelectionEnd: 10,
+ expectedSelectionStart: 1,
+ expectedSelectionEnd: 10,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.org/test",
+ initialSelectionStart: "https://example.".length,
+ initialSelectionEnd: "https://example.c".length,
+ expectedSelectionStart: "https://example.c".length,
+ expectedSelectionEnd: "https://example.c".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.org/test",
+ initialSelectionStart: "https://example.com/test".length,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: "https://example.org/test".length,
+ expectedSelectionEnd: "https://example.org/test".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.org/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: "https://example.org/test".length,
+ expectedSelectionEnd: "https://example.org/test".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/longer",
+ initialSelectionStart: "https://example.com/test".length,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: "https://example.com/longer".length,
+ expectedSelectionEnd: "https://example.com/longer".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "https://example.com/longer",
+ initialSelectionStart: 20,
+ initialSelectionEnd: 20,
+ expectedSelectionStart: 20,
+ expectedSelectionEnd: 20,
+ },
+ {
+ firstURL: "https://example.com/longer",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: "https://example.com/longer".length,
+ expectedSelectionStart: "https://example.com/test".length,
+ expectedSelectionEnd: "https://example.com/test".length,
+ },
+ {
+ firstURL: "https://example.com/longer",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: "https://example.com/longer".length,
+ initialSelectionEnd: "https://example.com/longer".length,
+ expectedSelectionStart: "https://example.com/test".length,
+ expectedSelectionEnd: "https://example.com/test".length,
+ },
+ {
+ firstURL: "https://example.com/longer",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: "https://example.com/longer".length - 1,
+ initialSelectionEnd: "https://example.com/longer".length - 1,
+ expectedSelectionStart: "https://example.com/test".length,
+ expectedSelectionEnd: "https://example.com/test".length,
+ },
+ {
+ firstURL: "https://example.com/longer",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: "https://example.com/longer".length - 1,
+ expectedSelectionStart: "https://example.com/test".length,
+ expectedSelectionEnd: "https://example.com/test".length,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "about:blank",
+ initialSelectionStart: 0,
+ initialSelectionEnd: 0,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "about:blank",
+ initialSelectionStart: 0,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "about:blank",
+ initialSelectionStart: 3,
+ initialSelectionEnd: 4,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "https://example.com/test",
+ secondURL: "about:blank",
+ initialSelectionStart: "https://example.com/test".length,
+ initialSelectionEnd: "https://example.com/test".length,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "about:blank",
+ secondURL: "https://example.com/test",
+ initialSelectionStart: 0,
+ initialSelectionEnd: 0,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "about:blank",
+ secondURL: LARGE_DATA_URL,
+ initialSelectionStart: 0,
+ initialSelectionEnd: 0,
+ expectedSelectionStart: 0,
+ expectedSelectionEnd: 0,
+ },
+ {
+ firstURL: "about:telemetry",
+ secondURL: LARGE_DATA_URL,
+ initialSelectionStart: "about:telemetry".length,
+ initialSelectionEnd: "about:telemetry".length,
+ expectedSelectionStart: LARGE_DATA_URL.length,
+ expectedSelectionEnd: LARGE_DATA_URL.length,
+ },
+ ];
+
+ for (const data of testData) {
+ info(
+ `Test for ${data.firstURL} -> ${data.secondURL} with initial selection: ${data.initialSelectionStart}, ${data.initialSelectionEnd}`
+ );
+ info("Check the caret position after setting second URL");
+ gURLBar.setURI(makeURI(data.firstURL));
+ gURLBar.selectionStart = data.initialSelectionStart;
+ gURLBar.selectionEnd = data.initialSelectionEnd;
+
+ // The change of the scroll amount dependent on the selection change will be
+ // ignored if the previous processing is unfinished yet. Therefore, make the
+ // processing finalize explicitly here.
+ await flushScrollStyle();
+
+ gURLBar.focus();
+ gURLBar.setURI(makeURI(data.secondURL));
+ await flushScrollStyle();
+
+ Assert.equal(gURLBar.selectionStart, data.expectedSelectionStart);
+ Assert.equal(gURLBar.selectionEnd, data.expectedSelectionEnd);
+ if (data.secondURL.length === data.expectedSelectionStart) {
+ // If the caret is at the end of url, the input field shows the end of
+ // text.
+ Assert.equal(
+ gURLBar.inputField.scrollLeft,
+ gURLBar.inputField.scrollLeftMax
+ );
+ }
+
+ info("Check the caret position while the input is not focused");
+ gURLBar.setURI(makeURI(data.firstURL));
+ gURLBar.selectionStart = data.initialSelectionStart;
+ gURLBar.selectionEnd = data.initialSelectionEnd;
+
+ await flushScrollStyle();
+
+ gURLBar.blur();
+ gURLBar.setURI(makeURI(data.secondURL));
+ await flushScrollStyle();
+
+ if (data.firstURL === data.secondURL) {
+ Assert.equal(gURLBar.selectionStart, data.initialSelectionStart);
+ Assert.equal(gURLBar.selectionEnd, data.initialSelectionEnd);
+ } else {
+ Assert.equal(gURLBar.selectionStart, gURLBar.value.length);
+ Assert.equal(gURLBar.selectionEnd, gURLBar.value.length);
+ }
+ Assert.equal(gURLBar.inputField.scrollLeft, 0);
+ }
+});
+
+// Tests that up and down keys move the caret on certain platforms, and that
+// opening the popup doesn't change the caret position.
+add_task(async function navigation() {
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: "This is a generic sentence",
+ });
+ await UrlbarTestUtils.promisePopupClose(window);
+
+ const INITIAL_SELECTION_START = 3;
+ const INITIAL_SELECTION_END = 10;
+ gURLBar.selectionStart = INITIAL_SELECTION_START;
+ gURLBar.selectionEnd = INITIAL_SELECTION_END;
+
+ if (AppConstants.platform == "macosx" || AppConstants.platform == "linux") {
+ await checkCaretMoves(
+ "KEY_ArrowDown",
+ gURLBar.value.length,
+ "Caret should have moved to the end",
+ window
+ );
+ await checkPopupOpens("KEY_ArrowDown", window);
+
+ await checkCaretMoves(
+ "KEY_ArrowUp",
+ 0,
+ "Caret should have moved to the start",
+ window
+ );
+ await checkPopupOpens("KEY_ArrowUp", window);
+ } else {
+ await checkPopupOpens("KEY_ArrowDown", window);
+ await checkPopupOpens("KEY_ArrowUp", window);
+ }
+});
+
+async function checkCaretMoves(key, pos, msg, win) {
+ checkIfKeyStartsQuery(key, false, win);
+ Assert.equal(
+ UrlbarTestUtils.isPopupOpen(win),
+ false,
+ `${key}: Popup shouldn't be open`
+ );
+ Assert.equal(
+ win.gURLBar.selectionStart,
+ win.gURLBar.selectionEnd,
+ `${key}: Input selection should be empty`
+ );
+ Assert.equal(win.gURLBar.selectionStart, pos, `${key}: ${msg}`);
+}
+
+async function checkPopupOpens(key, win) {
+ // Store current selection and check it doesn't change.
+ let selectionStart = win.gURLBar.selectionStart;
+ let selectionEnd = win.gURLBar.selectionEnd;
+ await UrlbarTestUtils.promisePopupOpen(win, () => {
+ checkIfKeyStartsQuery(key, true, win);
+ });
+ Assert.equal(
+ UrlbarTestUtils.getSelectedRowIndex(win),
+ 0,
+ `${key}: Heuristic result should be selected`
+ );
+ Assert.equal(
+ win.gURLBar.selectionStart,
+ selectionStart,
+ `${key}: Input selection start should not change`
+ );
+ Assert.equal(
+ win.gURLBar.selectionEnd,
+ selectionEnd,
+ `${key}: Input selection end should not change`
+ );
+ await UrlbarTestUtils.promisePopupClose(win);
+}
+
+function checkIfKeyStartsQuery(key, shouldStartQuery, win) {
+ let queryStarted = false;
+ let queryListener = {
+ onQueryStarted() {
+ queryStarted = true;
+ },
+ };
+ win.gURLBar.controller.addQueryListener(queryListener);
+ EventUtils.synthesizeKey(key, {}, win);
+ win.gURLBar.eventBufferer.replayDeferredEvents(false);
+ win.gURLBar.controller.removeQueryListener(queryListener);
+ Assert.equal(
+ queryStarted,
+ shouldStartQuery,
+ `${key}: Should${shouldStartQuery ? "" : "n't"} have started a query`
+ );
+}
+
+async function flushScrollStyle() {
+ // Flush pending notifications for the style.
+ /* eslint-disable no-unused-expressions */
+ gURLBar.inputField.scrollLeft;
+ // Ensure to apply the style.
+ await new Promise(resolve =>
+ gURLBar.inputField.ownerGlobal.requestAnimationFrame(resolve)
+ );
+}