1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,341 @@ 1.4 +/* vim:set ts=2 sw=2 sts=2 et: */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +const TEST_URI = "data:text/html;charset=utf-8,<p>bug 585991 - autocomplete popup keyboard usage test"; 1.10 +let HUD, popup, jsterm, inputNode, completeNode; 1.11 + 1.12 +function test() { 1.13 + addTab(TEST_URI); 1.14 + browser.addEventListener("load", function onLoad() { 1.15 + browser.removeEventListener("load", onLoad, true); 1.16 + openConsole(null, consoleOpened); 1.17 + }, true); 1.18 +} 1.19 + 1.20 +function consoleOpened(aHud) { 1.21 + HUD = aHud; 1.22 + info("web console opened"); 1.23 + 1.24 + jsterm = HUD.jsterm; 1.25 + 1.26 + jsterm.execute("window.foobarBug585991={" + 1.27 + "'item0': 'value0'," + 1.28 + "'item1': 'value1'," + 1.29 + "'item2': 'value2'," + 1.30 + "'item3': 'value3'" + 1.31 + "}"); 1.32 + popup = jsterm.autocompletePopup; 1.33 + completeNode = jsterm.completeNode; 1.34 + inputNode = jsterm.inputNode; 1.35 + 1.36 + ok(!popup.isOpen, "popup is not open"); 1.37 + 1.38 + popup._panel.addEventListener("popupshown", function onShown() { 1.39 + popup._panel.removeEventListener("popupshown", onShown, false); 1.40 + 1.41 + ok(popup.isOpen, "popup is open"); 1.42 + 1.43 + // 4 values, and the following properties: 1.44 + // __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__ 1.45 + // hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString 1.46 + // toSource unwatch valueOf watch constructor. 1.47 + is(popup.itemCount, 18, "popup.itemCount is correct"); 1.48 + 1.49 + let sameItems = popup.getItems().reverse().map(function(e) {return e.label;}); 1.50 + ok(sameItems.every(function(prop, index) { 1.51 + return [ 1.52 + "__defineGetter__", 1.53 + "__defineSetter__", 1.54 + "__lookupGetter__", 1.55 + "__lookupSetter__", 1.56 + "constructor", 1.57 + "hasOwnProperty", 1.58 + "isPrototypeOf", 1.59 + "item0", 1.60 + "item1", 1.61 + "item2", 1.62 + "item3", 1.63 + "propertyIsEnumerable", 1.64 + "toLocaleString", 1.65 + "toSource", 1.66 + "toString", 1.67 + "unwatch", 1.68 + "valueOf", 1.69 + "watch", 1.70 + ][index] === prop}), "getItems returns the items we expect"); 1.71 + 1.72 + is(popup.selectedIndex, 17, 1.73 + "Index of the first item from bottom is selected."); 1.74 + EventUtils.synthesizeKey("VK_DOWN", {}); 1.75 + 1.76 + let prefix = jsterm.inputNode.value.replace(/[\S]/g, " "); 1.77 + 1.78 + is(popup.selectedIndex, 0, "index 0 is selected"); 1.79 + is(popup.selectedItem.label, "watch", "watch is selected"); 1.80 + is(completeNode.value, prefix + "watch", 1.81 + "completeNode.value holds watch"); 1.82 + 1.83 + EventUtils.synthesizeKey("VK_DOWN", {}); 1.84 + 1.85 + is(popup.selectedIndex, 1, "index 1 is selected"); 1.86 + is(popup.selectedItem.label, "valueOf", "valueOf is selected"); 1.87 + is(completeNode.value, prefix + "valueOf", 1.88 + "completeNode.value holds valueOf"); 1.89 + 1.90 + EventUtils.synthesizeKey("VK_UP", {}); 1.91 + 1.92 + is(popup.selectedIndex, 0, "index 0 is selected"); 1.93 + is(popup.selectedItem.label, "watch", "watch is selected"); 1.94 + is(completeNode.value, prefix + "watch", 1.95 + "completeNode.value holds watch"); 1.96 + 1.97 + let currentSelectionIndex = popup.selectedIndex; 1.98 + 1.99 + EventUtils.synthesizeKey("VK_PAGE_DOWN", {}); 1.100 + 1.101 + ok(popup.selectedIndex > currentSelectionIndex, 1.102 + "Index is greater after PGDN"); 1.103 + 1.104 + currentSelectionIndex = popup.selectedIndex; 1.105 + EventUtils.synthesizeKey("VK_PAGE_UP", {}); 1.106 + 1.107 + ok(popup.selectedIndex < currentSelectionIndex, "Index is less after Page UP"); 1.108 + 1.109 + info("press Tab and wait for popup to hide"); 1.110 + popup._panel.addEventListener("popuphidden", popupHideAfterTab, false); 1.111 + EventUtils.synthesizeKey("VK_TAB", {}); 1.112 + }, false); 1.113 + 1.114 + info("wait for completion: window.foobarBug585991."); 1.115 + jsterm.setInputValue("window.foobarBug585991"); 1.116 + EventUtils.synthesizeKey(".", {}); 1.117 +} 1.118 + 1.119 +function popupHideAfterTab() 1.120 +{ 1.121 + // At this point the completion suggestion should be accepted. 1.122 + popup._panel.removeEventListener("popuphidden", popupHideAfterTab, false); 1.123 + 1.124 + ok(!popup.isOpen, "popup is not open"); 1.125 + 1.126 + is(inputNode.value, "window.foobarBug585991.watch", 1.127 + "completion was successful after VK_TAB"); 1.128 + 1.129 + ok(!completeNode.value, "completeNode is empty"); 1.130 + 1.131 + popup._panel.addEventListener("popupshown", function onShown() { 1.132 + popup._panel.removeEventListener("popupshown", onShown, false); 1.133 + 1.134 + ok(popup.isOpen, "popup is open"); 1.135 + 1.136 + is(popup.itemCount, 18, "popup.itemCount is correct"); 1.137 + 1.138 + is(popup.selectedIndex, 17, "First index from bottom is selected"); 1.139 + EventUtils.synthesizeKey("VK_DOWN", {}); 1.140 + 1.141 + let prefix = jsterm.inputNode.value.replace(/[\S]/g, " "); 1.142 + 1.143 + is(popup.selectedIndex, 0, "index 0 is selected"); 1.144 + is(popup.selectedItem.label, "watch", "watch is selected"); 1.145 + is(completeNode.value, prefix + "watch", 1.146 + "completeNode.value holds watch"); 1.147 + 1.148 + popup._panel.addEventListener("popuphidden", function onHidden() { 1.149 + popup._panel.removeEventListener("popuphidden", onHidden, false); 1.150 + 1.151 + ok(!popup.isOpen, "popup is not open after VK_ESCAPE"); 1.152 + 1.153 + is(inputNode.value, "window.foobarBug585991.", 1.154 + "completion was cancelled"); 1.155 + 1.156 + ok(!completeNode.value, "completeNode is empty"); 1.157 + 1.158 + executeSoon(testReturnKey); 1.159 + }, false); 1.160 + 1.161 + info("press Escape to close the popup"); 1.162 + executeSoon(function() { 1.163 + EventUtils.synthesizeKey("VK_ESCAPE", {}); 1.164 + }); 1.165 + }, false); 1.166 + 1.167 + info("wait for completion: window.foobarBug585991."); 1.168 + executeSoon(function() { 1.169 + jsterm.setInputValue("window.foobarBug585991"); 1.170 + EventUtils.synthesizeKey(".", {}); 1.171 + }); 1.172 +} 1.173 + 1.174 +function testReturnKey() 1.175 +{ 1.176 + popup._panel.addEventListener("popupshown", function onShown() { 1.177 + popup._panel.removeEventListener("popupshown", onShown, false); 1.178 + 1.179 + ok(popup.isOpen, "popup is open"); 1.180 + 1.181 + is(popup.itemCount, 18, "popup.itemCount is correct"); 1.182 + 1.183 + is(popup.selectedIndex, 17, "First index from bottom is selected"); 1.184 + EventUtils.synthesizeKey("VK_DOWN", {}); 1.185 + 1.186 + let prefix = jsterm.inputNode.value.replace(/[\S]/g, " "); 1.187 + 1.188 + is(popup.selectedIndex, 0, "index 0 is selected"); 1.189 + is(popup.selectedItem.label, "watch", "watch is selected"); 1.190 + is(completeNode.value, prefix + "watch", 1.191 + "completeNode.value holds watch"); 1.192 + 1.193 + EventUtils.synthesizeKey("VK_DOWN", {}); 1.194 + 1.195 + is(popup.selectedIndex, 1, "index 1 is selected"); 1.196 + is(popup.selectedItem.label, "valueOf", "valueOf is selected"); 1.197 + is(completeNode.value, prefix + "valueOf", 1.198 + "completeNode.value holds valueOf"); 1.199 + 1.200 + popup._panel.addEventListener("popuphidden", function onHidden() { 1.201 + popup._panel.removeEventListener("popuphidden", onHidden, false); 1.202 + 1.203 + ok(!popup.isOpen, "popup is not open after VK_RETURN"); 1.204 + 1.205 + is(inputNode.value, "window.foobarBug585991.valueOf", 1.206 + "completion was successful after VK_RETURN"); 1.207 + 1.208 + ok(!completeNode.value, "completeNode is empty"); 1.209 + 1.210 + dontShowArrayNumbers(); 1.211 + }, false); 1.212 + 1.213 + info("press Return to accept suggestion. wait for popup to hide"); 1.214 + 1.215 + executeSoon(() => EventUtils.synthesizeKey("VK_RETURN", {})); 1.216 + }, false); 1.217 + 1.218 + info("wait for completion suggestions: window.foobarBug585991."); 1.219 + 1.220 + executeSoon(function() { 1.221 + jsterm.setInputValue("window.foobarBug58599"); 1.222 + EventUtils.synthesizeKey("1", {}); 1.223 + EventUtils.synthesizeKey(".", {}); 1.224 + }); 1.225 +} 1.226 + 1.227 +function dontShowArrayNumbers() 1.228 +{ 1.229 + info("dontShowArrayNumbers"); 1.230 + content.wrappedJSObject.foobarBug585991 = ["Sherlock Holmes"]; 1.231 + 1.232 + let jsterm = HUD.jsterm; 1.233 + let popup = jsterm.autocompletePopup; 1.234 + let completeNode = jsterm.completeNode; 1.235 + 1.236 + popup._panel.addEventListener("popupshown", function onShown() { 1.237 + popup._panel.removeEventListener("popupshown", onShown, false); 1.238 + 1.239 + let sameItems = popup.getItems().map(function(e) {return e.label;}); 1.240 + ok(!sameItems.some(function(prop, index) { prop === "0"; }), 1.241 + "Completing on an array doesn't show numbers."); 1.242 + 1.243 + popup._panel.addEventListener("popuphidden", testReturnWithNoSelection, false); 1.244 + 1.245 + info("wait for popup to hide"); 1.246 + executeSoon(() => EventUtils.synthesizeKey("VK_ESCAPE", {})); 1.247 + }, false); 1.248 + 1.249 + info("wait for popup to show"); 1.250 + executeSoon(() => { 1.251 + jsterm.setInputValue("window.foobarBug585991"); 1.252 + EventUtils.synthesizeKey(".", {}); 1.253 + }); 1.254 +} 1.255 + 1.256 +function testReturnWithNoSelection() 1.257 +{ 1.258 + popup._panel.removeEventListener("popuphidden", testReturnWithNoSelection, false); 1.259 + 1.260 + info("test pressing return with open popup, but no selection, see bug 873250"); 1.261 + content.wrappedJSObject.testBug873250a = "hello world"; 1.262 + content.wrappedJSObject.testBug873250b = "hello world 2"; 1.263 + 1.264 + popup._panel.addEventListener("popupshown", function onShown() { 1.265 + popup._panel.removeEventListener("popupshown", onShown); 1.266 + 1.267 + ok(popup.isOpen, "popup is open"); 1.268 + is(popup.itemCount, 2, "popup.itemCount is correct"); 1.269 + isnot(popup.selectedIndex, -1, "popup.selectedIndex is correct"); 1.270 + 1.271 + info("press Return and wait for popup to hide"); 1.272 + popup._panel.addEventListener("popuphidden", popupHideAfterReturnWithNoSelection); 1.273 + executeSoon(() => EventUtils.synthesizeKey("VK_RETURN", {})); 1.274 + }); 1.275 + 1.276 + executeSoon(() => { 1.277 + info("wait for popup to show"); 1.278 + jsterm.setInputValue("window.testBu"); 1.279 + EventUtils.synthesizeKey("g", {}); 1.280 + }); 1.281 +} 1.282 + 1.283 +function popupHideAfterReturnWithNoSelection() 1.284 +{ 1.285 + popup._panel.removeEventListener("popuphidden", popupHideAfterReturnWithNoSelection); 1.286 + 1.287 + ok(!popup.isOpen, "popup is not open after VK_RETURN"); 1.288 + 1.289 + is(inputNode.value, "", "inputNode is empty after VK_RETURN"); 1.290 + is(completeNode.value, "", "completeNode is empty"); 1.291 + is(jsterm.history[jsterm.history.length-1], "window.testBug", 1.292 + "jsterm history is correct"); 1.293 + 1.294 + executeSoon(testCompletionInText); 1.295 +} 1.296 + 1.297 +function testCompletionInText() 1.298 +{ 1.299 + info("test that completion works inside text, see bug 812618"); 1.300 + 1.301 + popup._panel.addEventListener("popupshown", function onShown() { 1.302 + popup._panel.removeEventListener("popupshown", onShown); 1.303 + 1.304 + ok(popup.isOpen, "popup is open"); 1.305 + is(popup.itemCount, 2, "popup.itemCount is correct"); 1.306 + 1.307 + EventUtils.synthesizeKey("VK_DOWN", {}); 1.308 + is(popup.selectedIndex, 0, "popup.selectedIndex is correct"); 1.309 + ok(!completeNode.value, "completeNode.value is empty"); 1.310 + 1.311 + let items = popup.getItems().reverse().map(e => e.label); 1.312 + let sameItems = items.every((prop, index) => 1.313 + ["testBug873250a", "testBug873250b"][index] === prop); 1.314 + ok(sameItems, "getItems returns the items we expect"); 1.315 + 1.316 + info("press Tab and wait for popup to hide"); 1.317 + popup._panel.addEventListener("popuphidden", popupHideAfterCompletionInText); 1.318 + EventUtils.synthesizeKey("VK_TAB", {}); 1.319 + }); 1.320 + 1.321 + jsterm.setInputValue("dump(window.testBu)"); 1.322 + inputNode.selectionStart = inputNode.selectionEnd = 18; 1.323 + EventUtils.synthesizeKey("g", {}); 1.324 +} 1.325 + 1.326 +function popupHideAfterCompletionInText() 1.327 +{ 1.328 + // At this point the completion suggestion should be accepted. 1.329 + popup._panel.removeEventListener("popuphidden", popupHideAfterCompletionInText); 1.330 + 1.331 + ok(!popup.isOpen, "popup is not open"); 1.332 + is(inputNode.value, "dump(window.testBug873250b)", 1.333 + "completion was successful after VK_TAB"); 1.334 + is(inputNode.selectionStart, 26, "cursor location is correct"); 1.335 + is(inputNode.selectionStart, inputNode.selectionEnd, "cursor location (confirmed)"); 1.336 + ok(!completeNode.value, "completeNode is empty"); 1.337 + 1.338 + finishUp(); 1.339 +} 1.340 + 1.341 +function finishUp() { 1.342 + HUD = popup = jsterm = inputNode = completeNode = null; 1.343 + finishTest(); 1.344 +}