diff options
Diffstat (limited to 'devtools/client/webconsole/test/browser/browser_jsterm_ctrl_key_nav.js')
-rw-r--r-- | devtools/client/webconsole/test/browser/browser_jsterm_ctrl_key_nav.js | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_ctrl_key_nav.js b/devtools/client/webconsole/test/browser/browser_jsterm_ctrl_key_nav.js new file mode 100644 index 0000000000..5db3e2a68f --- /dev/null +++ b/devtools/client/webconsole/test/browser/browser_jsterm_ctrl_key_nav.js @@ -0,0 +1,335 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test navigation of webconsole contents via ctrl-a, ctrl-e, ctrl-p, ctrl-n +// see https://bugzilla.mozilla.org/show_bug.cgi?id=804845 +// +// The shortcuts tested here have platform limitations: +// - ctrl-e does not work on windows, +// - ctrl-a, ctrl-p and ctrl-n only work on OSX +"use strict"; + +const TEST_URI = + "data:text/html;charset=utf-8,<!DOCTYPE html>Web Console test for " + + "bug 804845 and bug 619598"; + +add_task(async function () { + const hud = await openNewTabAndConsole(TEST_URI); + + ok(!getInputValue(hud), "input is empty"); + checkInputCursorPosition(hud, 0, "Cursor is at the start of the input"); + + testSingleLineInputNavNoHistory(hud); + testMultiLineInputNavNoHistory(hud); + await testNavWithHistory(hud); +}); + +function testSingleLineInputNavNoHistory(hud) { + const checkInput = (expected, assertionInfo) => + checkInputValueAndCursorPosition(hud, expected, assertionInfo); + + // Single char input + EventUtils.sendString("1"); + checkInput("1|", "caret location after single char input"); + + // nav to start/end with ctrl-a and ctrl-e; + synthesizeLineStartKey(); + checkInput("|1", "caret location after single char input and ctrl-a"); + + synthesizeLineEndKey(); + checkInput("1|", "caret location after single char input and ctrl-e"); + + // Second char input + EventUtils.sendString("2"); + checkInput("12|", "caret location after second char input"); + + // nav to start/end with up/down keys; verify behaviour using ctrl-p/ctrl-n + EventUtils.synthesizeKey("KEY_ArrowUp"); + checkInput("|12", "caret location after two char input and KEY_ArrowUp"); + + EventUtils.synthesizeKey("KEY_ArrowDown"); + checkInput("12|", "caret location after two char input and KEY_ArrowDown"); + + synthesizeLineStartKey(); + checkInput("|12", "move caret to beginning of 2 char input with ctrl-a"); + + synthesizeLineStartKey(); + checkInput("|12", "no change of caret location on repeat ctrl-a"); + + synthesizeLineUpKey(); + checkInput( + "|12", + "no change of caret location on ctrl-p from beginning of line" + ); + + synthesizeLineEndKey(); + checkInput("12|", "move caret to end of 2 char input with ctrl-e"); + + synthesizeLineEndKey(); + checkInput("12|", "no change of caret location on repeat ctrl-e"); + + synthesizeLineDownKey(); + checkInput("12|", "no change of caret location on ctrl-n from end of line"); + + synthesizeLineUpKey(); + checkInput("|12", "ctrl-p moves to start of line"); + + synthesizeLineDownKey(); + checkInput("12|", "ctrl-n moves to end of line"); +} + +function testMultiLineInputNavNoHistory(hud) { + const checkInput = (expected, assertionInfo) => + checkInputValueAndCursorPosition(hud, expected, assertionInfo); + + const lineValues = ["one", "2", "something longer", "", "", "three!"]; + setInputValue(hud, ""); + // simulate shift-return + for (const lineValue of lineValues) { + setInputValue(hud, getInputValue(hud) + lineValue); + EventUtils.synthesizeKey("KEY_Enter", { shiftKey: true }); + } + + checkInput( + `one +2 +something longer + + +three! +|`, + "caret at end of multiline input" + ); + + // Ok, test navigating within the multi-line string! + EventUtils.synthesizeKey("KEY_ArrowUp"); + checkInput( + `one +2 +something longer + + +|three! +`, + "up arrow from end of multiline" + ); + + EventUtils.synthesizeKey("KEY_ArrowDown"); + checkInput( + `one +2 +something longer + + +three! +|`, + "down arrow from within multiline" + ); + + // navigate up through input lines + synthesizeLineUpKey(); + checkInput( + `one +2 +something longer + + +|three! +`, + "ctrl-p from end of multiline" + ); + + for (let i = 0; i < 5; i++) { + synthesizeLineUpKey(); + } + + checkInput( + `|one +2 +something longer + + +three! +`, + "reached start of input" + ); + + synthesizeLineUpKey(); + checkInput( + `|one +2 +something longer + + +three! +`, + "no change to multiline input on ctrl-p from beginning of multiline" + ); + + // navigate to end of first line + synthesizeLineEndKey(); + checkInput( + `one| +2 +something longer + + +three! +`, + "ctrl-e into multiline input" + ); + + synthesizeLineEndKey(); + checkInput( + `one| +2 +something longer + + +three! +`, + "repeat ctrl-e doesn't change caret position in multiline input" + ); + + synthesizeLineDownKey(); + synthesizeLineStartKey(); + checkInput( + `one +|2 +something longer + + +three! +` + ); + + synthesizeLineEndKey(); + synthesizeLineDownKey(); + synthesizeLineStartKey(); + checkInput( + `one +2 +|something longer + + +three! +` + ); +} + +async function testNavWithHistory(hud) { + const checkInput = (expected, assertionInfo) => + checkInputValueAndCursorPosition(hud, expected, assertionInfo); + + // NOTE: Tests does NOT currently define behaviour for ctrl-p/ctrl-n with + // caret placed _within_ single line input + const values = [ + "single line input", + "a longer single-line input to check caret repositioning", + "multi-line\ninput\nhere", + ]; + + // submit to history + for (const value of values) { + const onResult = waitForMessageByType(hud, "", ".result"); + setInputValue(hud, value); + EventUtils.synthesizeKey("KEY_Enter"); + await onResult; + } + + checkInput("|", "caret location at start of empty line"); + + synthesizeLineUpKey(); + checkInput( + "multi-line\ninput\nhere|", + "caret location at end of last history input" + ); + + synthesizeLineStartKey(); + checkInput( + "multi-line\ninput\n|here", + "caret location at beginning of last line of last history input" + ); + + synthesizeLineUpKey(); + checkInput( + "multi-line\n|input\nhere", + "caret location at beginning of second line of last history input" + ); + + synthesizeLineUpKey(); + checkInput( + "|multi-line\ninput\nhere", + "caret location at beginning of first line of last history input" + ); + + synthesizeLineUpKey(); + checkInput( + "a longer single-line input to check caret repositioning|", + "caret location at the end of second history input" + ); + + synthesizeLineUpKey(); + checkInput( + "single line input|", + "caret location at the end of first history input" + ); + + synthesizeLineUpKey(); + checkInput( + "|single line input", + "ctrl-p at beginning of history moves caret location to beginning of line" + ); + + synthesizeLineDownKey(); + checkInput( + "a longer single-line input to check caret repositioning|", + "caret location at the end of second history input" + ); + + synthesizeLineDownKey(); + checkInput( + "multi-line\ninput\nhere|", + "caret location at end of last history input" + ); + + synthesizeLineDownKey(); + checkInput("|", "ctrl-n at end of history updates to empty input"); + + // Simulate editing multi-line + const inputValue = "one\nlinebreak"; + setInputValue(hud, inputValue); + checkInput("one\nlinebreak|"); + + // Attempt nav within input + synthesizeLineUpKey(); + checkInput( + "one|\nlinebreak", + "ctrl-p from end of multi-line does not trigger history" + ); + + synthesizeLineStartKey(); + checkInput("|one\nlinebreak"); + + synthesizeLineUpKey(); + checkInput( + "multi-line\ninput\nhere|", + "ctrl-p from start of multi-line triggers history" + ); +} + +function synthesizeLineStartKey() { + EventUtils.synthesizeKey("a", { ctrlKey: true }); +} + +function synthesizeLineEndKey() { + EventUtils.synthesizeKey("e", { ctrlKey: true }); +} + +function synthesizeLineUpKey() { + EventUtils.synthesizeKey("p", { ctrlKey: true }); +} + +function synthesizeLineDownKey() { + EventUtils.synthesizeKey("n", { ctrlKey: true }); +} |