toolkit/components/passwordmgr/test/test_basic_form_autocomplete.html

changeset 0
6474c204b198
     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 +

mercurial