Bug 463154 - Form history should record creation/usage timestamps. r=mconnor, r=sdwilsh
[wine-gecko.git] / toolkit / components / passwordmgr / test / test_basic_form_autocomplete.html
blob9ff17282ec425ce9d4e348fb3c187196483b3326
1 <!DOCTYPE HTML>
2 <html>
3 <head>
4 <title>Test for Login Manager</title>
5 <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
6 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
7 <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
8 <script type="text/javascript" src="pwmgr_common.js"></script>
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
10 </head>
11 <body>
12 Login Manager test: multiple login autocomplete
13 <p id="display"></p>
15 <!-- we presumably can't hide the content for this test. -->
16 <div id="content">
18 <!-- form1 tests multiple matching logins -->
19 <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
20 <input type="text" name="uname">
21 <input type="password" name="pword">
22 <button type="submit">Submit</button>
23 </form>
25 <!-- other forms test single logins, with autocomplete=off set -->
26 <form id="form2" action="http://autocomplete2" onsubmit="return false;">
27 <input type="text" name="uname">
28 <input type="password" name="pword" autocomplete="off">
29 <button type="submit">Submit</button>
30 </form>
32 <form id="form3" action="http://autocomplete2" onsubmit="return false;">
33 <input type="text" name="uname" autocomplete="off">
34 <input type="password" name="pword">
35 <button type="submit">Submit</button>
36 </form>
38 <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off">
39 <input type="text" name="uname">
40 <input type="password" name="pword">
41 <button type="submit">Submit</button>
42 </form>
44 <form id="form5" action="http://autocomplete2" onsubmit="return false;">
45 <input type="text" name="uname" autocomplete="off">
46 <input type="password" name="pword" autocomplete="off">
47 <button type="submit">Submit</button>
48 </form>
50 <!-- control -->
51 <form id="form6" action="http://autocomplete2" onsubmit="return false;">
52 <input type="text" name="uname">
53 <input type="password" name="pword">
54 <button type="submit">Submit</button>
55 </form>
57 <!-- This form will be manipulated to insert a different username field. -->
58 <form id="form7" action="http://autocomplete3" onsubmit="return false;">
59 <input type="text" name="uname">
60 <input type="password" name="pword">
61 <button type="submit">Submit</button>
62 </form>
63 </div>
65 <pre id="test">
66 <script class="testbody" type="text/javascript">
68 /** Test for Login Manager: multiple login autocomplete. **/
70 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
72 var uname = $_(1, "uname");
73 var pword = $_(1, "pword");
74 const shiftModifier = Components.interfaces.nsIDOMNSEvent.SHIFT_MASK;
76 // Get the pwmgr service
77 var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
78 .getService(Components.interfaces.nsILoginManager);
79 ok(pwmgr != null, "nsLoginManager service");
81 // Create some logins just for this form, since we'll be deleting them.
82 var nsLoginInfo =
83 Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
84 Components.interfaces.nsILoginInfo, "init");
85 ok(nsLoginInfo != null, "nsLoginInfo constructor");
88 var login1 = new nsLoginInfo(
89 "http://localhost:8888", "http://autocomplete:8888", null,
90 "tempuser1", "temppass1", "uname", "pword");
92 var login2 = new nsLoginInfo(
93 "http://localhost:8888", "http://autocomplete:8888", null,
94 "testuser2", "testpass2", "uname", "pword");
96 var login3 = new nsLoginInfo(
97 "http://localhost:8888", "http://autocomplete:8888", null,
98 "testuser3", "testpass3", "uname", "pword");
100 var login4 = new nsLoginInfo(
101 "http://localhost:8888", "http://autocomplete:8888", null,
102 "zzzuser4", "zzzpass4", "uname", "pword");
104 // login 5 only used in the single-user forms
105 var login5 = new nsLoginInfo(
106 "http://localhost:8888", "http://autocomplete2", null,
107 "singleuser5", "singlepass5", "uname", "pword");
109 var login6A = new nsLoginInfo(
110 "http://localhost:8888", "http://autocomplete3", null,
111 "form7user1", "form7pass1", "uname", "pword");
112 var login6B = new nsLoginInfo(
113 "http://localhost:8888", "http://autocomplete3", null,
114 "form7user2", "form7pass2", "uname", "pword");
116 // try/catch in case someone runs the tests manually, twice.
117 try {
118 pwmgr.addLogin(login1);
119 pwmgr.addLogin(login2);
120 pwmgr.addLogin(login3);
121 pwmgr.addLogin(login4);
122 pwmgr.addLogin(login5);
123 pwmgr.addLogin(login6A);
124 pwmgr.addLogin(login6B);
125 } catch (e) {
126 ok(false, "addLogin threw: " + e);
130 // Restore the form to the default state.
131 function restoreForm() {
132 uname.value = "";
133 pword.value = "";
134 uname.focus();
138 // Check for expected username/password in form.
139 function checkACForm(expectedUsername, expectedPassword) {
140 var formID = uname.parentNode.id;
141 is(uname.value, expectedUsername, "Checking " + formID + " username");
142 is(pword.value, expectedPassword, "Checking " + formID + " password");
148 * Main section of test...
150 * This is a bit hacky, because the events are either being sent or
151 * processes asynchronously, so we need to interrupt our flow with lots of
152 * setTimeout() calls. The case statements are executed in order, one per
153 * timeout.
155 function runTest(testNum) {
156 // Seems we need to enable this again, or sendKeyEvent() complaints.
157 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
158 ok(true, "Starting test #" + testNum);
160 switch(testNum) {
161 case 1:
162 // Make sure initial form is empty.
163 checkACForm("", "");
164 // Trigger autocomplete popup
165 restoreForm();
166 doKey("down");
167 break;
169 case 2:
170 // Check first entry
171 doKey("down");
172 checkACForm("", ""); // value shouldn't update
173 doKey("return"); // not "enter"!
174 checkACForm("tempuser1", "temppass1");
176 // Trigger autocomplete popup
177 restoreForm();
178 doKey("down");
179 break;
181 case 3:
182 // Check second entry
183 doKey("down");
184 doKey("down");
185 doKey("return"); // not "enter"!
186 checkACForm("testuser2", "testpass2");
188 // Trigger autocomplete popup
189 restoreForm();
190 doKey("down");
191 break;
193 case 4:
194 // Check third entry
195 doKey("down");
196 doKey("down");
197 doKey("down");
198 doKey("return");
199 checkACForm("testuser3", "testpass3");
201 // Trigger autocomplete popup
202 restoreForm();
203 doKey("down");
204 break;
206 case 5:
207 // Check fourth entry
208 doKey("down");
209 doKey("down");
210 doKey("down");
211 doKey("down");
212 doKey("return");
213 checkACForm("zzzuser4", "zzzpass4");
215 // Trigger autocomplete popup
216 restoreForm();
217 doKey("down");
218 break;
220 case 6:
221 // Check first entry (wraparound)
222 doKey("down");
223 doKey("down");
224 doKey("down");
225 doKey("down");
226 doKey("down"); // deselects
227 doKey("down");
228 doKey("return");
229 checkACForm("tempuser1", "temppass1");
231 // Trigger autocomplete popup
232 restoreForm();
233 doKey("down");
234 break;
236 case 7:
237 // Check the last entry via arrow-up
238 doKey("up");
239 doKey("return");
240 checkACForm("zzzuser4", "zzzpass4");
242 // Trigger autocomplete popup
243 restoreForm();
244 doKey("down");
245 break;
247 case 8:
248 // Check the last entry via arrow-up
249 doKey("down"); // select first entry
250 doKey("up"); // selects nothing!
251 doKey("up"); // select last entry
252 doKey("return");
253 checkACForm("zzzuser4", "zzzpass4");
255 // Trigger autocomplete popup
256 restoreForm();
257 doKey("down");
258 break;
260 case 9:
261 // Check the last entry via arrow-up (wraparound)
262 doKey("down");
263 doKey("up"); // deselects
264 doKey("up"); // last entry
265 doKey("up");
266 doKey("up");
267 doKey("up"); // first entry
268 doKey("up"); // deselects
269 doKey("up"); // last entry
270 doKey("return");
271 checkACForm("zzzuser4", "zzzpass4");
273 // Trigger autocomplete popup
274 restoreForm();
275 doKey("down");
276 break;
278 case 10:
279 // Set first entry w/o triggering autocomplete
280 doKey("down");
281 doKey("right");
282 checkACForm("tempuser1", ""); // empty password
284 // Trigger autocomplete popup
285 restoreForm();
286 doKey("down");
287 break;
289 case 11:
290 // Set first entry w/o triggering autocomplete
291 doKey("down");
292 doKey("left");
293 checkACForm("tempuser1", ""); // empty password
295 // Trigger autocomplete popup
296 restoreForm();
297 doKey("down");
298 break;
300 case 12:
301 // Check first entry (page up)
302 doKey("down");
303 doKey("down");
304 doKey("page_up");
305 doKey("return");
306 checkACForm("tempuser1", "temppass1");
308 // Trigger autocomplete popup
309 restoreForm();
310 doKey("down");
311 break;
313 case 13:
314 // Check last entry (page down)
315 doKey("down");
316 doKey("page_down");
317 doKey("return");
318 checkACForm("zzzuser4", "zzzpass4");
320 // Trigger autocomplete popup
321 restoreForm();
322 doKey("down");
323 testNum = 49;
324 break;
326 case 14:
327 // Abort with ESC
328 // XXX This isn't working in the test suite, seems to fubar any later tests.
329 // doKey("down");
330 // doKey("down");
331 // doKey("escape");
332 // checkACForm("", "");
334 // Trigger autocomplete popup
335 // restoreForm();
336 // doKey("down");
337 break;
339 // XXX tried sending character "t" before/during dropdown to test
340 // filtering, but had no luck. Seemed like the character was getting lost.
341 // Setting uname.value didn't seem to work either. This works with a human
342 // driver, so I'm not sure what's up.
345 case 50:
346 // Delete the first entry (of 4), "tempuser1"
347 doKey("down");
348 var numLogins;
349 numLogins = pwmgr.countLogins("http://localhost:8888", "http://autocomplete:8888", null);
350 is(numLogins, 4, "Correct number of logins before deleting one");
352 // On OS X, shift-backspace and shift-delete work, just delete does not.
353 // On Win/Linux, shift-backspace does not work, delete and shift-delete do.
354 doKey("delete", shiftModifier);
356 checkACForm("", "");
357 numLogins = pwmgr.countLogins("http://localhost:8888", "http://autocomplete:8888", null);
358 is(numLogins, 3, "Correct number of logins after deleting one");
359 doKey("return");
360 checkACForm("testuser2", "testpass2");
362 // Trigger autocomplete popup
363 restoreForm();
364 doKey("down");
365 break;
367 case 51:
368 // Check the new first entry (of 3)
369 doKey("down");
370 doKey("return");
371 checkACForm("testuser2", "testpass2");
373 // Trigger autocomplete popup
374 restoreForm();
375 doKey("down");
376 break;
378 case 52:
379 // Delete the second entry (of 3), "testuser3"
380 doKey("down");
381 doKey("down");
382 doKey("delete", shiftModifier);
383 checkACForm("", "");
384 numLogins = pwmgr.countLogins("http://localhost:8888", "http://autocomplete:8888", null);
385 is(numLogins, 2, "Correct number of logins after deleting one");
386 doKey("return");
387 checkACForm("zzzuser4", "zzzpass4");
389 // Trigger autocomplete popup
390 restoreForm();
391 doKey("down");
392 break;
394 case 53:
395 // Check the new second entry (of 2)
396 doKey("down");
397 doKey("return");
398 checkACForm("testuser2", "testpass2");
400 // Trigger autocomplete popup
401 restoreForm();
402 doKey("down");
403 break;
405 case 54:
406 // Delete the last entry (of 2), "zzzuser4"
407 doKey("down");
408 doKey("down");
409 doKey("delete", shiftModifier);
410 checkACForm("", "");
411 numLogins = pwmgr.countLogins("http://localhost:8888", "http://autocomplete:8888", null);
412 is(numLogins, 1, "Correct number of logins after deleting one");
413 doKey("return");
414 checkACForm("testuser2", "testpass2");
416 // Trigger autocomplete popup
417 restoreForm();
418 doKey("down");
419 break;
421 case 55:
422 // Check the new second entry (of 2)
423 doKey("down");
424 doKey("return");
425 checkACForm("testuser2", "testpass2");
427 // Trigger autocomplete popup
428 restoreForm();
429 doKey("down");
430 break;
432 case 56:
433 // Delete the only remaining entry, "testuser2"
434 doKey("down");
435 doKey("delete", shiftModifier);
436 //doKey("return");
437 checkACForm("", "");
438 numLogins = pwmgr.countLogins("http://localhost:8888", "http://autocomplete:8888", null);
439 is(numLogins, 0, "Correct number of logins after deleting one");
440 testNum = 99;
441 break;
444 /* Tests for single-user forms with autocomplete=off */
446 case 100:
447 // Turn our attention to form2
448 uname = $_(2, "uname");
449 pword = $_(2, "pword");
450 checkACForm("", "");
452 // Trigger autocomplete popup
453 restoreForm();
454 doKey("down");
455 break;
457 case 101:
458 // Check first entry
459 doKey("down");
460 checkACForm("", ""); // value shouldn't update
461 doKey("return"); // not "enter"!
462 checkACForm("singleuser5", "singlepass5");
463 break;
465 case 102:
466 // Turn our attention to form3
467 uname = $_(3, "uname");
468 pword = $_(3, "pword");
469 checkACForm("", "");
471 // Trigger autocomplete popup
472 restoreForm();
473 doKey("down");
474 break;
476 case 103:
477 // Check first entry
478 doKey("down");
479 checkACForm("", ""); // value shouldn't update
480 doKey("return"); // not "enter"!
481 checkACForm("singleuser5", "singlepass5");
482 break;
484 case 104:
485 // Turn our attention to form4
486 uname = $_(4, "uname");
487 pword = $_(4, "pword");
488 checkACForm("", "");
490 // Trigger autocomplete popup
491 restoreForm();
492 doKey("down");
493 break;
495 case 105:
496 // Check first entry
497 doKey("down");
498 checkACForm("", ""); // value shouldn't update
499 doKey("return"); // not "enter"!
500 checkACForm("singleuser5", "singlepass5");
501 break;
503 case 106:
504 // Turn our attention to form5
505 uname = $_(5, "uname");
506 pword = $_(5, "pword");
507 checkACForm("", "");
509 // Trigger autocomplete popup
510 restoreForm();
511 doKey("down");
512 break;
514 case 107:
515 // Check first entry
516 doKey("down");
517 checkACForm("", ""); // value shouldn't update
518 doKey("return"); // not "enter"!
519 checkACForm("singleuser5", "singlepass5");
520 break;
522 case 108:
523 // Turn our attention to form6
524 // (this is a control, w/o autocomplete=off, to ensure the login
525 // that was being suppressed would have been filled in otherwise)
526 uname = $_(6, "uname");
527 pword = $_(6, "pword");
528 checkACForm("singleuser5", "singlepass5");
530 pwmgr.removeLogin(login5);
531 testNum = 499;
532 break;
534 case 500:
535 // Turn our attention to form7
536 uname = $_(7, "uname");
537 pword = $_(7, "pword");
538 checkACForm("", "");
540 // Insert a new username field into the form. We'll then make sure
541 // that invoking the autocomplete doesn't try to fill the form.
542 var newField = document.createElement("input");
543 newField.setAttribute("type", "text");
544 newField.setAttribute("name", "uname2");
545 pword.parentNode.insertBefore(newField, pword);
546 is($_(7, "uname2").value, "", "Verifying empty uname2");;
548 // Delete login6B. It was created just to prevent filling in a login
549 // automatically, removing it makes it more likely that we'll catch a
550 // future regression with form filling here.
551 pwmgr.removeLogin(login6B);
553 // Trigger autocomplete popup
554 restoreForm();
555 doKey("down");
556 break;
558 case 501:
559 // Check first entry
560 doKey("down");
561 checkACForm("", ""); // value shouldn't update
562 doKey("return"); // not "enter"!
563 // The form changes, so we expect the old username field to get the
564 // selected autocomplete value, but neither the new username field nor
565 // the password field should have any values filled in.
566 checkACForm("form7user1", "");
567 is($_(7, "uname2").value, "", "Verifying empty uname2");;
569 pwmgr.removeLogin(login6A);
572 SimpleTest.finish();
573 return;
575 default:
576 ok(false, "Unexpected invocataion of test #" + testNum);
577 SimpleTest.finish();
578 return;
581 setTimeout(runTest, 50, testNum + 1); // XXX 40ms was too slow, why?
585 function startTest() {
586 runTest(1);
589 window.onload = startTest;
591 SimpleTest.waitForExplicitFinish();
592 </script>
593 </pre>
594 </body>
595 </html>