1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/forms/test/test_bug935876.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,491 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=935876 1.8 +--> 1.9 +<head> 1.10 + <meta charset="utf-8"> 1.11 + <title>Test for Bug 935876</title> 1.12 + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.13 + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> 1.14 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 1.15 +</head> 1.16 +<body> 1.17 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=935876">Mozilla Bug 935876</a> 1.18 +<p id="display"></p> 1.19 +<div> 1.20 +<select id="listbox" size="3"> 1.21 + <option selected>1</option> 1.22 + <option>2</option> 1.23 + <option>3</option> 1.24 + <option>4</option> 1.25 + <option>5</option> 1.26 + <option>6</option> 1.27 + <option>7</option> 1.28 +</select> 1.29 +<select id="multipleListbox" size="3" multiple> 1.30 + <option selected>1</option> 1.31 + <option>2</option> 1.32 + <option>3</option> 1.33 + <option>4</option> 1.34 + <option>5</option> 1.35 + <option>6</option> 1.36 + <option>7</option> 1.37 +</select> 1.38 +<select id="combobox"> 1.39 + <option selected>1</option> 1.40 + <option>2</option> 1.41 + <option>3</option> 1.42 + <option>4</option> 1.43 + <option>5</option> 1.44 + <option>6</option> 1.45 + <option>7</option> 1.46 +</select> 1.47 +</div> 1.48 +<pre id="test"> 1.49 +</pre> 1.50 +<script type="application/javascript"> 1.51 +SimpleTest.waitForExplicitFinish(); 1.52 + 1.53 +const kIsWin = navigator.platform.indexOf("Win") == 0; 1.54 +const kIsMac = navigator.platform.indexOf("Mac") == 0; 1.55 +const kIsAndroid = navigator.appVersion.indexOf("Android") != 0; 1.56 + 1.57 +function runTests() 1.58 +{ 1.59 + var doPreventDefault = false; 1.60 + function onKeydown(aEvent) 1.61 + { 1.62 + if (doPreventDefault) { 1.63 + aEvent.preventDefault(); 1.64 + } 1.65 + } 1.66 + 1.67 + var keyPressEventFired = false; 1.68 + function onKeypress(aEvent) 1.69 + { 1.70 + keyPressEventFired = true; 1.71 + } 1.72 + 1.73 + var keyDownEventConsumedByJS = false; 1.74 + var keyDownEventConsumed = false; 1.75 + function onkeydownInSystemEventGroup(aEvent) 1.76 + { 1.77 + keyDownEventConsumedByJS = aEvent.defaultPrevented; 1.78 + keyDownEventConsumed = aEvent.getPreventDefault(); 1.79 + } 1.80 + 1.81 + function reset() 1.82 + { 1.83 + keyPressEventFired = false; 1.84 + keyDownEventConsumedByJS = false; 1.85 + keyDownEventConsumed = false; 1.86 + } 1.87 + 1.88 + function check(aExpectingKeydownConsumed, aDescription) 1.89 + { 1.90 + if (doPreventDefault) { 1.91 + ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription + 1.92 + " if preventDefault() of keydown event was called"); 1.93 + ok(keyDownEventConsumedByJS, "keydown event of " + aDescription + 1.94 + " should be consumed in content level if preventDefault() of keydown event is called"); 1.95 + ok(keyDownEventConsumed, "keydown event of " + aDescription + 1.96 + " should be consumed in system level if preventDefault() of keydown event is called"); 1.97 + } else if (aExpectingKeydownConsumed) { 1.98 + ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription); 1.99 + ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level"); 1.100 + ok(keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level"); 1.101 + } else { 1.102 + ok(keyPressEventFired, "keypress event should be fired for " + aDescription); 1.103 + ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level"); 1.104 + ok(!keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level"); 1.105 + } 1.106 + } 1.107 + 1.108 + var listbox = document.getElementById("listbox"); 1.109 + listbox.addEventListener("keydown", onKeydown, false); 1.110 + listbox.addEventListener("keypress", onKeypress, false); 1.111 + SpecialPowers.addSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false); 1.112 + 1.113 + listbox.focus(); 1.114 + 1.115 + [ false, true ].forEach(function (consume) { 1.116 + doPreventDefault = consume; 1.117 + for (var i = 0; i < listbox.options.length + 1; i++) { 1.118 + reset() 1.119 + synthesizeKey("VK_DOWN", {}); 1.120 + check(true, "DownArrow key on listbox #" + i); 1.121 + } 1.122 + 1.123 + for (var i = 0; i < listbox.options.length + 1; i++) { 1.124 + reset() 1.125 + synthesizeKey("VK_UP", {}); 1.126 + check(true, "UpArrow key on listbox #" + i); 1.127 + } 1.128 + 1.129 + for (var i = 0; i < listbox.options.length + 1; i++) { 1.130 + reset() 1.131 + synthesizeKey("VK_RIGHT", {}); 1.132 + check(true, "RightArrow key on listbox #" + i); 1.133 + } 1.134 + 1.135 + for (var i = 0; i < listbox.options.length + 1; i++) { 1.136 + reset() 1.137 + synthesizeKey("VK_LEFT", {}); 1.138 + check(true, "LeftArrow key on listbox #" + i); 1.139 + } 1.140 + 1.141 + for (var i = 0; i < 4; i++) { 1.142 + reset() 1.143 + synthesizeKey("VK_PAGE_DOWN", {}); 1.144 + check(true, "PageDown key on listbox #" + i); 1.145 + } 1.146 + 1.147 + for (var i = 0; i < 4; i++) { 1.148 + reset() 1.149 + synthesizeKey("VK_PAGE_UP", {}); 1.150 + check(true, "PageUp key on listbox #" + i); 1.151 + } 1.152 + 1.153 + for (var i = 0; i < 2; i++) { 1.154 + reset() 1.155 + synthesizeKey("VK_END", {}); 1.156 + check(true, "End key on listbox #" + i); 1.157 + } 1.158 + 1.159 + for (var i = 0; i < 2; i++) { 1.160 + reset() 1.161 + synthesizeKey("VK_HOME", {}); 1.162 + check(true, "Home key on listbox #" + i); 1.163 + } 1.164 + 1.165 + reset() 1.166 + synthesizeKey("VK_RETURN", {}); 1.167 + check(false, "Enter key on listbox"); 1.168 + 1.169 + reset() 1.170 + synthesizeKey("VK_ESCAPE", {}); 1.171 + check(false, "Esc key on listbox"); 1.172 + 1.173 + reset() 1.174 + synthesizeKey("VK_F4", {}); 1.175 + check(false, "F4 key on listbox"); 1.176 + 1.177 + reset() 1.178 + synthesizeKey("a", {}); 1.179 + check(false, "'A' key on listbox"); 1.180 + }); 1.181 + 1.182 + listbox.removeEventListener("keydown", onKeydown, false); 1.183 + listbox.removeEventListener("keypress", onKeypress, false); 1.184 + SpecialPowers.removeSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false); 1.185 + 1.186 + 1.187 + 1.188 + var multipleListbox = document.getElementById("multipleListbox"); 1.189 + multipleListbox.addEventListener("keydown", onKeydown, false); 1.190 + multipleListbox.addEventListener("keypress", onKeypress, false); 1.191 + SpecialPowers.addSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false); 1.192 + 1.193 + multipleListbox.focus(); 1.194 + 1.195 + [ false, true ].forEach(function (consume) { 1.196 + doPreventDefault = consume; 1.197 + for (var i = 0; i < multipleListbox.options.length + 1; i++) { 1.198 + reset() 1.199 + synthesizeKey("VK_DOWN", {}); 1.200 + check(true, "DownArrow key on multiple listbox #" + i); 1.201 + } 1.202 + 1.203 + for (var i = 0; i < multipleListbox.options.length + 1; i++) { 1.204 + reset() 1.205 + synthesizeKey("VK_UP", {}); 1.206 + check(true, "UpArrow key on multiple listbox #" + i); 1.207 + } 1.208 + 1.209 + for (var i = 0; i < multipleListbox.options.length + 1; i++) { 1.210 + reset() 1.211 + synthesizeKey("VK_RIGHT", {}); 1.212 + check(true, "RightArrow key on multiple listbox #" + i); 1.213 + } 1.214 + 1.215 + for (var i = 0; i < multipleListbox.options.length + 1; i++) { 1.216 + reset() 1.217 + synthesizeKey("VK_LEFT", {}); 1.218 + check(true, "LeftArrow key on multiple listbox #" + i); 1.219 + } 1.220 + 1.221 + for (var i = 0; i < 4; i++) { 1.222 + reset() 1.223 + synthesizeKey("VK_PAGE_DOWN", {}); 1.224 + check(true, "PageDown key on multiple listbox #" + i); 1.225 + } 1.226 + 1.227 + for (var i = 0; i < 4; i++) { 1.228 + reset() 1.229 + synthesizeKey("VK_PAGE_UP", {}); 1.230 + check(true, "PageUp key on multiple listbox #" + i); 1.231 + } 1.232 + 1.233 + for (var i = 0; i < 2; i++) { 1.234 + reset() 1.235 + synthesizeKey("VK_END", {}); 1.236 + check(true, "End key on multiple listbox #" + i); 1.237 + } 1.238 + 1.239 + for (var i = 0; i < 2; i++) { 1.240 + reset() 1.241 + synthesizeKey("VK_HOME", {}); 1.242 + check(true, "Home key on multiple listbox #" + i); 1.243 + } 1.244 + 1.245 + reset() 1.246 + synthesizeKey("VK_RETURN", {}); 1.247 + check(true, "Enter key on multiple listbox"); 1.248 + 1.249 + reset() 1.250 + synthesizeKey("VK_ESCAPE", {}); 1.251 + check(false, "Esc key on multiple listbox"); 1.252 + 1.253 + reset() 1.254 + synthesizeKey("VK_F4", {}); 1.255 + check(false, "F4 key on multiple listbox"); 1.256 + 1.257 + reset() 1.258 + synthesizeKey("a", {}); 1.259 + check(false, "'A' key on multiple listbox"); 1.260 + }); 1.261 + 1.262 + multipleListbox.removeEventListener("keydown", onKeydown, false); 1.263 + multipleListbox.removeEventListener("keypress", onKeypress, false); 1.264 + SpecialPowers.removeSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false); 1.265 + 1.266 + 1.267 + 1.268 + var combobox = document.getElementById("combobox"); 1.269 + combobox.addEventListener("keydown", onKeydown, false); 1.270 + combobox.addEventListener("keypress", onKeypress, false); 1.271 + SpecialPowers.addSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false); 1.272 + 1.273 + combobox.focus(); 1.274 + 1.275 + [ false, true ].forEach(function (consume) { 1.276 + doPreventDefault = consume; 1.277 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.278 + reset() 1.279 + synthesizeKey("VK_DOWN", {}); 1.280 + check(true, "DownArrow key on combobox #" + i); 1.281 + } 1.282 + 1.283 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.284 + reset() 1.285 + synthesizeKey("VK_UP", {}); 1.286 + check(true, "UpArrow key on combobox #" + i); 1.287 + } 1.288 + 1.289 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.290 + reset() 1.291 + synthesizeKey("VK_RIGHT", {}); 1.292 + check(true, "RightArrow key on combobox #" + i); 1.293 + } 1.294 + 1.295 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.296 + reset() 1.297 + synthesizeKey("VK_LEFT", {}); 1.298 + check(true, "LeftArrow key on combobox #" + i); 1.299 + } 1.300 + 1.301 + for (var i = 0; i < 4; i++) { 1.302 + reset() 1.303 + synthesizeKey("VK_PAGE_DOWN", {}); 1.304 + check(true, "PageDown key on combobox #" + i); 1.305 + } 1.306 + 1.307 + for (var i = 0; i < 4; i++) { 1.308 + reset() 1.309 + synthesizeKey("VK_PAGE_UP", {}); 1.310 + check(true, "PageUp key on combobox #" + i); 1.311 + } 1.312 + 1.313 + for (var i = 0; i < 2; i++) { 1.314 + reset() 1.315 + synthesizeKey("VK_END", {}); 1.316 + check(true, "End key on combobox #" + i); 1.317 + } 1.318 + 1.319 + for (var i = 0; i < 2; i++) { 1.320 + reset() 1.321 + synthesizeKey("VK_HOME", {}); 1.322 + check(true, "Home key on combobox #" + i); 1.323 + } 1.324 + 1.325 + reset() 1.326 + synthesizeKey("VK_RETURN", {}); 1.327 + check(false, "Enter key on combobox"); 1.328 + 1.329 + reset() 1.330 + synthesizeKey("VK_ESCAPE", {}); 1.331 + check(true, "Esc key on combobox"); 1.332 + 1.333 + if (!kIsWin) { 1.334 + reset() 1.335 + synthesizeKey("VK_F4", {}); 1.336 + check(false, "F4 key on combobox"); 1.337 + } 1.338 + 1.339 + reset() 1.340 + synthesizeKey("a", {}); 1.341 + check(false, "'A' key on combobox"); 1.342 + }); 1.343 + 1.344 + function finish() 1.345 + { 1.346 + combobox.removeEventListener("keydown", onKeydown, false); 1.347 + combobox.removeEventListener("keypress", onKeypress, false); 1.348 + SpecialPowers.removeSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false); 1.349 + SimpleTest.finish(); 1.350 + } 1.351 + 1.352 + // Mac uses native popup for dropdown. Let's skip the tests for popup 1.353 + // since it's not handled in nsListControlFrame. 1.354 + // Similarly, Android doesn't use popup for dropdown. 1.355 + if (kIsMac || kIsAndroid) { 1.356 + finish(); 1.357 + return; 1.358 + } 1.359 + 1.360 + function testDropDown(aCallback) 1.361 + { 1.362 + testOpenDropDown(function () { 1.363 + reset() 1.364 + synthesizeKey("VK_DOWN", { altKey: true }); 1.365 + }, function () { 1.366 + check(true, "Alt + DownArrow key on combobox at opening dropdown"); 1.367 + 1.368 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.369 + reset() 1.370 + synthesizeKey("VK_DOWN", {}); 1.371 + check(true, "DownArrow key on combobox during dropdown open #" + i); 1.372 + } 1.373 + 1.374 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.375 + reset() 1.376 + synthesizeKey("VK_UP", {}); 1.377 + check(true, "UpArrow key on combobox during dropdown open #" + i); 1.378 + } 1.379 + 1.380 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.381 + reset() 1.382 + synthesizeKey("VK_RIGHT", {}); 1.383 + check(true, "RightArrow key on combobox during dropdown open #" + i); 1.384 + } 1.385 + 1.386 + for (var i = 0; i < combobox.options.length + 1; i++) { 1.387 + reset() 1.388 + synthesizeKey("VK_LEFT", {}); 1.389 + check(true, "LeftArrow key on combobox during dropdown open #" + i); 1.390 + } 1.391 + 1.392 + for (var i = 0; i < 4; i++) { 1.393 + reset() 1.394 + synthesizeKey("VK_PAGE_DOWN", {}); 1.395 + check(true, "PageDown key on combobox during dropdown open #" + i); 1.396 + } 1.397 + 1.398 + for (var i = 0; i < 4; i++) { 1.399 + reset() 1.400 + synthesizeKey("VK_PAGE_UP", {}); 1.401 + check(true, "PageUp key on combobox during dropdown open #" + i); 1.402 + } 1.403 + 1.404 + for (var i = 0; i < 2; i++) { 1.405 + reset() 1.406 + synthesizeKey("VK_END", {}); 1.407 + check(true, "End key on combobox during dropdown open #" + i); 1.408 + } 1.409 + 1.410 + for (var i = 0; i < 2; i++) { 1.411 + reset() 1.412 + synthesizeKey("VK_HOME", {}); 1.413 + check(true, "Home key on combobox during dropdown open #" + i); 1.414 + } 1.415 + 1.416 + testCloseDropDown(function () { 1.417 + reset() 1.418 + synthesizeKey("VK_RETURN", {}); 1.419 + }, function () { 1.420 + testOpenDropDown(function () { 1.421 + check(true, "Enter key on combobox at closing dropdown"); 1.422 + 1.423 + synthesizeKey("VK_UP", { altKey: true }); 1.424 + }, function () { 1.425 + check(true, "Alt + UpArrow key on combobox at opening dropdown"); 1.426 + 1.427 + testCloseDropDown(function () { 1.428 + reset() 1.429 + synthesizeKey("VK_ESCAPE", {}); 1.430 + }, function () { 1.431 + check(true, "Esc key on combobox at closing dropdown"); 1.432 + 1.433 + // F4 key opens/closes dropdown only on Windows. So, other platforms 1.434 + // don't need to do anymore. 1.435 + if (!kIsWin) { 1.436 + aCallback(); 1.437 + return; 1.438 + } 1.439 + 1.440 + testOpenDropDown(function () { 1.441 + reset() 1.442 + synthesizeKey("VK_F4", {}); 1.443 + }, function () { 1.444 + check(true, "F4 key on combobox at opening dropdown on Windows"); 1.445 + 1.446 + testCloseDropDown(function () { 1.447 + reset() 1.448 + synthesizeKey("VK_F4", {}); 1.449 + }, function () { 1.450 + check(true, "F4 key on combobox at closing dropdown on Windows"); 1.451 + 1.452 + aCallback(); 1.453 + return; 1.454 + }); 1.455 + }); 1.456 + }); 1.457 + }); 1.458 + }); 1.459 + }); 1.460 + } 1.461 + 1.462 + doPreventDefault = false; 1.463 + testDropDown(function () { 1.464 + // Even if keydown event is consumed by JS, opening/closing dropdown 1.465 + // should work for a11y and security (e.g., cannot close dropdown causes 1.466 + // staying top-most window on the screen). If it's blocked by JS, this 1.467 + // test would cause permanent timeout. 1.468 + doPreventDefault = true; 1.469 + testDropDown(finish); 1.470 + }); 1.471 +} 1.472 + 1.473 +function testOpenDropDown(aTest, aOnOpenDropDown) 1.474 +{ 1.475 + document.addEventListener("popupshowing", function (aEvent) { 1.476 + document.removeEventListener(aEvent.type, arguments.callee, false); 1.477 + setTimeout(aOnOpenDropDown, 0); 1.478 + }, false); 1.479 + aTest(); 1.480 +} 1.481 + 1.482 +function testCloseDropDown(aTest, aOnCloseDropDown) 1.483 +{ 1.484 + document.addEventListener("popuphiding", function (aEvent) { 1.485 + document.removeEventListener(aEvent.type, arguments.callee, false); 1.486 + setTimeout(aOnCloseDropDown, 0) 1.487 + }, false); 1.488 + aTest(); 1.489 +} 1.490 + 1.491 +SimpleTest.waitForFocus(runTests); 1.492 +</script> 1.493 +</body> 1.494 +</html>