|
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="pwmgr_common.js"></script> |
|
7 <script type="text/javascript" src="prompt_common.js"></script> |
|
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
9 </head> |
|
10 <body> |
|
11 Login Manager test: master password. |
|
12 <script> |
|
13 "use strict"; |
|
14 |
|
15 commonInit(); |
|
16 SimpleTest.waitForExplicitFinish(); |
|
17 |
|
18 var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"] |
|
19 .getService(SpecialPowers.Ci.nsILoginManager); |
|
20 var pwcrypt = SpecialPowers.Cc["@mozilla.org/login-manager/crypto/SDR;1"] |
|
21 .getService(Ci.nsILoginManagerCrypto); |
|
22 |
|
23 var nsLoginInfo = new SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo); |
|
24 |
|
25 var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/"; |
|
26 var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/"; |
|
27 |
|
28 var login1 = new nsLoginInfo(); |
|
29 var login2 = new nsLoginInfo(); |
|
30 |
|
31 login1.init("http://example.com", "http://example.com", null, |
|
32 "user1", "pass1", "uname", "pword"); |
|
33 login2.init("http://example.org", "http://example.org", null, |
|
34 "user2", "pass2", "uname", "pword"); |
|
35 |
|
36 pwmgr.addLogin(login1); |
|
37 pwmgr.addLogin(login2); |
|
38 </script> |
|
39 |
|
40 <p id="display"></p> |
|
41 |
|
42 <div id="content" style="display: none"> |
|
43 <iframe id="iframe1"></iframe> |
|
44 <iframe id="iframe2"></iframe> |
|
45 </div> |
|
46 |
|
47 <pre id="test"> |
|
48 <script class="testbody" type="text/javascript"> |
|
49 var testNum = 1; |
|
50 var iframe1 = document.getElementById("iframe1"); |
|
51 var iframe2 = document.getElementById("iframe2"); |
|
52 |
|
53 /* |
|
54 * handleDialog |
|
55 * |
|
56 * Invoked a short period of time after calling startCallbackTimer(), and |
|
57 * allows testing the actual auth dialog while it's being displayed. Tests |
|
58 * should call startCallbackTimer() each time the auth dialog is expected (the |
|
59 * timer is a one-shot). |
|
60 */ |
|
61 function handleDialog(doc, testNum) { |
|
62 ok(true, "handleDialog running for test " + testNum); |
|
63 |
|
64 var clickOK = true; |
|
65 var doNothing = false; |
|
66 var passfield = doc.getElementById("password1Textbox"); |
|
67 var dialog = doc.getElementById("commonDialog"); |
|
68 |
|
69 switch(testNum) { |
|
70 case 1: |
|
71 is(passfield.getAttribute("value"), "", "Checking empty prompt"); |
|
72 passfield.setAttribute("value", masterPassword); |
|
73 is(passfield.getAttribute("value"), masterPassword, "Checking filled prompt"); |
|
74 break; |
|
75 |
|
76 case 2: |
|
77 clickOK = false; |
|
78 break; |
|
79 |
|
80 case 3: |
|
81 is(passfield.getAttribute("value"), "", "Checking empty prompt"); |
|
82 passfield.setAttribute("value", masterPassword); |
|
83 break; |
|
84 |
|
85 case 4: |
|
86 doNothing = true; |
|
87 break; |
|
88 |
|
89 case 5: |
|
90 is(passfield.getAttribute("value"), "", "Checking empty prompt"); |
|
91 passfield.setAttribute("value", masterPassword); |
|
92 break; |
|
93 |
|
94 default: |
|
95 ok(false, "Uhh, unhandled switch for testNum #" + testNum); |
|
96 break; |
|
97 } |
|
98 |
|
99 didDialog = true; |
|
100 |
|
101 if (!doNothing) { |
|
102 SpecialPowers.addObserver(outerWindowObserver, "outer-window-destroyed", false); |
|
103 if (clickOK) |
|
104 dialog.acceptDialog(); |
|
105 else |
|
106 dialog.cancelDialog(); |
|
107 } |
|
108 |
|
109 ok(true, "handleDialog done for test " + testNum); |
|
110 |
|
111 if (testNum == 4) |
|
112 checkTest4A(); |
|
113 } |
|
114 |
|
115 var outerWindowObserver = { |
|
116 observe: function(id) { |
|
117 SpecialPowers.removeObserver(outerWindowObserver, "outer-window-destroyed"); |
|
118 if (testNum == 1) |
|
119 startTest2(); |
|
120 else if (testNum == 2) |
|
121 startTest3(); |
|
122 else if (testNum == 3) |
|
123 checkTest3(); |
|
124 else if (testNum == 5) |
|
125 checkTest4C(); |
|
126 } |
|
127 }; |
|
128 |
|
129 |
|
130 function startTest1() { |
|
131 ok(pwcrypt.isLoggedIn, "should be initially logged in (no MP)"); |
|
132 enableMasterPassword(); |
|
133 ok(!pwcrypt.isLoggedIn, "should be logged out after setting MP"); |
|
134 |
|
135 // --- Test 1 --- |
|
136 // Trigger a MP prompt via the API |
|
137 startCallbackTimer(); |
|
138 var logins = pwmgr.getAllLogins(); |
|
139 ok(didDialog, "handleDialog was invoked"); |
|
140 is(logins.length, 3, "expected number of logins"); |
|
141 |
|
142 ok(pwcrypt.isLoggedIn, "should be logged in after MP prompt"); |
|
143 logoutMasterPassword(); |
|
144 ok(!pwcrypt.isLoggedIn, "should be logged out"); |
|
145 } |
|
146 |
|
147 function startTest2() { |
|
148 // Try again but click cancel. |
|
149 testNum++; |
|
150 startCallbackTimer(); |
|
151 var failedAsExpected = false; |
|
152 logins = null; |
|
153 try { |
|
154 logins = pwmgr.getAllLogins(); |
|
155 } catch (e) { failedAsExpected = true; } |
|
156 ok(didDialog, "handleDialog was invoked"); |
|
157 ok(failedAsExpected, "getAllLogins should have thrown"); |
|
158 is(logins, null, "shouldn't have gotten logins"); |
|
159 ok(!pwcrypt.isLoggedIn, "should still be logged out"); |
|
160 } |
|
161 |
|
162 function startTest3() { |
|
163 // Load a single iframe to trigger a MP |
|
164 testNum++; |
|
165 iframe1.src = exampleCom + "subtst_master_pass.html"; |
|
166 startCallbackTimer(); |
|
167 } |
|
168 |
|
169 function checkTest3() { |
|
170 ok(true, "checkTest3 starting"); |
|
171 ok(didDialog, "handleDialog was invoked"); |
|
172 |
|
173 // check contents of iframe1 fields |
|
174 var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield"); |
|
175 var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield"); |
|
176 is(u.value, "user1", "checking expected user to have been filled in"); |
|
177 is(p.value, "pass1", "checking expected pass to have been filled in"); |
|
178 |
|
179 ok(pwcrypt.isLoggedIn, "should be logged in"); |
|
180 logoutMasterPassword(); |
|
181 ok(!pwcrypt.isLoggedIn, "should be logged out"); |
|
182 |
|
183 |
|
184 // --- Test 4 --- |
|
185 // first part of loading 2 MP-triggering iframes |
|
186 testNum++; |
|
187 iframe1.src = exampleOrg + "subtst_master_pass.html"; |
|
188 // start the callback, but we'll not enter the MP, just call checkTest4A |
|
189 startCallbackTimer(); |
|
190 } |
|
191 |
|
192 function checkTest4A() { |
|
193 ok(true, "checkTest4A starting"); |
|
194 ok(didDialog, "handleDialog was invoked"); |
|
195 |
|
196 // check contents of iframe1 fields |
|
197 var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield"); |
|
198 var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield"); |
|
199 is(u.value, "", "checking expected empty user"); |
|
200 is(p.value, "", "checking expected empty pass"); |
|
201 |
|
202 |
|
203 ok(!pwcrypt.isLoggedIn, "should be logged out"); |
|
204 |
|
205 // XXX check that there's 1 MP window open |
|
206 |
|
207 // Load another iframe with a login form |
|
208 // This should detect that there's already a pending MP prompt, and not |
|
209 // put up a second one. The load event will fire (note that when pwmgr is |
|
210 // driven from DOMContentLoaded, if that blocks due to prompting for a MP, |
|
211 // the load even will also be blocked until the prompt is dismissed). |
|
212 iframe2.onload = checkTest4B; |
|
213 iframe2.src = exampleCom + "subtst_master_pass.html"; |
|
214 } |
|
215 |
|
216 function checkTest4B() { |
|
217 ok(true, "checkTest4B starting"); |
|
218 // iframe2 should load without having triggered a MP prompt (because one |
|
219 // is already waiting) |
|
220 |
|
221 // check contents of iframe2 fields |
|
222 var u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield"); |
|
223 var p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield"); |
|
224 is(u.value, "", "checking expected empty user"); |
|
225 is(p.value, "", "checking expected empty pass"); |
|
226 |
|
227 // XXX check that there's 1 MP window open |
|
228 ok(!pwcrypt.isLoggedIn, "should be logged out"); |
|
229 |
|
230 // Ok, now enter the MP. The MP prompt is already up, but we'll just reuse startCallBackTimer. |
|
231 // --- Test 5 --- |
|
232 testNum++; |
|
233 startCallbackTimer(); |
|
234 } |
|
235 |
|
236 function checkTest4C() { |
|
237 ok(true, "checkTest4C starting"); |
|
238 ok(didDialog, "handleDialog was invoked"); |
|
239 |
|
240 // We shouldn't have to worry about iframe1's load event racing with |
|
241 // filling of iframe2's data. We notify observers synchronously, so |
|
242 // iframe2's observer will process iframe2 before iframe1 even finishes |
|
243 // processing the form (which is blocking its load event). |
|
244 ok(pwcrypt.isLoggedIn, "should be logged in"); |
|
245 |
|
246 // check contents of iframe1 fields |
|
247 var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield"); |
|
248 var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield"); |
|
249 is(u.value, "user2", "checking expected user to have been filled in"); |
|
250 is(p.value, "pass2", "checking expected pass to have been filled in"); |
|
251 |
|
252 // check contents of iframe2 fields |
|
253 u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield"); |
|
254 p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield"); |
|
255 is(u.value, "user1", "checking expected user to have been filled in"); |
|
256 is(p.value, "pass1", "checking expected pass to have been filled in"); |
|
257 |
|
258 finishTest(); |
|
259 } |
|
260 |
|
261 // XXX do a test5ABC with clicking cancel? |
|
262 |
|
263 function finishTest() { |
|
264 disableMasterPassword(); |
|
265 ok(pwcrypt.isLoggedIn, "should be logged in"); |
|
266 |
|
267 pwmgr.removeLogin(login1); |
|
268 pwmgr.removeLogin(login2); |
|
269 SimpleTest.finish(); |
|
270 } |
|
271 |
|
272 window.onload = startTest1; |
|
273 </script> |
|
274 </pre> |
|
275 </body> |
|
276 </html> |
|
277 |