| 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 |