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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** BEGIN LICENSE BLOCK *****
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* Contributor(s):
* zmgmoz <zmgmoz@gmail.com>
*
* ***** END LICENSE BLOCK ***** */
// Test navigation of webconsole contents via ctrl-a, ctrl-e, ctrl-p, ctrl-n
// see https://bugzilla.mozilla.org/show_bug.cgi?id=804845
let jsterm, inputNode;
function test() {
addTab("data:text/html;charset=utf-8,Web Console test for bug 804845 and bug 619598");
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
openConsole(null, doTests);
}, true);
}
function doTests(HUD) {
jsterm = HUD.jsterm;
inputNode = jsterm.inputNode;
ok(!jsterm.inputNode.value, "inputNode.value is empty");
is(jsterm.inputNode.selectionStart, 0);
is(jsterm.inputNode.selectionEnd, 0);
testSingleLineInputNavNoHistory();
testMultiLineInputNavNoHistory();
testNavWithHistory();
jsterm = inputNode = null;
executeSoon(finishTest);
}
function testSingleLineInputNavNoHistory() {
// Single char input
EventUtils.synthesizeKey("1", {});
is(inputNode.selectionStart, 1, "caret location after single char input");
// nav to start/end with ctrl-a and ctrl-e;
EventUtils.synthesizeKey("a", { ctrlKey: true });
is(inputNode.selectionStart, 0, "caret location after single char input and ctrl-a");
EventUtils.synthesizeKey("e", { ctrlKey: true });
is(inputNode.selectionStart, 1, "caret location after single char input and ctrl-e");
// Second char input
EventUtils.synthesizeKey("2", {});
// nav to start/end with up/down keys; verify behaviour using ctrl-p/ctrl-n
EventUtils.synthesizeKey("VK_UP", {});
is(inputNode.selectionStart, 0, "caret location after two char input and VK_UP");
EventUtils.synthesizeKey("VK_DOWN", {});
is(inputNode.selectionStart, 2, "caret location after two char input and VK_DOWN");
EventUtils.synthesizeKey("a", { ctrlKey: true });
is(inputNode.selectionStart, 0, "move caret to beginning of 2 char input with ctrl-a");
EventUtils.synthesizeKey("a", { ctrlKey: true });
is(inputNode.selectionStart, 0, "no change of caret location on repeat ctrl-a");
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.selectionStart, 0, "no change of caret location on ctrl-p from beginning of line");
EventUtils.synthesizeKey("e", { ctrlKey: true });
is(inputNode.selectionStart, 2, "move caret to end of 2 char input with ctrl-e");
EventUtils.synthesizeKey("e", { ctrlKey: true });
is(inputNode.selectionStart, 2, "no change of caret location on repeat ctrl-e");
EventUtils.synthesizeKey("n", { ctrlKey: true });
is(inputNode.selectionStart, 2, "no change of caret location on ctrl-n from end of line");
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.selectionStart, 0, "ctrl-p moves to start of line");
EventUtils.synthesizeKey("n", { ctrlKey: true });
is(inputNode.selectionStart, 2, "ctrl-n moves to end of line");
}
function testMultiLineInputNavNoHistory() {
let lineValues = ["one", "2", "something longer", "", "", "three!"];
jsterm.setInputValue("");
// simulate shift-return
for (let i = 0; i < lineValues.length; i++) {
jsterm.setInputValue(inputNode.value + lineValues[i]);
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true });
}
let inputValue = inputNode.value;
is(inputNode.selectionStart, inputNode.selectionEnd);
is(inputNode.selectionStart, inputValue.length, "caret at end of multiline input");
// possibility newline is represented by one ('\r', '\n') or two ('\r\n') chars
let newlineString = inputValue.match(/(\r\n?|\n\r?)$/)[0];
// Ok, test navigating within the multi-line string!
EventUtils.synthesizeKey("VK_UP", {});
let expectedStringAfterCarat = lineValues[5]+newlineString;
is(inputNode.value.slice(inputNode.selectionStart), expectedStringAfterCarat,
"up arrow from end of multiline");
EventUtils.synthesizeKey("VK_DOWN", {});
is(inputNode.value.slice(inputNode.selectionStart), "",
"down arrow from within multiline");
// navigate up through input lines
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.value.slice(inputNode.selectionStart), expectedStringAfterCarat,
"ctrl-p from end of multiline");
for (let i = 4; i >= 0; i--) {
EventUtils.synthesizeKey("p", { ctrlKey: true });
expectedStringAfterCarat = lineValues[i] + newlineString + expectedStringAfterCarat;
is(inputNode.value.slice(inputNode.selectionStart), expectedStringAfterCarat,
"ctrl-p from within line " + i + " of multiline input");
}
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.selectionStart, 0, "reached start of input");
is(inputNode.value, inputValue,
"no change to multiline input on ctrl-p from beginning of multiline");
// navigate to end of first line
EventUtils.synthesizeKey("e", { ctrlKey: true });
let caretPos = inputNode.selectionStart;
let expectedStringBeforeCarat = lineValues[0];
is(inputNode.value.slice(0, caretPos), expectedStringBeforeCarat,
"ctrl-e into multiline input");
EventUtils.synthesizeKey("e", { ctrlKey: true });
is(inputNode.selectionStart, caretPos,
"repeat ctrl-e doesn't change caret position in multiline input");
// navigate down one line; ctrl-a to the beginning; ctrl-e to end
for (let i = 1; i < lineValues.length; i++) {
EventUtils.synthesizeKey("n", { ctrlKey: true });
EventUtils.synthesizeKey("a", { ctrlKey: true });
caretPos = inputNode.selectionStart;
expectedStringBeforeCarat += newlineString;
is(inputNode.value.slice(0, caretPos), expectedStringBeforeCarat,
"ctrl-a to beginning of line " + (i+1) + " in multiline input");
EventUtils.synthesizeKey("e", { ctrlKey: true });
caretPos = inputNode.selectionStart;
expectedStringBeforeCarat += lineValues[i];
is(inputNode.value.slice(0, caretPos), expectedStringBeforeCarat,
"ctrl-e to end of line " + (i+1) + "in multiline input");
}
}
function testNavWithHistory() {
// NOTE: Tests does NOT currently define behaviour for ctrl-p/ctrl-n with
// caret placed _within_ single line input
let values = ['"single line input"',
'"a longer single-line input to check caret repositioning"',
['"multi-line"', '"input"', '"here!"'].join("\n"),
];
// submit to history
for (let i = 0; i < values.length; i++) {
jsterm.setInputValue(values[i]);
jsterm.execute();
}
is(inputNode.selectionStart, 0, "caret location at start of empty line");
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.selectionStart, values[values.length-1].length,
"caret location correct at end of last history input");
// Navigate backwards history with ctrl-p
for (let i = values.length-1; i > 0; i--) {
let match = values[i].match(/(\n)/g);
if (match) {
// multi-line inputs won't update from history unless caret at beginning
EventUtils.synthesizeKey("a", { ctrlKey: true });
for (let i = 0; i < match.length; i++) {
EventUtils.synthesizeKey("p", { ctrlKey: true });
}
EventUtils.synthesizeKey("p", { ctrlKey: true });
} else {
// single-line inputs will update from history from end of line
EventUtils.synthesizeKey("p", { ctrlKey: true });
}
is(inputNode.value, values[i-1],
"ctrl-p updates inputNode from backwards history values[" + i-1 + "]");
}
let inputValue = inputNode.value;
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.selectionStart, 0,
"ctrl-p at beginning of history moves caret location to beginning of line");
is(inputNode.value, inputValue,
"no change to input value on ctrl-p from beginning of line");
// Navigate forwards history with ctrl-n
for (let i = 1; i<values.length; i++) {
EventUtils.synthesizeKey("n", { ctrlKey: true });
is(inputNode.value, values[i],
"ctrl-n updates inputNode from forwards history values[" + i + "]");
is(inputNode.selectionStart, values[i].length,
"caret location correct at end of history input for values[" + i + "]");
}
EventUtils.synthesizeKey("n", { ctrlKey: true });
ok(!inputNode.value, "ctrl-n at end of history updates to empty input");
// Simulate editing multi-line
inputValue = "one\nlinebreak";
jsterm.setInputValue(inputValue);
// Attempt nav within input
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.value, inputValue,
"ctrl-p from end of multi-line does not trigger history");
EventUtils.synthesizeKey("a", { ctrlKey: true });
EventUtils.synthesizeKey("p", { ctrlKey: true });
is(inputNode.value, values[values.length-1],
"ctrl-p from start of multi-line triggers history");
}
|