1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/passwordmgr/test/test_basic_form_autocomplete.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,815 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<head> 1.7 + <title>Test for Login Manager</title> 1.8 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.9 + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> 1.10 + <script type="text/javascript" src="pwmgr_common.js"></script> 1.11 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.12 +</head> 1.13 +<body> 1.14 +Login Manager test: multiple login autocomplete 1.15 + 1.16 +<script> 1.17 +commonInit(); 1.18 +SimpleTest.waitForExplicitFinish(); 1.19 + 1.20 +// Get the pwmgr service 1.21 +var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"] 1.22 + .getService(SpecialPowers.Ci.nsILoginManager); 1.23 +ok(pwmgr != null, "nsLoginManager service"); 1.24 + 1.25 +// Create some logins just for this form, since we'll be deleting them. 1.26 +var nsLoginInfo = 1.27 +SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1", 1.28 + SpecialPowers.Ci.nsILoginInfo, "init"); 1.29 +ok(nsLoginInfo != null, "nsLoginInfo constructor"); 1.30 + 1.31 + 1.32 +// login0 has no username, so should be filtered out from the autocomplete list. 1.33 +var login0 = new nsLoginInfo( 1.34 + "http://mochi.test:8888", "http://autocomplete:8888", null, 1.35 + "", "user0pass", "", "pword"); 1.36 + 1.37 +var login1 = new nsLoginInfo( 1.38 + "http://mochi.test:8888", "http://autocomplete:8888", null, 1.39 + "tempuser1", "temppass1", "uname", "pword"); 1.40 + 1.41 +var login2 = new nsLoginInfo( 1.42 + "http://mochi.test:8888", "http://autocomplete:8888", null, 1.43 + "testuser2", "testpass2", "uname", "pword"); 1.44 + 1.45 +var login3 = new nsLoginInfo( 1.46 + "http://mochi.test:8888", "http://autocomplete:8888", null, 1.47 + "testuser3", "testpass3", "uname", "pword"); 1.48 + 1.49 +var login4 = new nsLoginInfo( 1.50 + "http://mochi.test:8888", "http://autocomplete:8888", null, 1.51 + "zzzuser4", "zzzpass4", "uname", "pword"); 1.52 + 1.53 +// login 5 only used in the single-user forms 1.54 +var login5 = new nsLoginInfo( 1.55 + "http://mochi.test:8888", "http://autocomplete2", null, 1.56 + "singleuser5", "singlepass5", "uname", "pword"); 1.57 + 1.58 +var login6A = new nsLoginInfo( 1.59 + "http://mochi.test:8888", "http://autocomplete3", null, 1.60 + "form7user1", "form7pass1", "uname", "pword"); 1.61 +var login6B = new nsLoginInfo( 1.62 + "http://mochi.test:8888", "http://autocomplete3", null, 1.63 + "form7user2", "form7pass2", "uname", "pword"); 1.64 + 1.65 +var login7 = new nsLoginInfo( 1.66 + "http://mochi.test:8888", "http://autocomplete4", null, 1.67 + "form8user", "form8pass", "uname", "pword"); 1.68 + 1.69 +var login8A = new nsLoginInfo( 1.70 + "http://mochi.test:8888", "http://autocomplete5", null, 1.71 + "form9userAB", "form9pass", "uname", "pword"); 1.72 + 1.73 +var login8B = new nsLoginInfo( 1.74 + "http://mochi.test:8888", "http://autocomplete5", null, 1.75 + "form9userAAB", "form9pass", "uname", "pword"); 1.76 + 1.77 +// login8C is added later 1.78 +var login8C = new nsLoginInfo( 1.79 + "http://mochi.test:8888", "http://autocomplete5", null, 1.80 + "form9userAABz", "form9pass", "uname", "pword"); 1.81 +// try/catch in case someone runs the tests manually, twice. 1.82 +try { 1.83 + pwmgr.addLogin(login0); 1.84 + pwmgr.addLogin(login1); 1.85 + pwmgr.addLogin(login2); 1.86 + pwmgr.addLogin(login3); 1.87 + pwmgr.addLogin(login4); 1.88 + pwmgr.addLogin(login5); 1.89 + pwmgr.addLogin(login6A); 1.90 + pwmgr.addLogin(login6B); 1.91 + pwmgr.addLogin(login7); 1.92 + pwmgr.addLogin(login8A); 1.93 + pwmgr.addLogin(login8B); 1.94 +} catch (e) { 1.95 + ok(false, "addLogin threw: " + e); 1.96 +} 1.97 + 1.98 +</script> 1.99 +<p id="display"></p> 1.100 + 1.101 +<!-- we presumably can't hide the content for this test. --> 1.102 +<div id="content"> 1.103 + 1.104 + <!-- form1 tests multiple matching logins --> 1.105 + <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> 1.106 + <input type="text" name="uname"> 1.107 + <input type="password" name="pword"> 1.108 + <button type="submit">Submit</button> 1.109 + </form> 1.110 + 1.111 + <!-- other forms test single logins, with autocomplete=off set --> 1.112 + <form id="form2" action="http://autocomplete2" onsubmit="return false;"> 1.113 + <input type="text" name="uname"> 1.114 + <input type="password" name="pword" autocomplete="off"> 1.115 + <button type="submit">Submit</button> 1.116 + </form> 1.117 + 1.118 + <form id="form3" action="http://autocomplete2" onsubmit="return false;"> 1.119 + <input type="text" name="uname" autocomplete="off"> 1.120 + <input type="password" name="pword"> 1.121 + <button type="submit">Submit</button> 1.122 + </form> 1.123 + 1.124 + <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off"> 1.125 + <input type="text" name="uname"> 1.126 + <input type="password" name="pword"> 1.127 + <button type="submit">Submit</button> 1.128 + </form> 1.129 + 1.130 + <form id="form5" action="http://autocomplete2" onsubmit="return false;"> 1.131 + <input type="text" name="uname" autocomplete="off"> 1.132 + <input type="password" name="pword" autocomplete="off"> 1.133 + <button type="submit">Submit</button> 1.134 + </form> 1.135 + 1.136 + <!-- control --> 1.137 + <form id="form6" action="http://autocomplete2" onsubmit="return false;"> 1.138 + <input type="text" name="uname"> 1.139 + <input type="password" name="pword"> 1.140 + <button type="submit">Submit</button> 1.141 + </form> 1.142 + 1.143 + <!-- This form will be manipulated to insert a different username field. --> 1.144 + <form id="form7" action="http://autocomplete3" onsubmit="return false;"> 1.145 + <input type="text" name="uname"> 1.146 + <input type="password" name="pword"> 1.147 + <button type="submit">Submit</button> 1.148 + </form> 1.149 + 1.150 + <!-- test for no autofill after onblur with blank username --> 1.151 + <form id="form8" action="http://autocomplete4" onsubmit="return false;"> 1.152 + <input type="text" name="uname"> 1.153 + <input type="password" name="pword"> 1.154 + <button type="submit">Submit</button> 1.155 + </form> 1.156 + 1.157 + <!-- test autocomplete dropdown --> 1.158 + <form id="form9" action="http://autocomplete5" onsubmit="return false;"> 1.159 + <input type="text" name="uname"> 1.160 + <input type="password" name="pword"> 1.161 + <button type="submit">Submit</button> 1.162 + </form> 1.163 +</div> 1.164 + 1.165 +<pre id="test"> 1.166 +<script class="testbody" type="text/javascript"> 1.167 + 1.168 +/** Test for Login Manager: multiple login autocomplete. **/ 1.169 + 1.170 + 1.171 +var uname = $_(1, "uname"); 1.172 +var pword = $_(1, "pword"); 1.173 +const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; 1.174 + 1.175 +// Restore the form to the default state. 1.176 +function restoreForm() { 1.177 + uname.value = ""; 1.178 + pword.value = ""; 1.179 + uname.focus(); 1.180 +} 1.181 + 1.182 + 1.183 +// Check for expected username/password in form. 1.184 +function checkACForm(expectedUsername, expectedPassword) { 1.185 + var formID = uname.parentNode.id; 1.186 + is(uname.value, expectedUsername, "Checking " + formID + " username"); 1.187 + is(pword.value, expectedPassword, "Checking " + formID + " password"); 1.188 +} 1.189 + 1.190 + 1.191 +function sendFakeAutocompleteEvent(element) { 1.192 + var acEvent = document.createEvent("HTMLEvents"); 1.193 + acEvent.initEvent("DOMAutoComplete", true, false); 1.194 + element.dispatchEvent(acEvent); 1.195 +} 1.196 + 1.197 +function hitEventLoop(func, times) { 1.198 + if (times > 0) { 1.199 + setTimeout(hitEventLoop, 0, func, times - 1); 1.200 + } else { 1.201 + setTimeout(func, 0); 1.202 + } 1.203 +} 1.204 + 1.205 +var gNextTestWillOpenPopup = true; 1.206 +var gLastTest = 704; 1.207 + 1.208 +function addPopupListener(eventName, func, capture) { 1.209 + autocompletePopup.addEventListener(eventName, func, capture); 1.210 +} 1.211 + 1.212 +function removePopupListener(eventName, func, capture) { 1.213 + autocompletePopup.removeEventListener(eventName, func, capture); 1.214 +} 1.215 + 1.216 +/* 1.217 + * Main section of test... 1.218 + * 1.219 + * This is a bit hacky, because the events are either being sent or 1.220 + * processes asynchronously, so we need to interrupt our flow with lots of 1.221 + * setTimeout() calls. The case statements are executed in order, one per 1.222 + * timeout. 1.223 + */ 1.224 +function runTest(testNum) { 1.225 + ok(true, "Starting test #" + testNum); 1.226 + 1.227 + if (gNextTestWillOpenPopup) { 1.228 + addPopupListener("popupshown", function() { 1.229 + removePopupListener("popupshown", arguments.callee, false); 1.230 + 1.231 + if (testNum != gLastTest) { 1.232 + window.setTimeout(runTest, 0, testNum + 1); 1.233 + } 1.234 + }, false); 1.235 + } else { 1.236 + var unexpectedPopup = function() { 1.237 + removePopupListener("popupshown", arguments.callee, false); 1.238 + 1.239 + ok(false, "Test " + testNum + " should not show a popup"); 1.240 + }; 1.241 + addPopupListener("popupshown", unexpectedPopup, false); 1.242 + if (testNum == gLastTest) { 1.243 + removePopupListener("popupshown", unexpectedPopup, false); 1.244 + } else { 1.245 + hitEventLoop(function() { 1.246 + removePopupListener("popupshown", unexpectedPopup, false); 1.247 + runTest(testNum + 1); 1.248 + }, 100); 1.249 + } 1.250 + } 1.251 + 1.252 + switch(testNum) { 1.253 + case 1: 1.254 + // Make sure initial form is empty. 1.255 + checkACForm("", ""); 1.256 + // Trigger autocomplete popup 1.257 + restoreForm(); 1.258 + doKey("down"); 1.259 + break; 1.260 + 1.261 + case 2: 1.262 + // Check first entry 1.263 + doKey("down"); 1.264 + checkACForm("", ""); // value shouldn't update 1.265 + doKey("return"); // not "enter"! 1.266 + checkACForm("tempuser1", "temppass1"); 1.267 + 1.268 + // Trigger autocomplete popup 1.269 + restoreForm(); 1.270 + doKey("down"); 1.271 + break; 1.272 + 1.273 + case 3: 1.274 + // Check second entry 1.275 + doKey("down"); 1.276 + doKey("down"); 1.277 + doKey("return"); // not "enter"! 1.278 + checkACForm("testuser2", "testpass2"); 1.279 + 1.280 + // Trigger autocomplete popup 1.281 + restoreForm(); 1.282 + doKey("down"); 1.283 + break; 1.284 + 1.285 + case 4: 1.286 + // Check third entry 1.287 + doKey("down"); 1.288 + doKey("down"); 1.289 + doKey("down"); 1.290 + doKey("return"); 1.291 + checkACForm("testuser3", "testpass3"); 1.292 + 1.293 + // Trigger autocomplete popup 1.294 + restoreForm(); 1.295 + doKey("down"); 1.296 + break; 1.297 + 1.298 + case 5: 1.299 + // Check fourth entry 1.300 + doKey("down"); 1.301 + doKey("down"); 1.302 + doKey("down"); 1.303 + doKey("down"); 1.304 + doKey("return"); 1.305 + checkACForm("zzzuser4", "zzzpass4"); 1.306 + 1.307 + // Trigger autocomplete popup 1.308 + restoreForm(); 1.309 + doKey("down"); 1.310 + break; 1.311 + 1.312 + case 6: 1.313 + // Check first entry (wraparound) 1.314 + doKey("down"); 1.315 + doKey("down"); 1.316 + doKey("down"); 1.317 + doKey("down"); 1.318 + doKey("down"); // deselects 1.319 + doKey("down"); 1.320 + doKey("return"); 1.321 + checkACForm("tempuser1", "temppass1"); 1.322 + 1.323 + // Trigger autocomplete popup 1.324 + restoreForm(); 1.325 + doKey("down"); 1.326 + break; 1.327 + 1.328 + case 7: 1.329 + // Check the last entry via arrow-up 1.330 + doKey("up"); 1.331 + doKey("return"); 1.332 + checkACForm("zzzuser4", "zzzpass4"); 1.333 + 1.334 + // Trigger autocomplete popup 1.335 + restoreForm(); 1.336 + doKey("down"); 1.337 + break; 1.338 + 1.339 + case 8: 1.340 + // Check the last entry via arrow-up 1.341 + doKey("down"); // select first entry 1.342 + doKey("up"); // selects nothing! 1.343 + doKey("up"); // select last entry 1.344 + doKey("return"); 1.345 + checkACForm("zzzuser4", "zzzpass4"); 1.346 + 1.347 + // Trigger autocomplete popup 1.348 + restoreForm(); 1.349 + doKey("down"); 1.350 + break; 1.351 + 1.352 + case 9: 1.353 + // Check the last entry via arrow-up (wraparound) 1.354 + doKey("down"); 1.355 + doKey("up"); // deselects 1.356 + doKey("up"); // last entry 1.357 + doKey("up"); 1.358 + doKey("up"); 1.359 + doKey("up"); // first entry 1.360 + doKey("up"); // deselects 1.361 + doKey("up"); // last entry 1.362 + doKey("return"); 1.363 + checkACForm("zzzuser4", "zzzpass4"); 1.364 + 1.365 + // Trigger autocomplete popup 1.366 + restoreForm(); 1.367 + doKey("down"); 1.368 + break; 1.369 + 1.370 + case 10: 1.371 + // Set first entry w/o triggering autocomplete 1.372 + doKey("down"); 1.373 + doKey("right"); 1.374 + checkACForm("tempuser1", ""); // empty password 1.375 + 1.376 + // Trigger autocomplete popup 1.377 + restoreForm(); 1.378 + doKey("down"); 1.379 + break; 1.380 + 1.381 + case 11: 1.382 + // Set first entry w/o triggering autocomplete 1.383 + doKey("down"); 1.384 + doKey("left"); 1.385 + checkACForm("tempuser1", ""); // empty password 1.386 + 1.387 + // Trigger autocomplete popup 1.388 + restoreForm(); 1.389 + doKey("down"); 1.390 + break; 1.391 + 1.392 + case 12: 1.393 + // Check first entry (page up) 1.394 + doKey("down"); 1.395 + doKey("down"); 1.396 + doKey("page_up"); 1.397 + doKey("return"); 1.398 + checkACForm("tempuser1", "temppass1"); 1.399 + 1.400 + // Trigger autocomplete popup 1.401 + restoreForm(); 1.402 + doKey("down"); 1.403 + gNextTestWillOpenPopup = false; 1.404 + break; 1.405 + 1.406 + case 13: 1.407 + // Check last entry (page down) 1.408 + doKey("down"); 1.409 + doKey("page_down"); 1.410 + doKey("return"); 1.411 + checkACForm("zzzuser4", "zzzpass4"); 1.412 + restoreForm(); 1.413 + gNextTestWillOpenPopup = false; 1.414 + break; 1.415 + 1.416 + case 14: 1.417 + // Send a fake (untrusted) event. 1.418 + checkACForm("", ""); 1.419 + uname.value = "zzzuser4"; 1.420 + sendFakeAutocompleteEvent(uname); 1.421 + checkACForm("zzzuser4", ""); 1.422 + gNextTestWillOpenPopup = true; 1.423 + break; 1.424 + 1.425 + case 15: 1.426 + //checkACForm("zzzuser4", ""); 1.427 + 1.428 + // Trigger autocomplete popup 1.429 + restoreForm(); 1.430 + doKey("down"); 1.431 + testNum = 49; 1.432 + break; 1.433 + 1.434 + // XXX tried sending character "t" before/during dropdown to test 1.435 + // filtering, but had no luck. Seemed like the character was getting lost. 1.436 + // Setting uname.value didn't seem to work either. This works with a human 1.437 + // driver, so I'm not sure what's up. 1.438 + 1.439 + 1.440 + case 50: 1.441 + // Delete the first entry (of 4), "tempuser1" 1.442 + doKey("down"); 1.443 + var numLogins; 1.444 + numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); 1.445 + is(numLogins, 5, "Correct number of logins before deleting one"); 1.446 + 1.447 + // On OS X, shift-backspace and shift-delete work, just delete does not. 1.448 + // On Win/Linux, shift-backspace does not work, delete and shift-delete do. 1.449 + doKey("delete", shiftModifier); 1.450 + 1.451 + checkACForm("", ""); 1.452 + numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); 1.453 + is(numLogins, 4, "Correct number of logins after deleting one"); 1.454 + doKey("return"); 1.455 + checkACForm("testuser2", "testpass2"); 1.456 + 1.457 + // Trigger autocomplete popup 1.458 + restoreForm(); 1.459 + doKey("down"); 1.460 + break; 1.461 + 1.462 + case 51: 1.463 + // Check the new first entry (of 3) 1.464 + doKey("down"); 1.465 + doKey("return"); 1.466 + checkACForm("testuser2", "testpass2"); 1.467 + 1.468 + // Trigger autocomplete popup 1.469 + restoreForm(); 1.470 + doKey("down"); 1.471 + break; 1.472 + 1.473 + case 52: 1.474 + // Delete the second entry (of 3), "testuser3" 1.475 + doKey("down"); 1.476 + doKey("down"); 1.477 + doKey("delete", shiftModifier); 1.478 + checkACForm("", ""); 1.479 + numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); 1.480 + is(numLogins, 3, "Correct number of logins after deleting one"); 1.481 + doKey("return"); 1.482 + checkACForm("zzzuser4", "zzzpass4"); 1.483 + 1.484 + // Trigger autocomplete popup 1.485 + restoreForm(); 1.486 + doKey("down"); 1.487 + break; 1.488 + 1.489 + case 53: 1.490 + // Check the new second entry (of 2) 1.491 + doKey("down"); 1.492 + doKey("return"); 1.493 + checkACForm("testuser2", "testpass2"); 1.494 + 1.495 + // Trigger autocomplete popup 1.496 + restoreForm(); 1.497 + doKey("down"); 1.498 + break; 1.499 + 1.500 + case 54: 1.501 + // Delete the last entry (of 2), "zzzuser4" 1.502 + doKey("down"); 1.503 + doKey("down"); 1.504 + doKey("delete", shiftModifier); 1.505 + checkACForm("", ""); 1.506 + numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); 1.507 + is(numLogins, 2, "Correct number of logins after deleting one"); 1.508 + doKey("return"); 1.509 + checkACForm("testuser2", "testpass2"); 1.510 + 1.511 + // Trigger autocomplete popup 1.512 + restoreForm(); 1.513 + doKey("down"); 1.514 + break; 1.515 + 1.516 + case 55: 1.517 + // Check the new second entry (of 2) 1.518 + doKey("down"); 1.519 + doKey("return"); 1.520 + checkACForm("testuser2", "testpass2"); 1.521 + 1.522 + // Trigger autocomplete popup 1.523 + restoreForm(); 1.524 + doKey("down"); 1.525 + gNextTestWillOpenPopup = false; 1.526 + break; 1.527 + 1.528 + case 56: 1.529 + // Delete the only remaining entry, "testuser2" 1.530 + doKey("down"); 1.531 + doKey("delete", shiftModifier); 1.532 + //doKey("return"); 1.533 + checkACForm("", ""); 1.534 + numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); 1.535 + is(numLogins, 1, "Correct number of logins after deleting one"); 1.536 + pwmgr.removeLogin(login0); // remove the login that's not shown in the list. 1.537 + testNum = 99; 1.538 + gNextTestWillOpenPopup = true; 1.539 + break; 1.540 + 1.541 + 1.542 + /* Tests for single-user forms with autocomplete=off */ 1.543 + 1.544 + case 100: 1.545 + // Turn our attention to form2 1.546 + uname = $_(2, "uname"); 1.547 + pword = $_(2, "pword"); 1.548 + checkACForm("", ""); 1.549 + 1.550 + // Trigger autocomplete popup 1.551 + restoreForm(); 1.552 + doKey("down"); 1.553 + gNextTestWillOpenPopup = false; 1.554 + break; 1.555 + 1.556 + case 101: 1.557 + // Check first entry 1.558 + doKey("down"); 1.559 + checkACForm("", ""); // value shouldn't update 1.560 + doKey("return"); // not "enter"! 1.561 + checkACForm("singleuser5", "singlepass5"); 1.562 + restoreForm(); // clear field, so reloading test doesn't fail 1.563 + gNextTestWillOpenPopup = true; 1.564 + break; 1.565 + 1.566 + case 102: 1.567 + // Turn our attention to form3 1.568 + uname = $_(3, "uname"); 1.569 + pword = $_(3, "pword"); 1.570 + checkACForm("", ""); 1.571 + 1.572 + // Trigger autocomplete popup 1.573 + restoreForm(); 1.574 + doKey("down"); 1.575 + gNextTestWillOpenPopup = false; 1.576 + break; 1.577 + 1.578 + case 103: 1.579 + // Check first entry 1.580 + doKey("down"); 1.581 + checkACForm("", ""); // value shouldn't update 1.582 + doKey("return"); // not "enter"! 1.583 + checkACForm("singleuser5", "singlepass5"); 1.584 + gNextTestWillOpenPopup = true; 1.585 + break; 1.586 + 1.587 + case 104: 1.588 + // Turn our attention to form4 1.589 + uname = $_(4, "uname"); 1.590 + pword = $_(4, "pword"); 1.591 + checkACForm("", ""); 1.592 + 1.593 + // Trigger autocomplete popup 1.594 + restoreForm(); 1.595 + doKey("down"); 1.596 + gNextTestWillOpenPopup = false; 1.597 + break; 1.598 + 1.599 + case 105: 1.600 + // Check first entry 1.601 + doKey("down"); 1.602 + checkACForm("", ""); // value shouldn't update 1.603 + doKey("return"); // not "enter"! 1.604 + checkACForm("singleuser5", "singlepass5"); 1.605 + gNextTestWillOpenPopup = true; 1.606 + break; 1.607 + 1.608 + case 106: 1.609 + // Turn our attention to form5 1.610 + uname = $_(5, "uname"); 1.611 + pword = $_(5, "pword"); 1.612 + checkACForm("", ""); 1.613 + 1.614 + // Trigger autocomplete popup 1.615 + restoreForm(); 1.616 + doKey("down"); 1.617 + gNextTestWillOpenPopup = false; 1.618 + break; 1.619 + 1.620 + case 107: 1.621 + // Check first entry 1.622 + doKey("down"); 1.623 + checkACForm("", ""); // value shouldn't update 1.624 + doKey("return"); // not "enter"! 1.625 + checkACForm("singleuser5", "singlepass5"); 1.626 + gNextTestWillOpenPopup = false; 1.627 + break; 1.628 + 1.629 + case 108: 1.630 + // Turn our attention to form6 1.631 + // (this is a control, w/o autocomplete=off, to ensure the login 1.632 + // that was being suppressed would have been filled in otherwise) 1.633 + uname = $_(6, "uname"); 1.634 + pword = $_(6, "pword"); 1.635 + checkACForm("singleuser5", "singlepass5"); 1.636 + gNextTestWillOpenPopup = false; 1.637 + break; 1.638 + 1.639 + case 109: 1.640 + // Test that the password field remains filled in after changing 1.641 + // the username. 1.642 + uname.focus(); 1.643 + doKey("right"); 1.644 + sendChar("X"); 1.645 + // Trigger the 'blur' event on uname 1.646 + pword.focus(); 1.647 + checkACForm("sXingleuser5", "singlepass5"); 1.648 + 1.649 + pwmgr.removeLogin(login5); 1.650 + testNum = 499; 1.651 + gNextTestWillOpenPopup = true; 1.652 + break; 1.653 + 1.654 + case 500: 1.655 + // Turn our attention to form7 1.656 + uname = $_(7, "uname"); 1.657 + pword = $_(7, "pword"); 1.658 + checkACForm("", ""); 1.659 + 1.660 + // Insert a new username field into the form. We'll then make sure 1.661 + // that invoking the autocomplete doesn't try to fill the form. 1.662 + var newField = document.createElement("input"); 1.663 + newField.setAttribute("type", "text"); 1.664 + newField.setAttribute("name", "uname2"); 1.665 + pword.parentNode.insertBefore(newField, pword); 1.666 + is($_(7, "uname2").value, "", "Verifying empty uname2");; 1.667 + 1.668 + // Delete login6B. It was created just to prevent filling in a login 1.669 + // automatically, removing it makes it more likely that we'll catch a 1.670 + // future regression with form filling here. 1.671 + pwmgr.removeLogin(login6B); 1.672 + 1.673 + // Trigger autocomplete popup 1.674 + restoreForm(); 1.675 + doKey("down"); 1.676 + gNextTestWillOpenPopup = false; 1.677 + break; 1.678 + 1.679 + case 501: 1.680 + // Check first entry 1.681 + doKey("down"); 1.682 + checkACForm("", ""); // value shouldn't update 1.683 + doKey("return"); // not "enter"! 1.684 + // The form changes, so we expect the old username field to get the 1.685 + // selected autocomplete value, but neither the new username field nor 1.686 + // the password field should have any values filled in. 1.687 + checkACForm("form7user1", ""); 1.688 + is($_(7, "uname2").value, "", "Verifying empty uname2");; 1.689 + restoreForm(); // clear field, so reloading test doesn't fail 1.690 + 1.691 + pwmgr.removeLogin(login6A); 1.692 + testNum = 599; 1.693 + gNextTestWillOpenPopup = false; 1.694 + break; 1.695 + 1.696 + case 600: 1.697 + // Turn our attention to form8 1.698 + uname = $_(8, "uname"); 1.699 + pword = $_(8, "pword"); 1.700 + checkACForm("form8user", "form8pass"); 1.701 + restoreForm(); 1.702 + gNextTestWillOpenPopup = false; 1.703 + break; 1.704 + 1.705 + case 601: 1.706 + checkACForm("", ""); 1.707 + // Focus the previous form to trigger a blur. 1.708 + $_(7, "uname").focus(); 1.709 + gNextTestWillOpenPopup = false; 1.710 + break; 1.711 + 1.712 + case 602: 1.713 + checkACForm("", ""); 1.714 + restoreForm(); 1.715 + gNextTestWillOpenPopup = false; 1.716 + break; 1.717 + 1.718 + case 603: 1.719 + checkACForm("", ""); 1.720 + pwmgr.removeLogin(login7); 1.721 + 1.722 + testNum = 699; 1.723 + gNextTestWillOpenPopup = true; 1.724 + break; 1.725 + 1.726 + case 700: 1.727 + // Turn our attention to form9 to test the dropdown - bug 497541 1.728 + uname = $_(9, "uname"); 1.729 + pword = $_(9, "pword"); 1.730 + uname.focus(); 1.731 + sendString("form9userAB"); 1.732 + gNextTestWillOpenPopup = true; 1.733 + break; 1.734 + 1.735 + case 701: 1.736 + checkACForm("form9userAB", ""); 1.737 + uname.focus(); 1.738 + doKey("left"); 1.739 + sendChar("A"); 1.740 + gNextTestWillOpenPopup = false; 1.741 + break; 1.742 + 1.743 + case 702: 1.744 + // check dropdown is updated after inserting "A" 1.745 + checkACForm("form9userAAB", ""); 1.746 + checkMenuEntries(["form9userAAB"]); 1.747 + doKey("down"); 1.748 + doKey("return"); 1.749 + checkACForm("form9userAAB", "form9pass"); 1.750 + gNextTestWillOpenPopup = false; 1.751 + break; 1.752 + 1.753 + case 703: 1.754 + pwmgr.addLogin(login8C); 1.755 + uname.focus(); 1.756 + sendChar("z"); 1.757 + gNextTestWillOpenPopup = false; 1.758 + break; 1.759 + 1.760 + case 704: 1.761 + // check that empty results are cached - bug 496466 1.762 + checkMenuEntries([]); 1.763 + 1.764 + SimpleTest.finish(); 1.765 + return; 1.766 + 1.767 + default: 1.768 + ok(false, "Unexpected invocation of test #" + testNum); 1.769 + SimpleTest.finish(); 1.770 + return; 1.771 + } 1.772 +} 1.773 + 1.774 + 1.775 +function checkMenuEntries(expectedValues) { 1.776 + var actualValues = getMenuEntries(); 1.777 + is(actualValues.length, expectedValues.length, "Checking length of expected menu"); 1.778 + for (var i = 0; i < expectedValues.length; i++) 1.779 + is(actualValues[i], expectedValues[i], "Checking menu entry #"+i); 1.780 +} 1.781 + 1.782 +var autocompletePopup; 1.783 +function getMenuEntries() { 1.784 + var entries = []; 1.785 + 1.786 + // Could perhaps pull values directly from the controller, but it seems 1.787 + // more reliable to test the values that are actually in the tree? 1.788 + var column = autocompletePopup.tree.columns[0]; 1.789 + var numRows = autocompletePopup.tree.view.rowCount; 1.790 + for (var i = 0; i < numRows; i++) { 1.791 + entries.push(autocompletePopup.tree.view.getValueAt(i, column)); 1.792 + } 1.793 + return entries; 1.794 +} 1.795 + 1.796 +function startTest() { 1.797 + var Ci = SpecialPowers.Ci; 1.798 + chromeWin = SpecialPowers.wrap(window) 1.799 + .QueryInterface(Ci.nsIInterfaceRequestor) 1.800 + .getInterface(Ci.nsIWebNavigation) 1.801 + .QueryInterface(Ci.nsIDocShellTreeItem) 1.802 + .rootTreeItem 1.803 + .QueryInterface(Ci.nsIInterfaceRequestor) 1.804 + .getInterface(Ci.nsIDOMWindow) 1.805 + .QueryInterface(Ci.nsIDOMChromeWindow); 1.806 + // shouldn't reach into browser internals like this and 1.807 + // shouldn't assume ID is consistent across products 1.808 + autocompletePopup = chromeWin.document.getElementById("PopupAutoComplete"); 1.809 + ok(autocompletePopup, "Got autocomplete popup"); 1.810 + runTest(1); 1.811 +} 1.812 + 1.813 +window.onload = startTest; 1.814 +</script> 1.815 +</pre> 1.816 +</body> 1.817 +</html> 1.818 +