OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
3 <head> | 3 <head> |
4 <script src="../../resources/js-test.js"></script> | 4 <script src="../../resources/js-test.js"></script> |
5 <script> | 5 <script> |
6 jsTestIsAsync = true; | 6 jsTestIsAsync = true; |
7 | 7 |
8 var numErrors = 0; | 8 var numErrors = 0; |
9 var numErrorsExpected = 4; | 9 var numErrorsExpected = 5; |
10 var eventsBubbleToBody = false; | 10 var eventsBubbleToBody = false; |
11 var eventsBubbleToDocument = false; | 11 var eventsBubbleToDocument = false; |
12 var eventsBubbleToWindow = false; | 12 var eventsBubbleToWindow = false; |
| 13 var eventReason = ''; |
| 14 var promiseFired = false; |
| 15 |
| 16 function debugMsg(msg) |
| 17 { |
| 18 debug('DEBUG ' + msg); |
| 19 } |
13 | 20 |
14 function runTests() | 21 function runTests() |
15 { | 22 { |
16 checkDynamicAttributes(); | 23 checkDynamicAttributes(); |
17 checkNonUserGesture(); | |
18 checkParsedAttributes(); | 24 checkParsedAttributes(); |
19 checkEventsBubble(); | 25 checkEventsBubble(); |
| 26 checkPromiseRejects(); |
| 27 checkNonUserGesture(); |
| 28 debugMsg('finished runs tests, waiting for results'); |
| 29 } |
| 30 |
| 31 function debugStart() |
| 32 { |
| 33 debugMsg(arguments.callee.caller.name + ' running'); |
20 } | 34 } |
21 | 35 |
22 function checkForEnumerableProperties(form) | 36 function checkForEnumerableProperties(form) |
23 { | 37 { |
24 var enumerable = {}; | 38 if (!('onautocomplete' in form)) |
25 for (var field in form) | |
26 enumerable[field] = true; | |
27 if (!enumerable.onautocomplete) | |
28 testFailed('failed to enumerate HTMLFormElement.onautocomplete'); | 39 testFailed('failed to enumerate HTMLFormElement.onautocomplete'); |
29 if (!enumerable.onautocompleteerror) | 40 |
| 41 if (!('onautocompleteerror' in form)) |
30 testFailed('failed to enumerate HTMLFormElement.onautocompleteerror'); | 42 testFailed('failed to enumerate HTMLFormElement.onautocompleteerror'); |
| 43 |
31 testPassed('found enumerable properties on HTMLFormElement'); | 44 testPassed('found enumerable properties on HTMLFormElement'); |
32 } | 45 } |
33 | 46 |
34 function checkDynamicAttributes() | 47 function checkDynamicAttributes() |
35 { | 48 { |
| 49 debugStart(); |
| 50 |
36 var form = document.createElement('form'); | 51 var form = document.createElement('form'); |
37 checkForEnumerableProperties(form); | 52 checkForEnumerableProperties(form); |
38 | 53 form.addEventListener('autocompleteerror', errorWithReason('disabled')); |
39 form.autocomplete = 'off'; | 54 form.autocomplete = 'off'; |
40 form.addEventListener('autocompleteerror', errorWithReason('disabled')); | |
41 form.requestAutocomplete(); | 55 form.requestAutocomplete(); |
42 } | 56 } |
43 | 57 |
44 function checkNonUserGesture() | |
45 { | |
46 var form = document.createElement('form'); | |
47 checkForEnumerableProperties(form); | |
48 form.onautocompleteerror = errorWithReason('disabled'); | |
49 | |
50 setTimeout(function() | |
51 { | |
52 form.requestAutocomplete(); | |
53 }, 0); | |
54 } | |
55 | |
56 function checkParsedAttributes() | 58 function checkParsedAttributes() |
57 { | 59 { |
| 60 debugStart(); |
| 61 |
58 var form = document.forms[0]; | 62 var form = document.forms[0]; |
| 63 checkForEnumerableProperties(form); |
59 if (!form || !form.onautocompleteerror || form.autocomplete != 'off') | 64 if (!form || !form.onautocompleteerror || form.autocomplete != 'off') |
60 testFailed('failed to pick up parsed DOM attributes correctly'); | 65 testFailed('failed to pick up parsed DOM attributes correctly'); |
61 checkForEnumerableProperties(form); | |
62 | 66 |
63 form.requestAutocomplete(); | 67 form.requestAutocomplete(); |
64 } | 68 } |
65 | 69 |
66 function checkEventsBubble() | 70 function checkEventsBubble() |
67 { | 71 { |
| 72 debugStart(); |
| 73 |
68 var form = document.createElement('form'); | 74 var form = document.createElement('form'); |
69 form.autocomplete = 'off'; | 75 form.autocomplete = 'off'; |
70 | 76 |
71 document.body.onautocompleteerror = function(event) { | 77 document.body.onautocompleteerror = function(event) { |
72 eventsBubbleToBody = true; | 78 eventsBubbleToBody = true; |
73 if (event.target == form) { | 79 if (event.target == form) { |
74 event.stopPropagation(); | 80 event.stopPropagation(); |
75 setTimeout(onError); | 81 setTimeout(onError); |
76 } | 82 } |
77 }; | 83 }; |
78 | 84 |
79 document.onautocompleteerror = function(event) { | 85 document.onautocompleteerror = function(event) { |
80 eventsBubbleToDocument = true; | 86 eventsBubbleToDocument = true; |
81 if (event.target == form) | 87 if (event.target == form) |
82 testFailed("event should've been cancelled"); | 88 testFailed("event should've been cancelled"); |
83 }; | 89 }; |
84 | 90 |
85 window.onautocompleteerror = function(event) { | 91 window.onautocompleteerror = function(event) { |
86 eventsBubbleToWindow = true; | 92 eventsBubbleToWindow = true; |
87 if (event.target == form) | 93 if (event.target == form) |
88 testFailed("event should've been cancelled"); | 94 testFailed("event should've been cancelled"); |
89 }; | 95 }; |
90 | 96 |
91 document.body.appendChild(form); | 97 document.body.appendChild(form); |
92 form.requestAutocomplete(); | 98 form.requestAutocomplete(); |
93 } | 99 } |
94 | 100 |
| 101 function checkPromiseRejects() |
| 102 { |
| 103 debugStart(); |
| 104 |
| 105 var form = document.createElement('form'); |
| 106 form.autocomplete = 'off'; |
| 107 |
| 108 form.onautocompleteerror = function(e) { |
| 109 eventReason = e.reason; |
| 110 }; |
| 111 |
| 112 var promise = form.requestAutocomplete(); |
| 113 if (promise instanceof Promise) |
| 114 testPassed('requestAutocomplete() returns a Promise'); |
| 115 else |
| 116 testFailed('expected requestAutocomplete() to return a Promise'); |
| 117 |
| 118 promise.catch(objectWithReason('disabled')); |
| 119 } |
| 120 |
| 121 function checkNonUserGesture() |
| 122 { |
| 123 debugStart(); |
| 124 |
| 125 var form = document.createElement('form'); |
| 126 form.onautocompleteerror = errorWithReason('disabled'); |
| 127 |
| 128 setTimeout(function() { |
| 129 form.requestAutocomplete(); |
| 130 }); |
| 131 } |
| 132 |
95 function errorWithReason(reason) | 133 function errorWithReason(reason) |
96 { | 134 { |
| 135 var from = arguments.callee.caller.name; |
97 return function(event) { | 136 return function(event) { |
| 137 debugMsg('handling error from ' + from); |
| 138 |
98 if (event instanceof AutocompleteErrorEvent) | 139 if (event instanceof AutocompleteErrorEvent) |
99 testPassed('event is an AutocompleteErrorEvent'); | 140 testPassed('event is an AutocompleteErrorEvent'); |
100 else | 141 else |
101 testFailed('expected an AutocompleteErrorEvent'); | 142 testFailed('expected an AutocompleteErrorEvent'); |
102 | 143 |
103 if (event.reason == reason) | 144 if (event.reason == reason) |
104 testPassed('got expected reason: ' + reason); | 145 testPassed('got expected reason: ' + reason); |
105 else | 146 else |
106 testFailed('wrong reason, expected: ' + reason + ', got: ' + event.r
eason); | 147 testFailed('wrong reason, expected: ' + reason + ', got: ' + event.r
eason); |
107 | 148 |
108 onError(); | 149 onError(); |
109 }; | 150 }; |
110 } | 151 } |
111 | 152 |
| 153 function objectWithReason(reason) |
| 154 { |
| 155 return function(result) { |
| 156 if (promiseFired) { |
| 157 testFailed('Promise.catch() fired too many times'); |
| 158 return; |
| 159 } |
| 160 promiseFired = true; |
| 161 |
| 162 if (!eventReason) |
| 163 testFailed('events should dispatch before Promises are resolved'); |
| 164 |
| 165 if (!(result instanceof Error)) |
| 166 testFailed('expected Promise argument to be an result'); |
| 167 |
| 168 if (!('reason' in result)) |
| 169 testFailed('Promise result has no "reason" key'); |
| 170 |
| 171 if (result.reason != eventReason) |
| 172 testFailed('wrong reason, expected: ' + promiseResult.expectedReason
+ ', got: ' + promiseResult.actualReason); |
| 173 |
| 174 onError(); |
| 175 }; |
| 176 } |
| 177 |
112 function onError() | 178 function onError() |
113 { | 179 { |
114 numErrors += 1; | 180 numErrors += 1; |
115 if (numErrors > numErrorsExpected) { | 181 if (numErrors == numErrorsExpected) { |
116 testFailed('too many error events'); | |
117 } else if (numErrors == numErrorsExpected) { | |
118 if (!eventsBubbleToBody) | 182 if (!eventsBubbleToBody) |
119 testFailed('no events bubbled to body'); | 183 testFailed('no events bubbled to body'); |
| 184 |
120 if (!eventsBubbleToDocument) | 185 if (!eventsBubbleToDocument) |
121 testFailed('no events bubbled to document'); | 186 testFailed('no events bubbled to document'); |
| 187 |
122 if (!eventsBubbleToWindow) | 188 if (!eventsBubbleToWindow) |
123 testFailed('no events bubbled to window'); | 189 testFailed('no events bubbled to window'); |
| 190 |
124 if (eventsBubbleToBody && eventsBubbleToDocument && eventsBubbleToWindow
) | 191 if (eventsBubbleToBody && eventsBubbleToDocument && eventsBubbleToWindow
) |
125 testPassed('events bubbled as expected'); | 192 testPassed('events bubbled as expected'); |
| 193 |
| 194 if (promiseFired) |
| 195 testPassed('Promise.catch() fired'); |
| 196 else |
| 197 testFailed('Promise.catch() never fired'); |
| 198 |
126 testPassed('got expected number of error events (' + numErrorsExpected +
')'); | 199 testPassed('got expected number of error events (' + numErrorsExpected +
')'); |
127 finishJSTest(); | 200 finishJSTest(); |
128 } | 201 } |
129 } | 202 } |
130 | 203 |
131 window.addEventListener('load', runTests, true); | 204 window.addEventListener('load', runTests, true); |
132 </script> | 205 </script> |
133 </head> | 206 </head> |
134 <body> | 207 <body> |
135 <p> <a href="https://code.google.com/p/chromium/issues/detail?id=159537">HTMLFor
mElement#requestAutocomplete and associated events</a> </p> | 208 <p> <a href="https://code.google.com/p/chromium/issues/detail?id=159537">HTMLFor
mElement#requestAutocomplete and associated events</a> </p> |
136 <p> For this test to pass, you should see all PASSED below. </p> | 209 <p> For this test to pass, you should see all PASSED below. </p> |
137 <form autocomplete="off" onautocompleteerror="onError();"></form> | 210 <form autocomplete="off" onautocompleteerror="onError();"></form> |
138 <p id="console"></p> | 211 <p id="console"></p> |
139 </body> | 212 </body> |
140 </html> | 213 </html> |
OLD | NEW |