|
1 var gInvalidFormPopup = document.getElementById('invalid-form-popup'); |
|
2 ok(gInvalidFormPopup, |
|
3 "The browser should have a popup to show when a form is invalid"); |
|
4 |
|
5 function checkPopupShow() |
|
6 { |
|
7 ok(gInvalidFormPopup.state == 'showing' || gInvalidFormPopup.state == 'open', |
|
8 "[Test " + testId + "] The invalid form popup should be shown"); |
|
9 } |
|
10 |
|
11 function checkPopupHide() |
|
12 { |
|
13 ok(gInvalidFormPopup.state != 'showing' && gInvalidFormPopup.state != 'open', |
|
14 "[Test " + testId + "] The invalid form popup should not be shown"); |
|
15 } |
|
16 |
|
17 function checkPopupMessage(doc) |
|
18 { |
|
19 is(gInvalidFormPopup.firstChild.textContent, |
|
20 doc.getElementById('i').validationMessage, |
|
21 "[Test " + testId + "] The panel should show the message from validationMessage"); |
|
22 } |
|
23 |
|
24 let gObserver = { |
|
25 QueryInterface : XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver]), |
|
26 |
|
27 notifyInvalidSubmit : function (aFormElement, aInvalidElements) |
|
28 { |
|
29 } |
|
30 }; |
|
31 |
|
32 var testId = -1; |
|
33 |
|
34 function nextTest() |
|
35 { |
|
36 testId++; |
|
37 if (testId >= tests.length) { |
|
38 finish(); |
|
39 return; |
|
40 } |
|
41 executeSoon(tests[testId]); |
|
42 } |
|
43 |
|
44 function test() |
|
45 { |
|
46 waitForExplicitFinish(); |
|
47 waitForFocus(nextTest); |
|
48 } |
|
49 |
|
50 var tests = [ |
|
51 |
|
52 /** |
|
53 * In this test, we check that no popup appears if the form is valid. |
|
54 */ |
|
55 function() |
|
56 { |
|
57 let uri = "data:text/html,<html><body><iframe name='t'></iframe><form target='t' action='data:text/html,'><input><input id='s' type='submit'></form></body></html>"; |
|
58 let tab = gBrowser.addTab(); |
|
59 |
|
60 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
61 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
62 let doc = gBrowser.contentDocument; |
|
63 |
|
64 doc.getElementById('s').click(); |
|
65 |
|
66 executeSoon(function() { |
|
67 checkPopupHide(); |
|
68 |
|
69 // Clean-up |
|
70 gBrowser.removeTab(gBrowser.selectedTab); |
|
71 nextTest(); |
|
72 }); |
|
73 }, true); |
|
74 |
|
75 gBrowser.selectedTab = tab; |
|
76 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
77 }, |
|
78 |
|
79 /** |
|
80 * In this test, we check that, when an invalid form is submitted, |
|
81 * the invalid element is focused and a popup appears. |
|
82 */ |
|
83 function() |
|
84 { |
|
85 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input required id='i'><input id='s' type='submit'></form>"; |
|
86 let tab = gBrowser.addTab(); |
|
87 |
|
88 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
89 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
90 |
|
91 let doc = gBrowser.contentDocument; |
|
92 is(doc.activeElement, doc.getElementById('i'), |
|
93 "First invalid element should be focused"); |
|
94 |
|
95 checkPopupShow(); |
|
96 checkPopupMessage(doc); |
|
97 |
|
98 // Clean-up and next test. |
|
99 gBrowser.removeTab(gBrowser.selectedTab); |
|
100 nextTest(); |
|
101 }, false); |
|
102 |
|
103 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
104 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
105 |
|
106 gBrowser.contentDocument.getElementById('s').click(); |
|
107 }, true); |
|
108 |
|
109 gBrowser.selectedTab = tab; |
|
110 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
111 }, |
|
112 |
|
113 /** |
|
114 * In this test, we check that, when an invalid form is submitted, |
|
115 * the first invalid element is focused and a popup appears. |
|
116 */ |
|
117 function() |
|
118 { |
|
119 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input><input id='i' required><input required><input id='s' type='submit'></form>"; |
|
120 let tab = gBrowser.addTab(); |
|
121 |
|
122 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
123 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
124 |
|
125 let doc = gBrowser.contentDocument; |
|
126 is(doc.activeElement, doc.getElementById('i'), |
|
127 "First invalid element should be focused"); |
|
128 |
|
129 checkPopupShow(); |
|
130 checkPopupMessage(doc); |
|
131 |
|
132 // Clean-up and next test. |
|
133 gBrowser.removeTab(gBrowser.selectedTab); |
|
134 nextTest(); |
|
135 }, false); |
|
136 |
|
137 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
138 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
139 |
|
140 gBrowser.contentDocument.getElementById('s').click(); |
|
141 }, true); |
|
142 |
|
143 gBrowser.selectedTab = tab; |
|
144 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
145 }, |
|
146 |
|
147 /** |
|
148 * In this test, we check that, we hide the popup by interacting with the |
|
149 * invalid element if the element becomes valid. |
|
150 */ |
|
151 function() |
|
152 { |
|
153 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>"; |
|
154 let tab = gBrowser.addTab(); |
|
155 |
|
156 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
157 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
158 |
|
159 let doc = gBrowser.contentDocument; |
|
160 is(doc.activeElement, doc.getElementById('i'), |
|
161 "First invalid element should be focused"); |
|
162 |
|
163 checkPopupShow(); |
|
164 checkPopupMessage(doc); |
|
165 |
|
166 EventUtils.synthesizeKey("a", {}); |
|
167 |
|
168 executeSoon(function () { |
|
169 checkPopupHide(); |
|
170 |
|
171 // Clean-up and next test. |
|
172 gBrowser.removeTab(gBrowser.selectedTab); |
|
173 nextTest(); |
|
174 }); |
|
175 }, false); |
|
176 |
|
177 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
178 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
179 |
|
180 gBrowser.contentDocument.getElementById('s').click(); |
|
181 }, true); |
|
182 |
|
183 gBrowser.selectedTab = tab; |
|
184 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
185 }, |
|
186 |
|
187 /** |
|
188 * In this test, we check that, we don't hide the popup by interacting with the |
|
189 * invalid element if the element is still invalid. |
|
190 */ |
|
191 function() |
|
192 { |
|
193 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input type='email' id='i' required><input id='s' type='submit'></form>"; |
|
194 let tab = gBrowser.addTab(); |
|
195 |
|
196 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
197 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
198 |
|
199 let doc = gBrowser.contentDocument; |
|
200 is(doc.activeElement, doc.getElementById('i'), |
|
201 "First invalid element should be focused"); |
|
202 |
|
203 checkPopupShow(); |
|
204 checkPopupMessage(doc); |
|
205 |
|
206 EventUtils.synthesizeKey("a", {}); |
|
207 |
|
208 executeSoon(function () { |
|
209 checkPopupShow(); |
|
210 |
|
211 // Clean-up and next test. |
|
212 gBrowser.removeTab(gBrowser.selectedTab); |
|
213 nextTest(); |
|
214 }); |
|
215 }, false); |
|
216 |
|
217 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
218 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
219 |
|
220 gBrowser.contentDocument.getElementById('s').click(); |
|
221 }, true); |
|
222 |
|
223 gBrowser.selectedTab = tab; |
|
224 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
225 }, |
|
226 |
|
227 /** |
|
228 * In this test, we check that we can hide the popup by blurring the invalid |
|
229 * element. |
|
230 */ |
|
231 function() |
|
232 { |
|
233 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>"; |
|
234 let tab = gBrowser.addTab(); |
|
235 |
|
236 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
237 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
238 |
|
239 let doc = gBrowser.contentDocument; |
|
240 is(doc.activeElement, doc.getElementById('i'), |
|
241 "First invalid element should be focused"); |
|
242 |
|
243 checkPopupShow(); |
|
244 checkPopupMessage(doc); |
|
245 |
|
246 doc.getElementById('i').blur(); |
|
247 |
|
248 executeSoon(function () { |
|
249 checkPopupHide(); |
|
250 |
|
251 // Clean-up and next test. |
|
252 gBrowser.removeTab(gBrowser.selectedTab); |
|
253 nextTest(); |
|
254 }); |
|
255 }, false); |
|
256 |
|
257 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
258 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
259 |
|
260 gBrowser.contentDocument.getElementById('s').click(); |
|
261 }, true); |
|
262 |
|
263 gBrowser.selectedTab = tab; |
|
264 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
265 }, |
|
266 |
|
267 /** |
|
268 * In this test, we check that we can hide the popup by pressing TAB. |
|
269 */ |
|
270 function() |
|
271 { |
|
272 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>"; |
|
273 let tab = gBrowser.addTab(); |
|
274 |
|
275 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
276 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
277 |
|
278 let doc = gBrowser.contentDocument; |
|
279 is(doc.activeElement, doc.getElementById('i'), |
|
280 "First invalid element should be focused"); |
|
281 |
|
282 checkPopupShow(); |
|
283 checkPopupMessage(doc); |
|
284 |
|
285 EventUtils.synthesizeKey("VK_TAB", {}); |
|
286 |
|
287 executeSoon(function () { |
|
288 checkPopupHide(); |
|
289 |
|
290 // Clean-up and next test. |
|
291 gBrowser.removeTab(gBrowser.selectedTab); |
|
292 nextTest(); |
|
293 }); |
|
294 }, false); |
|
295 |
|
296 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
297 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
298 |
|
299 gBrowser.contentDocument.getElementById('s').click(); |
|
300 }, true); |
|
301 |
|
302 gBrowser.selectedTab = tab; |
|
303 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
304 }, |
|
305 |
|
306 /** |
|
307 * In this test, we check that the popup will hide if we move to another tab. |
|
308 */ |
|
309 function() |
|
310 { |
|
311 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>"; |
|
312 let tab = gBrowser.addTab(); |
|
313 |
|
314 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
315 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
316 |
|
317 let doc = gBrowser.contentDocument; |
|
318 is(doc.activeElement, doc.getElementById('i'), |
|
319 "First invalid element should be focused"); |
|
320 |
|
321 checkPopupShow(); |
|
322 checkPopupMessage(doc); |
|
323 |
|
324 // Create a new tab and move to it. |
|
325 gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true}); |
|
326 |
|
327 executeSoon(function() { |
|
328 checkPopupHide(); |
|
329 |
|
330 // Clean-up and next test. |
|
331 gBrowser.removeTab(gBrowser.selectedTab); |
|
332 gBrowser.removeTab(gBrowser.selectedTab); |
|
333 nextTest(); |
|
334 }); |
|
335 }, false); |
|
336 |
|
337 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
338 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
339 |
|
340 gBrowser.contentDocument.getElementById('s').click(); |
|
341 }, true); |
|
342 |
|
343 gBrowser.selectedTab = tab; |
|
344 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
345 }, |
|
346 |
|
347 /** |
|
348 * In this test, we check that nothing happen (no focus nor popup) if the |
|
349 * invalid form is submitted in another tab than the current focused one |
|
350 * (submitted in background). |
|
351 */ |
|
352 function() |
|
353 { |
|
354 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>"; |
|
355 let tab = gBrowser.addTab(); |
|
356 |
|
357 gObserver.notifyInvalidSubmit = function() { |
|
358 executeSoon(function() { |
|
359 let doc = tab.linkedBrowser.contentDocument; |
|
360 isnot(doc.activeElement, doc.getElementById('i'), |
|
361 "We should not focus the invalid element when the form is submitted in background"); |
|
362 |
|
363 checkPopupHide(); |
|
364 |
|
365 // Clean-up |
|
366 Services.obs.removeObserver(gObserver, "invalidformsubmit"); |
|
367 gObserver.notifyInvalidSubmit = function () {}; |
|
368 gBrowser.removeTab(tab); |
|
369 |
|
370 nextTest(); |
|
371 }); |
|
372 }; |
|
373 |
|
374 Services.obs.addObserver(gObserver, "invalidformsubmit", false); |
|
375 |
|
376 tab.linkedBrowser.addEventListener("load", function(e) { |
|
377 // Ignore load events from the iframe. |
|
378 if (tab.linkedBrowser.contentDocument == e.target) { |
|
379 let browser = e.currentTarget; |
|
380 browser.removeEventListener("load", arguments.callee, true); |
|
381 |
|
382 isnot(gBrowser.selectedTab.linkedBrowser, browser, |
|
383 "This tab should have been loaded in background"); |
|
384 browser.contentDocument.getElementById('s').click(); |
|
385 } |
|
386 }, true); |
|
387 |
|
388 tab.linkedBrowser.loadURI(uri); |
|
389 }, |
|
390 |
|
391 /** |
|
392 * In this test, we check that the author defined error message is shown. |
|
393 */ |
|
394 function() |
|
395 { |
|
396 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input x-moz-errormessage='foo' required id='i'><input id='s' type='submit'></form>"; |
|
397 let tab = gBrowser.addTab(); |
|
398 |
|
399 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
400 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
401 |
|
402 let doc = gBrowser.contentDocument; |
|
403 is(doc.activeElement, doc.getElementById('i'), |
|
404 "First invalid element should be focused"); |
|
405 |
|
406 checkPopupShow(); |
|
407 |
|
408 is(gInvalidFormPopup.firstChild.textContent, "foo", |
|
409 "The panel should show the author defined error message"); |
|
410 |
|
411 // Clean-up and next test. |
|
412 gBrowser.removeTab(gBrowser.selectedTab); |
|
413 nextTest(); |
|
414 }, false); |
|
415 |
|
416 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
417 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
418 |
|
419 gBrowser.contentDocument.getElementById('s').click(); |
|
420 }, true); |
|
421 |
|
422 gBrowser.selectedTab = tab; |
|
423 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
424 }, |
|
425 |
|
426 /** |
|
427 * In this test, we check that the message is correctly updated when it changes. |
|
428 */ |
|
429 function() |
|
430 { |
|
431 let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input type='email' required id='i'><input id='s' type='submit'></form>"; |
|
432 let tab = gBrowser.addTab(); |
|
433 |
|
434 gInvalidFormPopup.addEventListener("popupshown", function() { |
|
435 gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); |
|
436 |
|
437 let doc = gBrowser.contentDocument; |
|
438 let input = doc.getElementById('i'); |
|
439 is(doc.activeElement, input, "First invalid element should be focused"); |
|
440 |
|
441 checkPopupShow(); |
|
442 |
|
443 is(gInvalidFormPopup.firstChild.textContent, input.validationMessage, |
|
444 "The panel should show the current validation message"); |
|
445 |
|
446 input.addEventListener('input', function() { |
|
447 input.removeEventListener('input', arguments.callee, false); |
|
448 |
|
449 executeSoon(function() { |
|
450 // Now, the element suffers from another error, the message should have |
|
451 // been updated. |
|
452 is(gInvalidFormPopup.firstChild.textContent, input.validationMessage, |
|
453 "The panel should show the current validation message"); |
|
454 |
|
455 // Clean-up and next test. |
|
456 gBrowser.removeTab(gBrowser.selectedTab); |
|
457 nextTest(); |
|
458 }); |
|
459 }, false); |
|
460 |
|
461 EventUtils.synthesizeKey('f', {}); |
|
462 }, false); |
|
463 |
|
464 tab.linkedBrowser.addEventListener("load", function(aEvent) { |
|
465 tab.linkedBrowser.removeEventListener("load", arguments.callee, true); |
|
466 |
|
467 gBrowser.contentDocument.getElementById('s').click(); |
|
468 }, true); |
|
469 |
|
470 gBrowser.selectedTab = tab; |
|
471 gBrowser.selectedTab.linkedBrowser.loadURI(uri); |
|
472 }, |
|
473 |
|
474 ]; |