diff options
Diffstat (limited to 'devtools/client/webconsole/test/browser/browser_jsterm_completion_bracket.js')
-rw-r--r-- | devtools/client/webconsole/test/browser/browser_jsterm_completion_bracket.js | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_completion_bracket.js b/devtools/client/webconsole/test/browser/browser_jsterm_completion_bracket.js new file mode 100644 index 0000000000..7704230d6e --- /dev/null +++ b/devtools/client/webconsole/test/browser/browser_jsterm_completion_bracket.js @@ -0,0 +1,254 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that code completion works properly with `[` + +"use strict"; + +const TEST_URI = `data:text/html;charset=utf8,<!DOCTYPE html><p>test [ completion. + <script> + window.testObject = Object.create(null, Object.getOwnPropertyDescriptors({ + bar: 0, + dataTest: 1, + "data-test": 2, + 'da"ta"test': 3, + "da\`ta\`test": 4, + "da'ta'test": 5, + "DATA-TEST": 6, + "DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d\\ud83d\\ude80_TEST": 7, + })); + </script>`; + +add_task(async function () { + await pushPref("devtools.editor.autoclosebrackets", false); + const hud = await openNewTabAndConsole(TEST_URI); + await testInputs(hud, false); + await testCompletionTextUpdateOnPopupNavigate(hud, false); + await testAcceptCompletionExistingClosingBracket(hud); + + info("Test again with autoclosebracket set to true"); + await pushPref("devtools.editor.autoclosebrackets", true); + const hudAutoclose = await openNewTabAndConsole(TEST_URI); + await testInputs(hudAutoclose, true); + await testCompletionTextUpdateOnPopupNavigate(hudAutoclose, true); + await testAcceptCompletionExistingClosingBracket(hudAutoclose); +}); + +async function testInputs(hud, autocloseEnabled) { + const tests = [ + { + description: "Check that the popup is opened when typing `[`", + input: "window.testObject[", + expectedItems: [ + `"bar"`, + `"da'ta'test"`, + `"da\\"ta\\"test"`, + `"da\`ta\`test"`, + `"data-test"`, + `"dataTest"`, + `"DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST"`, + `"DATA-TEST"`, + ], + expectedCompletionText: autocloseEnabled ? "" : `"bar"]`, + expectedInputAfterCompletion: `window.testObject["bar"]`, + }, + { + description: "Test that the list can be filtered even without quote", + input: "window.testObject[d", + expectedItems: [ + `"da'ta'test"`, + `"da\\"ta\\"test"`, + `"da\`ta\`test"`, + `"data-test"`, + `"dataTest"`, + `"DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST"`, + `"DATA-TEST"`, + ], + expectedCompletionText: autocloseEnabled ? "" : `a'ta'test"]`, + expectedInputAfterCompletion: `window.testObject["da'ta'test"]`, + }, + { + description: "Test filtering with quote and string", + input: `window.testObject["d`, + expectedItems: [ + `"da'ta'test"`, + `"da\\"ta\\"test"`, + `"da\`ta\`test"`, + `"data-test"`, + `"dataTest"`, + `"DAT_\\\\a\\"'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST"`, + `"DATA-TEST"`, + ], + expectedCompletionText: autocloseEnabled ? "" : `a'ta'test"]`, + expectedInputAfterCompletion: `window.testObject["da'ta'test"]`, + }, + { + description: "Test filtering with simple quote and string", + input: `window.testObject['d`, + expectedItems: [ + `'da"ta"test'`, + `'da\\'ta\\'test'`, + `'da\`ta\`test'`, + `'data-test'`, + `'dataTest'`, + `'DAT_\\\\a"\\'\`\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST'`, + `'DATA-TEST'`, + ], + expectedCompletionText: autocloseEnabled ? "" : `a"ta"test']`, + expectedInputAfterCompletion: `window.testObject['da"ta"test']`, + }, + { + description: "Test filtering with template literal and string", + input: "window.testObject[`d", + expectedItems: [ + "`da'ta'test`", + '`da"ta"test`', + "`da\\`ta\\`test`", + "`data-test`", + "`dataTest`", + "`DAT_\\\\a\"'\\`\\${0}\\u0000\\b\\t\\n\\f\\r\\ude80\\ud83d🚀_TEST`", + "`DATA-TEST`", + ], + expectedCompletionText: autocloseEnabled ? "" : "a'ta'test`]", + expectedInputAfterCompletion: "window.testObject[`da'ta'test`]", + }, + { + description: "Test that filtering is case insensitive", + input: "window.testObject[data-t", + expectedItems: [`"data-test"`, `"DATA-TEST"`], + expectedCompletionText: autocloseEnabled ? "" : `est"]`, + expectedInputAfterCompletion: `window.testObject["data-test"]`, + }, + { + description: + "Test that filtering without quote displays the popup when there's only 1 match", + input: "window.testObject[DATA-", + expectedItems: [`"DATA-TEST"`], + expectedCompletionText: autocloseEnabled ? "" : `TEST"]`, + expectedInputAfterCompletion: `window.testObject["DATA-TEST"]`, + }, + ]; + + for (const test of tests) { + await testInput(hud, test); + } +} + +async function testInput( + hud, + { + description, + input, + expectedItems, + expectedCompletionText, + expectedInputAfterCompletion, + } +) { + const { jsterm } = hud; + const { autocompletePopup } = jsterm; + + info(`${description} - test popup opening`); + const onPopUpOpen = autocompletePopup.once("popup-opened"); + EventUtils.sendString(input); + await onPopUpOpen; + + ok( + hasExactPopupLabels(autocompletePopup, expectedItems), + `${description} - popup has expected item, in expected order` + ); + checkInputCompletionValue( + hud, + expectedCompletionText, + `${description} - completeNode has expected value` + ); + + info(`${description} - test accepting completion`); + const onPopupClose = autocompletePopup.once("popup-closed"); + EventUtils.synthesizeKey("KEY_Tab"); + await onPopupClose; + checkInputValueAndCursorPosition( + hud, + expectedInputAfterCompletion + "|", + `${description} - input was completed as expected` + ); + checkInputCompletionValue(hud, "", `${description} - completeNode is empty`); + + setInputValue(hud, ""); +} + +async function testCompletionTextUpdateOnPopupNavigate(hud, autocloseEnabled) { + const { jsterm } = hud; + const { autocompletePopup } = jsterm; + + info( + "Test that navigating the popup list update the completionText as expected" + ); + const onPopUpOpen = autocompletePopup.once("popup-opened"); + const input = `window.testObject[data`; + EventUtils.sendString(input); + await onPopUpOpen; + + ok( + hasExactPopupLabels(autocompletePopup, [ + `"data-test"`, + `"dataTest"`, + `"DATA-TEST"`, + ]), + `popup has expected items, in expected order` + ); + checkInputCompletionValue( + hud, + autocloseEnabled ? "" : `-test"]`, + `completeNode has expected value` + ); + + EventUtils.synthesizeKey("KEY_ArrowDown"); + checkInputCompletionValue( + hud, + autocloseEnabled ? "" : `Test"]`, + `completeNode has expected value` + ); + + EventUtils.synthesizeKey("KEY_ArrowDown"); + checkInputCompletionValue( + hud, + autocloseEnabled ? "" : `-TEST"]`, + `completeNode has expected value` + ); + + const onPopupClose = autocompletePopup.once("popup-closed"); + EventUtils.synthesizeKey("KEY_Tab"); + await onPopupClose; + checkInputValueAndCursorPosition( + hud, + `window.testObject["DATA-TEST"]|`, + `input was completed as expected after navigating the popup` + ); +} + +async function testAcceptCompletionExistingClosingBracket(hud) { + const { jsterm } = hud; + const { autocompletePopup } = jsterm; + + info( + "Check that accepting completion when there's a closing bracket does not append " + + "another closing bracket" + ); + await setInputValueForAutocompletion(hud, "window.testObject[]", -1); + const onPopUpOpen = autocompletePopup.once("popup-opened"); + EventUtils.sendString(`"b`); + await onPopUpOpen; + ok( + hasExactPopupLabels(autocompletePopup, [`"bar"`]), + `popup has expected item` + ); + + const onPopupClose = autocompletePopup.once("popup-closed"); + EventUtils.synthesizeKey("KEY_Tab"); + await onPopupClose; + checkInputValueAndCursorPosition( + hud, + `window.testObject["bar"]|`, + `input was completed as expected, without adding a closing bracket` + ); +} |