|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <head> |
|
4 <title>Test for Login Manager</title> |
|
5 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
6 <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> |
|
7 <script type="text/javascript" src="pwmgr_common.js"></script> |
|
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
9 </head> |
|
10 <body> |
|
11 Login Manager test: multiple login autocomplete |
|
12 |
|
13 <script> |
|
14 commonInit(); |
|
15 SimpleTest.waitForExplicitFinish(); |
|
16 |
|
17 // Get the pwmgr service |
|
18 var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"] |
|
19 .getService(SpecialPowers.Ci.nsILoginManager); |
|
20 ok(pwmgr != null, "nsLoginManager service"); |
|
21 |
|
22 // Create some logins just for this form, since we'll be deleting them. |
|
23 var nsLoginInfo = |
|
24 SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1", |
|
25 SpecialPowers.Ci.nsILoginInfo, "init"); |
|
26 ok(nsLoginInfo != null, "nsLoginInfo constructor"); |
|
27 |
|
28 |
|
29 // login0 has no username, so should be filtered out from the autocomplete list. |
|
30 var login0 = new nsLoginInfo( |
|
31 "http://mochi.test:8888", "http://autocomplete:8888", null, |
|
32 "", "user0pass", "", "pword"); |
|
33 |
|
34 var login1 = new nsLoginInfo( |
|
35 "http://mochi.test:8888", "http://autocomplete:8888", null, |
|
36 "tempuser1", "temppass1", "uname", "pword"); |
|
37 |
|
38 var login2 = new nsLoginInfo( |
|
39 "http://mochi.test:8888", "http://autocomplete:8888", null, |
|
40 "testuser2", "testpass2", "uname", "pword"); |
|
41 |
|
42 var login3 = new nsLoginInfo( |
|
43 "http://mochi.test:8888", "http://autocomplete:8888", null, |
|
44 "testuser3", "testpass3", "uname", "pword"); |
|
45 |
|
46 var login4 = new nsLoginInfo( |
|
47 "http://mochi.test:8888", "http://autocomplete:8888", null, |
|
48 "zzzuser4", "zzzpass4", "uname", "pword"); |
|
49 |
|
50 // login 5 only used in the single-user forms |
|
51 var login5 = new nsLoginInfo( |
|
52 "http://mochi.test:8888", "http://autocomplete2", null, |
|
53 "singleuser5", "singlepass5", "uname", "pword"); |
|
54 |
|
55 var login6A = new nsLoginInfo( |
|
56 "http://mochi.test:8888", "http://autocomplete3", null, |
|
57 "form7user1", "form7pass1", "uname", "pword"); |
|
58 var login6B = new nsLoginInfo( |
|
59 "http://mochi.test:8888", "http://autocomplete3", null, |
|
60 "form7user2", "form7pass2", "uname", "pword"); |
|
61 |
|
62 var login7 = new nsLoginInfo( |
|
63 "http://mochi.test:8888", "http://autocomplete4", null, |
|
64 "form8user", "form8pass", "uname", "pword"); |
|
65 |
|
66 var login8A = new nsLoginInfo( |
|
67 "http://mochi.test:8888", "http://autocomplete5", null, |
|
68 "form9userAB", "form9pass", "uname", "pword"); |
|
69 |
|
70 var login8B = new nsLoginInfo( |
|
71 "http://mochi.test:8888", "http://autocomplete5", null, |
|
72 "form9userAAB", "form9pass", "uname", "pword"); |
|
73 |
|
74 // login8C is added later |
|
75 var login8C = new nsLoginInfo( |
|
76 "http://mochi.test:8888", "http://autocomplete5", null, |
|
77 "form9userAABz", "form9pass", "uname", "pword"); |
|
78 // try/catch in case someone runs the tests manually, twice. |
|
79 try { |
|
80 pwmgr.addLogin(login0); |
|
81 pwmgr.addLogin(login1); |
|
82 pwmgr.addLogin(login2); |
|
83 pwmgr.addLogin(login3); |
|
84 pwmgr.addLogin(login4); |
|
85 pwmgr.addLogin(login5); |
|
86 pwmgr.addLogin(login6A); |
|
87 pwmgr.addLogin(login6B); |
|
88 pwmgr.addLogin(login7); |
|
89 pwmgr.addLogin(login8A); |
|
90 pwmgr.addLogin(login8B); |
|
91 } catch (e) { |
|
92 ok(false, "addLogin threw: " + e); |
|
93 } |
|
94 |
|
95 </script> |
|
96 <p id="display"></p> |
|
97 |
|
98 <!-- we presumably can't hide the content for this test. --> |
|
99 <div id="content"> |
|
100 |
|
101 <!-- form1 tests multiple matching logins --> |
|
102 <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> |
|
103 <input type="text" name="uname"> |
|
104 <input type="password" name="pword"> |
|
105 <button type="submit">Submit</button> |
|
106 </form> |
|
107 |
|
108 <!-- other forms test single logins, with autocomplete=off set --> |
|
109 <form id="form2" action="http://autocomplete2" onsubmit="return false;"> |
|
110 <input type="text" name="uname"> |
|
111 <input type="password" name="pword" autocomplete="off"> |
|
112 <button type="submit">Submit</button> |
|
113 </form> |
|
114 |
|
115 <form id="form3" action="http://autocomplete2" onsubmit="return false;"> |
|
116 <input type="text" name="uname" autocomplete="off"> |
|
117 <input type="password" name="pword"> |
|
118 <button type="submit">Submit</button> |
|
119 </form> |
|
120 |
|
121 <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off"> |
|
122 <input type="text" name="uname"> |
|
123 <input type="password" name="pword"> |
|
124 <button type="submit">Submit</button> |
|
125 </form> |
|
126 |
|
127 <form id="form5" action="http://autocomplete2" onsubmit="return false;"> |
|
128 <input type="text" name="uname" autocomplete="off"> |
|
129 <input type="password" name="pword" autocomplete="off"> |
|
130 <button type="submit">Submit</button> |
|
131 </form> |
|
132 |
|
133 <!-- control --> |
|
134 <form id="form6" action="http://autocomplete2" onsubmit="return false;"> |
|
135 <input type="text" name="uname"> |
|
136 <input type="password" name="pword"> |
|
137 <button type="submit">Submit</button> |
|
138 </form> |
|
139 |
|
140 <!-- This form will be manipulated to insert a different username field. --> |
|
141 <form id="form7" action="http://autocomplete3" onsubmit="return false;"> |
|
142 <input type="text" name="uname"> |
|
143 <input type="password" name="pword"> |
|
144 <button type="submit">Submit</button> |
|
145 </form> |
|
146 |
|
147 <!-- test for no autofill after onblur with blank username --> |
|
148 <form id="form8" action="http://autocomplete4" onsubmit="return false;"> |
|
149 <input type="text" name="uname"> |
|
150 <input type="password" name="pword"> |
|
151 <button type="submit">Submit</button> |
|
152 </form> |
|
153 |
|
154 <!-- test autocomplete dropdown --> |
|
155 <form id="form9" action="http://autocomplete5" onsubmit="return false;"> |
|
156 <input type="text" name="uname"> |
|
157 <input type="password" name="pword"> |
|
158 <button type="submit">Submit</button> |
|
159 </form> |
|
160 </div> |
|
161 |
|
162 <pre id="test"> |
|
163 <script class="testbody" type="text/javascript"> |
|
164 |
|
165 /** Test for Login Manager: multiple login autocomplete. **/ |
|
166 |
|
167 |
|
168 var uname = $_(1, "uname"); |
|
169 var pword = $_(1, "pword"); |
|
170 const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; |
|
171 |
|
172 // Restore the form to the default state. |
|
173 function restoreForm() { |
|
174 uname.value = ""; |
|
175 pword.value = ""; |
|
176 uname.focus(); |
|
177 } |
|
178 |
|
179 |
|
180 // Check for expected username/password in form. |
|
181 function checkACForm(expectedUsername, expectedPassword) { |
|
182 var formID = uname.parentNode.id; |
|
183 is(uname.value, expectedUsername, "Checking " + formID + " username"); |
|
184 is(pword.value, expectedPassword, "Checking " + formID + " password"); |
|
185 } |
|
186 |
|
187 |
|
188 function sendFakeAutocompleteEvent(element) { |
|
189 var acEvent = document.createEvent("HTMLEvents"); |
|
190 acEvent.initEvent("DOMAutoComplete", true, false); |
|
191 element.dispatchEvent(acEvent); |
|
192 } |
|
193 |
|
194 function hitEventLoop(func, times) { |
|
195 if (times > 0) { |
|
196 setTimeout(hitEventLoop, 0, func, times - 1); |
|
197 } else { |
|
198 setTimeout(func, 0); |
|
199 } |
|
200 } |
|
201 |
|
202 var gNextTestWillOpenPopup = true; |
|
203 var gLastTest = 704; |
|
204 |
|
205 function addPopupListener(eventName, func, capture) { |
|
206 autocompletePopup.addEventListener(eventName, func, capture); |
|
207 } |
|
208 |
|
209 function removePopupListener(eventName, func, capture) { |
|
210 autocompletePopup.removeEventListener(eventName, func, capture); |
|
211 } |
|
212 |
|
213 /* |
|
214 * Main section of test... |
|
215 * |
|
216 * This is a bit hacky, because the events are either being sent or |
|
217 * processes asynchronously, so we need to interrupt our flow with lots of |
|
218 * setTimeout() calls. The case statements are executed in order, one per |
|
219 * timeout. |
|
220 */ |
|
221 function runTest(testNum) { |
|
222 ok(true, "Starting test #" + testNum); |
|
223 |
|
224 if (gNextTestWillOpenPopup) { |
|
225 addPopupListener("popupshown", function() { |
|
226 removePopupListener("popupshown", arguments.callee, false); |
|
227 |
|
228 if (testNum != gLastTest) { |
|
229 window.setTimeout(runTest, 0, testNum + 1); |
|
230 } |
|
231 }, false); |
|
232 } else { |
|
233 var unexpectedPopup = function() { |
|
234 removePopupListener("popupshown", arguments.callee, false); |
|
235 |
|
236 ok(false, "Test " + testNum + " should not show a popup"); |
|
237 }; |
|
238 addPopupListener("popupshown", unexpectedPopup, false); |
|
239 if (testNum == gLastTest) { |
|
240 removePopupListener("popupshown", unexpectedPopup, false); |
|
241 } else { |
|
242 hitEventLoop(function() { |
|
243 removePopupListener("popupshown", unexpectedPopup, false); |
|
244 runTest(testNum + 1); |
|
245 }, 100); |
|
246 } |
|
247 } |
|
248 |
|
249 switch(testNum) { |
|
250 case 1: |
|
251 // Make sure initial form is empty. |
|
252 checkACForm("", ""); |
|
253 // Trigger autocomplete popup |
|
254 restoreForm(); |
|
255 doKey("down"); |
|
256 break; |
|
257 |
|
258 case 2: |
|
259 // Check first entry |
|
260 doKey("down"); |
|
261 checkACForm("", ""); // value shouldn't update |
|
262 doKey("return"); // not "enter"! |
|
263 checkACForm("tempuser1", "temppass1"); |
|
264 |
|
265 // Trigger autocomplete popup |
|
266 restoreForm(); |
|
267 doKey("down"); |
|
268 break; |
|
269 |
|
270 case 3: |
|
271 // Check second entry |
|
272 doKey("down"); |
|
273 doKey("down"); |
|
274 doKey("return"); // not "enter"! |
|
275 checkACForm("testuser2", "testpass2"); |
|
276 |
|
277 // Trigger autocomplete popup |
|
278 restoreForm(); |
|
279 doKey("down"); |
|
280 break; |
|
281 |
|
282 case 4: |
|
283 // Check third entry |
|
284 doKey("down"); |
|
285 doKey("down"); |
|
286 doKey("down"); |
|
287 doKey("return"); |
|
288 checkACForm("testuser3", "testpass3"); |
|
289 |
|
290 // Trigger autocomplete popup |
|
291 restoreForm(); |
|
292 doKey("down"); |
|
293 break; |
|
294 |
|
295 case 5: |
|
296 // Check fourth entry |
|
297 doKey("down"); |
|
298 doKey("down"); |
|
299 doKey("down"); |
|
300 doKey("down"); |
|
301 doKey("return"); |
|
302 checkACForm("zzzuser4", "zzzpass4"); |
|
303 |
|
304 // Trigger autocomplete popup |
|
305 restoreForm(); |
|
306 doKey("down"); |
|
307 break; |
|
308 |
|
309 case 6: |
|
310 // Check first entry (wraparound) |
|
311 doKey("down"); |
|
312 doKey("down"); |
|
313 doKey("down"); |
|
314 doKey("down"); |
|
315 doKey("down"); // deselects |
|
316 doKey("down"); |
|
317 doKey("return"); |
|
318 checkACForm("tempuser1", "temppass1"); |
|
319 |
|
320 // Trigger autocomplete popup |
|
321 restoreForm(); |
|
322 doKey("down"); |
|
323 break; |
|
324 |
|
325 case 7: |
|
326 // Check the last entry via arrow-up |
|
327 doKey("up"); |
|
328 doKey("return"); |
|
329 checkACForm("zzzuser4", "zzzpass4"); |
|
330 |
|
331 // Trigger autocomplete popup |
|
332 restoreForm(); |
|
333 doKey("down"); |
|
334 break; |
|
335 |
|
336 case 8: |
|
337 // Check the last entry via arrow-up |
|
338 doKey("down"); // select first entry |
|
339 doKey("up"); // selects nothing! |
|
340 doKey("up"); // select last entry |
|
341 doKey("return"); |
|
342 checkACForm("zzzuser4", "zzzpass4"); |
|
343 |
|
344 // Trigger autocomplete popup |
|
345 restoreForm(); |
|
346 doKey("down"); |
|
347 break; |
|
348 |
|
349 case 9: |
|
350 // Check the last entry via arrow-up (wraparound) |
|
351 doKey("down"); |
|
352 doKey("up"); // deselects |
|
353 doKey("up"); // last entry |
|
354 doKey("up"); |
|
355 doKey("up"); |
|
356 doKey("up"); // first entry |
|
357 doKey("up"); // deselects |
|
358 doKey("up"); // last entry |
|
359 doKey("return"); |
|
360 checkACForm("zzzuser4", "zzzpass4"); |
|
361 |
|
362 // Trigger autocomplete popup |
|
363 restoreForm(); |
|
364 doKey("down"); |
|
365 break; |
|
366 |
|
367 case 10: |
|
368 // Set first entry w/o triggering autocomplete |
|
369 doKey("down"); |
|
370 doKey("right"); |
|
371 checkACForm("tempuser1", ""); // empty password |
|
372 |
|
373 // Trigger autocomplete popup |
|
374 restoreForm(); |
|
375 doKey("down"); |
|
376 break; |
|
377 |
|
378 case 11: |
|
379 // Set first entry w/o triggering autocomplete |
|
380 doKey("down"); |
|
381 doKey("left"); |
|
382 checkACForm("tempuser1", ""); // empty password |
|
383 |
|
384 // Trigger autocomplete popup |
|
385 restoreForm(); |
|
386 doKey("down"); |
|
387 break; |
|
388 |
|
389 case 12: |
|
390 // Check first entry (page up) |
|
391 doKey("down"); |
|
392 doKey("down"); |
|
393 doKey("page_up"); |
|
394 doKey("return"); |
|
395 checkACForm("tempuser1", "temppass1"); |
|
396 |
|
397 // Trigger autocomplete popup |
|
398 restoreForm(); |
|
399 doKey("down"); |
|
400 gNextTestWillOpenPopup = false; |
|
401 break; |
|
402 |
|
403 case 13: |
|
404 // Check last entry (page down) |
|
405 doKey("down"); |
|
406 doKey("page_down"); |
|
407 doKey("return"); |
|
408 checkACForm("zzzuser4", "zzzpass4"); |
|
409 restoreForm(); |
|
410 gNextTestWillOpenPopup = false; |
|
411 break; |
|
412 |
|
413 case 14: |
|
414 // Send a fake (untrusted) event. |
|
415 checkACForm("", ""); |
|
416 uname.value = "zzzuser4"; |
|
417 sendFakeAutocompleteEvent(uname); |
|
418 checkACForm("zzzuser4", ""); |
|
419 gNextTestWillOpenPopup = true; |
|
420 break; |
|
421 |
|
422 case 15: |
|
423 //checkACForm("zzzuser4", ""); |
|
424 |
|
425 // Trigger autocomplete popup |
|
426 restoreForm(); |
|
427 doKey("down"); |
|
428 testNum = 49; |
|
429 break; |
|
430 |
|
431 // XXX tried sending character "t" before/during dropdown to test |
|
432 // filtering, but had no luck. Seemed like the character was getting lost. |
|
433 // Setting uname.value didn't seem to work either. This works with a human |
|
434 // driver, so I'm not sure what's up. |
|
435 |
|
436 |
|
437 case 50: |
|
438 // Delete the first entry (of 4), "tempuser1" |
|
439 doKey("down"); |
|
440 var numLogins; |
|
441 numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); |
|
442 is(numLogins, 5, "Correct number of logins before deleting one"); |
|
443 |
|
444 // On OS X, shift-backspace and shift-delete work, just delete does not. |
|
445 // On Win/Linux, shift-backspace does not work, delete and shift-delete do. |
|
446 doKey("delete", shiftModifier); |
|
447 |
|
448 checkACForm("", ""); |
|
449 numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); |
|
450 is(numLogins, 4, "Correct number of logins after deleting one"); |
|
451 doKey("return"); |
|
452 checkACForm("testuser2", "testpass2"); |
|
453 |
|
454 // Trigger autocomplete popup |
|
455 restoreForm(); |
|
456 doKey("down"); |
|
457 break; |
|
458 |
|
459 case 51: |
|
460 // Check the new first entry (of 3) |
|
461 doKey("down"); |
|
462 doKey("return"); |
|
463 checkACForm("testuser2", "testpass2"); |
|
464 |
|
465 // Trigger autocomplete popup |
|
466 restoreForm(); |
|
467 doKey("down"); |
|
468 break; |
|
469 |
|
470 case 52: |
|
471 // Delete the second entry (of 3), "testuser3" |
|
472 doKey("down"); |
|
473 doKey("down"); |
|
474 doKey("delete", shiftModifier); |
|
475 checkACForm("", ""); |
|
476 numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); |
|
477 is(numLogins, 3, "Correct number of logins after deleting one"); |
|
478 doKey("return"); |
|
479 checkACForm("zzzuser4", "zzzpass4"); |
|
480 |
|
481 // Trigger autocomplete popup |
|
482 restoreForm(); |
|
483 doKey("down"); |
|
484 break; |
|
485 |
|
486 case 53: |
|
487 // Check the new second entry (of 2) |
|
488 doKey("down"); |
|
489 doKey("return"); |
|
490 checkACForm("testuser2", "testpass2"); |
|
491 |
|
492 // Trigger autocomplete popup |
|
493 restoreForm(); |
|
494 doKey("down"); |
|
495 break; |
|
496 |
|
497 case 54: |
|
498 // Delete the last entry (of 2), "zzzuser4" |
|
499 doKey("down"); |
|
500 doKey("down"); |
|
501 doKey("delete", shiftModifier); |
|
502 checkACForm("", ""); |
|
503 numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); |
|
504 is(numLogins, 2, "Correct number of logins after deleting one"); |
|
505 doKey("return"); |
|
506 checkACForm("testuser2", "testpass2"); |
|
507 |
|
508 // Trigger autocomplete popup |
|
509 restoreForm(); |
|
510 doKey("down"); |
|
511 break; |
|
512 |
|
513 case 55: |
|
514 // Check the new second entry (of 2) |
|
515 doKey("down"); |
|
516 doKey("return"); |
|
517 checkACForm("testuser2", "testpass2"); |
|
518 |
|
519 // Trigger autocomplete popup |
|
520 restoreForm(); |
|
521 doKey("down"); |
|
522 gNextTestWillOpenPopup = false; |
|
523 break; |
|
524 |
|
525 case 56: |
|
526 // Delete the only remaining entry, "testuser2" |
|
527 doKey("down"); |
|
528 doKey("delete", shiftModifier); |
|
529 //doKey("return"); |
|
530 checkACForm("", ""); |
|
531 numLogins = pwmgr.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); |
|
532 is(numLogins, 1, "Correct number of logins after deleting one"); |
|
533 pwmgr.removeLogin(login0); // remove the login that's not shown in the list. |
|
534 testNum = 99; |
|
535 gNextTestWillOpenPopup = true; |
|
536 break; |
|
537 |
|
538 |
|
539 /* Tests for single-user forms with autocomplete=off */ |
|
540 |
|
541 case 100: |
|
542 // Turn our attention to form2 |
|
543 uname = $_(2, "uname"); |
|
544 pword = $_(2, "pword"); |
|
545 checkACForm("", ""); |
|
546 |
|
547 // Trigger autocomplete popup |
|
548 restoreForm(); |
|
549 doKey("down"); |
|
550 gNextTestWillOpenPopup = false; |
|
551 break; |
|
552 |
|
553 case 101: |
|
554 // Check first entry |
|
555 doKey("down"); |
|
556 checkACForm("", ""); // value shouldn't update |
|
557 doKey("return"); // not "enter"! |
|
558 checkACForm("singleuser5", "singlepass5"); |
|
559 restoreForm(); // clear field, so reloading test doesn't fail |
|
560 gNextTestWillOpenPopup = true; |
|
561 break; |
|
562 |
|
563 case 102: |
|
564 // Turn our attention to form3 |
|
565 uname = $_(3, "uname"); |
|
566 pword = $_(3, "pword"); |
|
567 checkACForm("", ""); |
|
568 |
|
569 // Trigger autocomplete popup |
|
570 restoreForm(); |
|
571 doKey("down"); |
|
572 gNextTestWillOpenPopup = false; |
|
573 break; |
|
574 |
|
575 case 103: |
|
576 // Check first entry |
|
577 doKey("down"); |
|
578 checkACForm("", ""); // value shouldn't update |
|
579 doKey("return"); // not "enter"! |
|
580 checkACForm("singleuser5", "singlepass5"); |
|
581 gNextTestWillOpenPopup = true; |
|
582 break; |
|
583 |
|
584 case 104: |
|
585 // Turn our attention to form4 |
|
586 uname = $_(4, "uname"); |
|
587 pword = $_(4, "pword"); |
|
588 checkACForm("", ""); |
|
589 |
|
590 // Trigger autocomplete popup |
|
591 restoreForm(); |
|
592 doKey("down"); |
|
593 gNextTestWillOpenPopup = false; |
|
594 break; |
|
595 |
|
596 case 105: |
|
597 // Check first entry |
|
598 doKey("down"); |
|
599 checkACForm("", ""); // value shouldn't update |
|
600 doKey("return"); // not "enter"! |
|
601 checkACForm("singleuser5", "singlepass5"); |
|
602 gNextTestWillOpenPopup = true; |
|
603 break; |
|
604 |
|
605 case 106: |
|
606 // Turn our attention to form5 |
|
607 uname = $_(5, "uname"); |
|
608 pword = $_(5, "pword"); |
|
609 checkACForm("", ""); |
|
610 |
|
611 // Trigger autocomplete popup |
|
612 restoreForm(); |
|
613 doKey("down"); |
|
614 gNextTestWillOpenPopup = false; |
|
615 break; |
|
616 |
|
617 case 107: |
|
618 // Check first entry |
|
619 doKey("down"); |
|
620 checkACForm("", ""); // value shouldn't update |
|
621 doKey("return"); // not "enter"! |
|
622 checkACForm("singleuser5", "singlepass5"); |
|
623 gNextTestWillOpenPopup = false; |
|
624 break; |
|
625 |
|
626 case 108: |
|
627 // Turn our attention to form6 |
|
628 // (this is a control, w/o autocomplete=off, to ensure the login |
|
629 // that was being suppressed would have been filled in otherwise) |
|
630 uname = $_(6, "uname"); |
|
631 pword = $_(6, "pword"); |
|
632 checkACForm("singleuser5", "singlepass5"); |
|
633 gNextTestWillOpenPopup = false; |
|
634 break; |
|
635 |
|
636 case 109: |
|
637 // Test that the password field remains filled in after changing |
|
638 // the username. |
|
639 uname.focus(); |
|
640 doKey("right"); |
|
641 sendChar("X"); |
|
642 // Trigger the 'blur' event on uname |
|
643 pword.focus(); |
|
644 checkACForm("sXingleuser5", "singlepass5"); |
|
645 |
|
646 pwmgr.removeLogin(login5); |
|
647 testNum = 499; |
|
648 gNextTestWillOpenPopup = true; |
|
649 break; |
|
650 |
|
651 case 500: |
|
652 // Turn our attention to form7 |
|
653 uname = $_(7, "uname"); |
|
654 pword = $_(7, "pword"); |
|
655 checkACForm("", ""); |
|
656 |
|
657 // Insert a new username field into the form. We'll then make sure |
|
658 // that invoking the autocomplete doesn't try to fill the form. |
|
659 var newField = document.createElement("input"); |
|
660 newField.setAttribute("type", "text"); |
|
661 newField.setAttribute("name", "uname2"); |
|
662 pword.parentNode.insertBefore(newField, pword); |
|
663 is($_(7, "uname2").value, "", "Verifying empty uname2");; |
|
664 |
|
665 // Delete login6B. It was created just to prevent filling in a login |
|
666 // automatically, removing it makes it more likely that we'll catch a |
|
667 // future regression with form filling here. |
|
668 pwmgr.removeLogin(login6B); |
|
669 |
|
670 // Trigger autocomplete popup |
|
671 restoreForm(); |
|
672 doKey("down"); |
|
673 gNextTestWillOpenPopup = false; |
|
674 break; |
|
675 |
|
676 case 501: |
|
677 // Check first entry |
|
678 doKey("down"); |
|
679 checkACForm("", ""); // value shouldn't update |
|
680 doKey("return"); // not "enter"! |
|
681 // The form changes, so we expect the old username field to get the |
|
682 // selected autocomplete value, but neither the new username field nor |
|
683 // the password field should have any values filled in. |
|
684 checkACForm("form7user1", ""); |
|
685 is($_(7, "uname2").value, "", "Verifying empty uname2");; |
|
686 restoreForm(); // clear field, so reloading test doesn't fail |
|
687 |
|
688 pwmgr.removeLogin(login6A); |
|
689 testNum = 599; |
|
690 gNextTestWillOpenPopup = false; |
|
691 break; |
|
692 |
|
693 case 600: |
|
694 // Turn our attention to form8 |
|
695 uname = $_(8, "uname"); |
|
696 pword = $_(8, "pword"); |
|
697 checkACForm("form8user", "form8pass"); |
|
698 restoreForm(); |
|
699 gNextTestWillOpenPopup = false; |
|
700 break; |
|
701 |
|
702 case 601: |
|
703 checkACForm("", ""); |
|
704 // Focus the previous form to trigger a blur. |
|
705 $_(7, "uname").focus(); |
|
706 gNextTestWillOpenPopup = false; |
|
707 break; |
|
708 |
|
709 case 602: |
|
710 checkACForm("", ""); |
|
711 restoreForm(); |
|
712 gNextTestWillOpenPopup = false; |
|
713 break; |
|
714 |
|
715 case 603: |
|
716 checkACForm("", ""); |
|
717 pwmgr.removeLogin(login7); |
|
718 |
|
719 testNum = 699; |
|
720 gNextTestWillOpenPopup = true; |
|
721 break; |
|
722 |
|
723 case 700: |
|
724 // Turn our attention to form9 to test the dropdown - bug 497541 |
|
725 uname = $_(9, "uname"); |
|
726 pword = $_(9, "pword"); |
|
727 uname.focus(); |
|
728 sendString("form9userAB"); |
|
729 gNextTestWillOpenPopup = true; |
|
730 break; |
|
731 |
|
732 case 701: |
|
733 checkACForm("form9userAB", ""); |
|
734 uname.focus(); |
|
735 doKey("left"); |
|
736 sendChar("A"); |
|
737 gNextTestWillOpenPopup = false; |
|
738 break; |
|
739 |
|
740 case 702: |
|
741 // check dropdown is updated after inserting "A" |
|
742 checkACForm("form9userAAB", ""); |
|
743 checkMenuEntries(["form9userAAB"]); |
|
744 doKey("down"); |
|
745 doKey("return"); |
|
746 checkACForm("form9userAAB", "form9pass"); |
|
747 gNextTestWillOpenPopup = false; |
|
748 break; |
|
749 |
|
750 case 703: |
|
751 pwmgr.addLogin(login8C); |
|
752 uname.focus(); |
|
753 sendChar("z"); |
|
754 gNextTestWillOpenPopup = false; |
|
755 break; |
|
756 |
|
757 case 704: |
|
758 // check that empty results are cached - bug 496466 |
|
759 checkMenuEntries([]); |
|
760 |
|
761 SimpleTest.finish(); |
|
762 return; |
|
763 |
|
764 default: |
|
765 ok(false, "Unexpected invocation of test #" + testNum); |
|
766 SimpleTest.finish(); |
|
767 return; |
|
768 } |
|
769 } |
|
770 |
|
771 |
|
772 function checkMenuEntries(expectedValues) { |
|
773 var actualValues = getMenuEntries(); |
|
774 is(actualValues.length, expectedValues.length, "Checking length of expected menu"); |
|
775 for (var i = 0; i < expectedValues.length; i++) |
|
776 is(actualValues[i], expectedValues[i], "Checking menu entry #"+i); |
|
777 } |
|
778 |
|
779 var autocompletePopup; |
|
780 function getMenuEntries() { |
|
781 var entries = []; |
|
782 |
|
783 // Could perhaps pull values directly from the controller, but it seems |
|
784 // more reliable to test the values that are actually in the tree? |
|
785 var column = autocompletePopup.tree.columns[0]; |
|
786 var numRows = autocompletePopup.tree.view.rowCount; |
|
787 for (var i = 0; i < numRows; i++) { |
|
788 entries.push(autocompletePopup.tree.view.getValueAt(i, column)); |
|
789 } |
|
790 return entries; |
|
791 } |
|
792 |
|
793 function startTest() { |
|
794 var Ci = SpecialPowers.Ci; |
|
795 chromeWin = SpecialPowers.wrap(window) |
|
796 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
797 .getInterface(Ci.nsIWebNavigation) |
|
798 .QueryInterface(Ci.nsIDocShellTreeItem) |
|
799 .rootTreeItem |
|
800 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
801 .getInterface(Ci.nsIDOMWindow) |
|
802 .QueryInterface(Ci.nsIDOMChromeWindow); |
|
803 // shouldn't reach into browser internals like this and |
|
804 // shouldn't assume ID is consistent across products |
|
805 autocompletePopup = chromeWin.document.getElementById("PopupAutoComplete"); |
|
806 ok(autocompletePopup, "Got autocomplete popup"); |
|
807 runTest(1); |
|
808 } |
|
809 |
|
810 window.onload = startTest; |
|
811 </script> |
|
812 </pre> |
|
813 </body> |
|
814 </html> |
|
815 |