|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <head> |
|
4 <title>Test for Form History Autocomplete</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="satchel_common.js"></script> |
|
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
9 </head> |
|
10 <body> |
|
11 Form History test: form field autocomplete |
|
12 <p id="display"></p> |
|
13 |
|
14 <!-- we presumably can't hide the content for this test. --> |
|
15 <div id="content" style="direction: rtl;"> |
|
16 <!-- unused --> |
|
17 <form id="unused" onsubmit="return false;"> |
|
18 <input type="text" name="field1" value="unused"> |
|
19 </form> |
|
20 |
|
21 <!-- normal, basic form --> |
|
22 <form id="form1" onsubmit="return false;"> |
|
23 <input type="text" name="field1"> |
|
24 <button type="submit">Submit</button> |
|
25 </form> |
|
26 </div> |
|
27 |
|
28 <pre id="test"> |
|
29 <script class="testbody" type="text/javascript"> |
|
30 |
|
31 /** Test for Form History autocomplete **/ |
|
32 |
|
33 var autocompletePopup = getAutocompletePopup(); |
|
34 autocompletePopup.style.direction = "ltr"; |
|
35 |
|
36 var input = $_(1, "field1"); |
|
37 |
|
38 // Get the form history service |
|
39 function setupFormHistory(aCallback) { |
|
40 updateFormHistory([ |
|
41 { op : "remove" }, |
|
42 { op : "add", fieldname : "field1", value : "value1" }, |
|
43 { op : "add", fieldname : "field1", value : "value2" }, |
|
44 { op : "add", fieldname : "field1", value : "value3" }, |
|
45 { op : "add", fieldname : "field1", value : "value4" }, |
|
46 { op : "add", fieldname : "field1", value : "value5" }, |
|
47 { op : "add", fieldname : "field1", value : "value6" }, |
|
48 { op : "add", fieldname : "field1", value : "value7" }, |
|
49 { op : "add", fieldname : "field1", value : "value8" }, |
|
50 { op : "add", fieldname : "field1", value : "value9" }, |
|
51 ], aCallback); |
|
52 } |
|
53 |
|
54 function checkForm(expectedValue) { |
|
55 var formID = input.parentNode.id; |
|
56 is(input.value, expectedValue, "Checking " + formID + " input"); |
|
57 } |
|
58 |
|
59 function checkPopupOpen(isOpen, expectedIndex) { |
|
60 var actuallyOpen = autocompletePopup.popupOpen; |
|
61 var actualIndex = autocompletePopup.selectedIndex; |
|
62 is(actuallyOpen, isOpen, "popup should be " + (isOpen ? "open" : "closed")); |
|
63 if (isOpen) |
|
64 is(actualIndex, expectedIndex, "checking selected index"); |
|
65 |
|
66 // Correct state if needed, so following tests run as expected. |
|
67 if (actuallyOpen != isOpen) { |
|
68 if (isOpen) |
|
69 autocompletePopup.openPopup(); |
|
70 else |
|
71 autocompletePopup.closePopup(); |
|
72 } |
|
73 if (isOpen && actualIndex != expectedIndex) |
|
74 autocompletePopup.selectedIndex = expectedIndex; |
|
75 } |
|
76 |
|
77 function doKeyUnprivileged(key) { |
|
78 var keyName = "DOM_VK_" + key.toUpperCase(); |
|
79 var keycode, charcode, alwaysVal; |
|
80 |
|
81 if (key.length == 1) { |
|
82 keycode = 0; |
|
83 charcode = key.charCodeAt(0); |
|
84 alwaysval = charcode; |
|
85 } else { |
|
86 keycode = KeyEvent[keyName]; |
|
87 if (!keycode) |
|
88 throw "invalid keyname in test"; |
|
89 charcode = 0; |
|
90 alwaysval = keycode; |
|
91 } |
|
92 |
|
93 var dnEvent = document.createEvent('KeyboardEvent'); |
|
94 var prEvent = document.createEvent('KeyboardEvent'); |
|
95 var upEvent = document.createEvent('KeyboardEvent'); |
|
96 |
|
97 dnEvent.initKeyEvent("keydown", true, true, null, false, false, false, false, alwaysval, 0); |
|
98 prEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, keycode, charcode); |
|
99 upEvent.initKeyEvent("keyup", true, true, null, false, false, false, false, alwaysval, 0); |
|
100 |
|
101 input.dispatchEvent(dnEvent); |
|
102 input.dispatchEvent(prEvent); |
|
103 input.dispatchEvent(upEvent); |
|
104 } |
|
105 |
|
106 function doClickUnprivileged() { |
|
107 var dnEvent = document.createEvent('MouseEvent'); |
|
108 var upEvent = document.createEvent('MouseEvent'); |
|
109 var ckEvent = document.createEvent('MouseEvent'); |
|
110 |
|
111 dnEvent.initMouseEvent("mousedown", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null); |
|
112 upEvent.initMouseEvent("mouseup", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null); |
|
113 ckEvent.initMouseEvent("mouseclick", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null); |
|
114 |
|
115 input.dispatchEvent(dnEvent); |
|
116 input.dispatchEvent(upEvent); |
|
117 input.dispatchEvent(ckEvent); |
|
118 } |
|
119 |
|
120 var testNum = 0; |
|
121 var expectingPopup = false; |
|
122 |
|
123 function expectPopup() |
|
124 { |
|
125 info("expecting popup for test " + testNum); |
|
126 expectingPopup = true; |
|
127 } |
|
128 |
|
129 function popupShownListener() |
|
130 { |
|
131 info("popup shown for test " + testNum); |
|
132 if (expectingPopup) { |
|
133 expectingPopup = false; |
|
134 SimpleTest.executeSoon(runTest); |
|
135 } |
|
136 else { |
|
137 ok(false, "Autocomplete popup not expected" + testNum); |
|
138 } |
|
139 } |
|
140 |
|
141 SpecialPowers.addAutoCompletePopupEventListener(window, "popupshown", popupShownListener); |
|
142 |
|
143 /* |
|
144 * Main section of test... |
|
145 * |
|
146 * This is a bit hacky, because the events are either being sent or |
|
147 * processes asynchronously, so we need to interrupt our flow with lots of |
|
148 * setTimeout() calls. The case statements are executed in order, one per |
|
149 * timeout. |
|
150 */ |
|
151 function runTest() { |
|
152 testNum++; |
|
153 |
|
154 ok(true, "Starting test #" + testNum); |
|
155 |
|
156 switch(testNum) { |
|
157 // |
|
158 // Check initial state |
|
159 // |
|
160 case 1: |
|
161 input.value = ""; |
|
162 checkForm(""); |
|
163 is(autocompletePopup.popupOpen, false, "popup should be initially closed"); |
|
164 break; |
|
165 |
|
166 // |
|
167 // Try to open the autocomplete popup from untrusted events. |
|
168 // |
|
169 // try a focus() |
|
170 case 2: |
|
171 input.focus(); |
|
172 break; |
|
173 case 3: |
|
174 checkPopupOpen(false); |
|
175 checkForm(""); |
|
176 break; |
|
177 // try a click() |
|
178 case 4: |
|
179 input.click(); |
|
180 break; |
|
181 case 5: |
|
182 checkPopupOpen(false); |
|
183 checkForm(""); |
|
184 break; |
|
185 // try a mouseclick event |
|
186 case 6: |
|
187 doClickUnprivileged(); |
|
188 break; |
|
189 case 7: |
|
190 checkPopupOpen(false); |
|
191 checkForm(""); |
|
192 break; |
|
193 // try a down-arrow |
|
194 case 8: |
|
195 doKeyUnprivileged("down"); |
|
196 break; |
|
197 case 9: |
|
198 checkPopupOpen(false); |
|
199 checkForm(""); |
|
200 break; |
|
201 // try a page-down |
|
202 case 10: |
|
203 doKeyUnprivileged("page_down"); |
|
204 break; |
|
205 case 11: |
|
206 checkPopupOpen(false); |
|
207 checkForm(""); |
|
208 break; |
|
209 // try a return |
|
210 case 12: |
|
211 // XXX this causes later tests to fail for some reason. |
|
212 // doKeyUnprivileged("return"); // not "enter"! |
|
213 break; |
|
214 case 13: |
|
215 checkPopupOpen(false); |
|
216 checkForm(""); |
|
217 break; |
|
218 // try a keypress |
|
219 case 14: |
|
220 doKeyUnprivileged('v'); |
|
221 break; |
|
222 case 15: |
|
223 checkPopupOpen(false); |
|
224 checkForm(""); |
|
225 break; |
|
226 // try a space |
|
227 case 16: |
|
228 doKeyUnprivileged(" "); |
|
229 break; |
|
230 case 17: |
|
231 checkPopupOpen(false); |
|
232 checkForm(""); |
|
233 break; |
|
234 // backspace |
|
235 case 18: |
|
236 doKeyUnprivileged("back_space"); |
|
237 break; |
|
238 case 19: |
|
239 checkPopupOpen(false); |
|
240 checkForm(""); |
|
241 break; |
|
242 case 20: |
|
243 // We're privileged for this test, so open the popup. |
|
244 checkPopupOpen(false); |
|
245 checkForm(""); |
|
246 expectPopup(); |
|
247 doKey("down"); |
|
248 return; |
|
249 break; |
|
250 case 21: |
|
251 checkPopupOpen(true, -1); |
|
252 checkForm(""); |
|
253 testNum = 99; |
|
254 break; |
|
255 |
|
256 // |
|
257 // Try to change the selected autocomplete item from untrusted events |
|
258 // |
|
259 |
|
260 // try a down-arrow |
|
261 case 100: |
|
262 doKeyUnprivileged("down"); |
|
263 break; |
|
264 case 101: |
|
265 checkPopupOpen(true, -1); |
|
266 checkForm(""); |
|
267 break; |
|
268 // try a page-down |
|
269 case 102: |
|
270 doKeyUnprivileged("page_down"); |
|
271 break; |
|
272 case 103: |
|
273 checkPopupOpen(true, -1); |
|
274 checkForm(""); |
|
275 break; |
|
276 // really adjust the index |
|
277 case 104: |
|
278 // (We're privileged for this test.) Try a privileged down-arrow. |
|
279 doKey("down"); |
|
280 break; |
|
281 case 105: |
|
282 checkPopupOpen(true, 0); |
|
283 checkForm(""); |
|
284 break; |
|
285 // try a down-arrow |
|
286 case 106: |
|
287 doKeyUnprivileged("down"); |
|
288 break; |
|
289 case 107: |
|
290 checkPopupOpen(true, 0); |
|
291 checkForm(""); |
|
292 break; |
|
293 // try a page-down |
|
294 case 108: |
|
295 doKeyUnprivileged("page_down"); |
|
296 break; |
|
297 case 109: |
|
298 checkPopupOpen(true, 0); |
|
299 checkForm(""); |
|
300 // try a keypress |
|
301 case 110: |
|
302 // XXX this causes the popup to close, and makes the value "vaa" (sic) |
|
303 //doKeyUnprivileged('a'); |
|
304 break; |
|
305 case 111: |
|
306 checkPopupOpen(true, 0); |
|
307 checkForm(""); |
|
308 testNum = 199; |
|
309 break; |
|
310 |
|
311 // |
|
312 // Try to use the selected autocomplete item from untrusted events |
|
313 // |
|
314 // try a right-arrow |
|
315 case 200: |
|
316 doKeyUnprivileged("right"); |
|
317 break; |
|
318 case 201: |
|
319 checkPopupOpen(true, 0); |
|
320 checkForm(""); |
|
321 break; |
|
322 // try a space |
|
323 case 202: |
|
324 doKeyUnprivileged(" "); |
|
325 break; |
|
326 case 203: |
|
327 // XXX we should ignore this input while popup is open? |
|
328 checkPopupOpen(true, 0); |
|
329 checkForm(""); |
|
330 break; |
|
331 // backspace |
|
332 case 204: |
|
333 doKeyUnprivileged("back_space"); |
|
334 break; |
|
335 case 205: |
|
336 // XXX we should ignore this input while popup is open? |
|
337 checkPopupOpen(true, 0); |
|
338 checkForm(""); |
|
339 break; |
|
340 case 206: |
|
341 // (this space intentionally left blank) |
|
342 break; |
|
343 case 207: |
|
344 checkPopupOpen(true, 0); |
|
345 checkForm(""); |
|
346 break; |
|
347 // try a return |
|
348 case 208: |
|
349 // XXX this seems to cause problems with reliably closing the popup |
|
350 // doKeyUnprivileged("return"); // not "enter"! |
|
351 break; |
|
352 case 209: |
|
353 checkPopupOpen(true, 0); |
|
354 checkForm(""); |
|
355 break; |
|
356 // Send a real Escape to ensure popup closed at end of test. |
|
357 case 210: |
|
358 // Need to use doKey(), even though this test is not privileged. |
|
359 doKey("escape"); |
|
360 break; |
|
361 case 211: |
|
362 checkPopupOpen(false); |
|
363 checkForm(""); |
|
364 is(autocompletePopup.style.direction, "rtl", "direction should have been changed from ltr to rtl"); |
|
365 |
|
366 SpecialPowers.removeAutoCompletePopupEventListener(window, "popupshown", popupShownListener); |
|
367 SimpleTest.finish(); |
|
368 return; |
|
369 |
|
370 default: |
|
371 ok(false, "Unexpected invocation of test #" + testNum); |
|
372 SpecialPowers.removeAutoCompletePopupEventListener(window, "popupshown", popupShownListener); |
|
373 SimpleTest.finish(); |
|
374 return; |
|
375 } |
|
376 |
|
377 SimpleTest.executeSoon(runTest); |
|
378 } |
|
379 |
|
380 function startTest() { |
|
381 setupFormHistory(runTest); |
|
382 } |
|
383 |
|
384 SimpleTest.waitForFocus(startTest); |
|
385 |
|
386 SimpleTest.waitForExplicitFinish(); |
|
387 </script> |
|
388 </pre> |
|
389 </body> |
|
390 </html> |