Chromium Code Reviews| 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 | 13 |
| 14 function debugMsg(msg) | |
| 15 { | |
| 16 debug('DEBUG ' + msg); | |
| 17 } | |
| 18 | |
| 14 function runTests() | 19 function runTests() |
| 15 { | 20 { |
| 16 checkDynamicAttributes(); | 21 checkDynamicAttributes(); |
| 17 checkNonUserGesture(); | |
| 18 checkParsedAttributes(); | 22 checkParsedAttributes(); |
| 19 checkEventsBubble(); | 23 checkEventsBubble(); |
| 24 checkPromiseRejects(); | |
|
yhirano
2014/04/17 10:57:48
Can you serialize the tests using Promises?
Otherw
Dan Beam
2014/04/17 23:02:04
Done. (order doesn't matter now)
| |
| 25 checkNonUserGesture(); | |
| 26 debugMsg('finished running synchronous code'); | |
| 27 } | |
| 28 | |
| 29 function debugStart() | |
| 30 { | |
| 31 debugMsg(arguments.callee.caller.name + ' running'); | |
| 20 } | 32 } |
| 21 | 33 |
| 22 function checkForEnumerableProperties(form) | 34 function checkForEnumerableProperties(form) |
| 23 { | 35 { |
| 24 var enumerable = {}; | 36 var enumerable = {}; |
| 25 for (var field in form) | 37 for (var field in form) |
| 26 enumerable[field] = true; | 38 enumerable[field] = true; |
| 27 if (!enumerable.onautocomplete) | 39 if (!enumerable.onautocomplete) |
| 28 testFailed('failed to enumerate HTMLFormElement.onautocomplete'); | 40 testFailed('failed to enumerate HTMLFormElement.onautocomplete'); |
| 29 if (!enumerable.onautocompleteerror) | 41 if (!enumerable.onautocompleteerror) |
| 30 testFailed('failed to enumerate HTMLFormElement.onautocompleteerror'); | 42 testFailed('failed to enumerate HTMLFormElement.onautocompleteerror'); |
| 31 testPassed('found enumerable properties on HTMLFormElement'); | 43 testPassed('found enumerable properties on HTMLFormElement'); |
| 32 } | 44 } |
| 33 | 45 |
| 34 function checkDynamicAttributes() | 46 function checkDynamicAttributes() |
| 35 { | 47 { |
| 48 debugStart(); | |
| 49 | |
| 36 var form = document.createElement('form'); | 50 var form = document.createElement('form'); |
| 37 checkForEnumerableProperties(form); | 51 checkForEnumerableProperties(form); |
| 38 | 52 |
| 39 form.autocomplete = 'off'; | 53 form.autocomplete = 'off'; |
| 40 form.addEventListener('autocompleteerror', errorWithReason('disabled')); | 54 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]; |
| 59 if (!form || !form.onautocompleteerror || form.autocomplete != 'off') | 63 if (!form || !form.onautocompleteerror || form.autocomplete != 'off') |
| 60 testFailed('failed to pick up parsed DOM attributes correctly'); | 64 testFailed('failed to pick up parsed DOM attributes correctly'); |
| 61 checkForEnumerableProperties(form); | 65 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 var eventDispatched = false; | |
| 109 form.onautocompleteerror = function() { | |
| 110 eventDispatched = true; | |
| 111 }; | |
| 112 | |
| 113 var promise = form.requestAutocomplete(); | |
| 114 if (promise instanceof Promise) | |
| 115 testPassed('requestAutocomplete() returns a Promise'); | |
| 116 else | |
| 117 testFailed('expected requestAutocomplete() to return a Promise'); | |
| 118 | |
| 119 promise.catch(objectWithReason('disabled')); | |
| 120 promise.catch(function() { | |
| 121 if (eventDispatched) | |
| 122 testPassed('Promises were fullfilled after events were dispatched'); | |
| 123 else | |
| 124 testFailed('events should be dispatched before Promises are resolved '); | |
| 125 }); | |
| 126 } | |
| 127 | |
| 128 function checkNonUserGesture() | |
| 129 { | |
| 130 debugStart(); | |
| 131 | |
| 132 var form = document.createElement('form'); | |
| 133 checkForEnumerableProperties(form); | |
| 134 form.onautocompleteerror = errorWithReason('disabled'); | |
| 135 | |
| 136 setTimeout(function() { | |
| 137 form.requestAutocomplete(); | |
| 138 }); | |
| 139 } | |
| 140 | |
| 95 function errorWithReason(reason) | 141 function errorWithReason(reason) |
| 96 { | 142 { |
| 143 var from = arguments.callee.caller.name; | |
| 97 return function(event) { | 144 return function(event) { |
| 145 debugMsg('handling error from ' + from); | |
| 146 | |
| 98 if (event instanceof AutocompleteErrorEvent) | 147 if (event instanceof AutocompleteErrorEvent) |
| 99 testPassed('event is an AutocompleteErrorEvent'); | 148 testPassed('event is an AutocompleteErrorEvent'); |
| 100 else | 149 else |
| 101 testFailed('expected an AutocompleteErrorEvent'); | 150 testFailed('expected an AutocompleteErrorEvent'); |
| 102 | 151 |
| 103 if (event.reason == reason) | 152 if (event.reason == reason) |
| 104 testPassed('got expected reason: ' + reason); | 153 testPassed('got expected reason: ' + reason); |
| 105 else | 154 else |
| 106 testFailed('wrong reason, expected: ' + reason + ', got: ' + event.r eason); | 155 testFailed('wrong reason, expected: ' + reason + ', got: ' + event.r eason); |
| 107 | 156 |
| 108 onError(); | 157 onError(); |
| 109 }; | 158 }; |
| 110 } | 159 } |
| 111 | 160 |
| 161 function objectWithReason(reason) | |
| 162 { | |
| 163 var from = arguments.callee.caller.name; | |
| 164 return function(result) { | |
| 165 debugMsg('handling error from ' + from); | |
| 166 | |
| 167 if (result instanceof Error) | |
| 168 testPassed('Promise received an Error result'); | |
| 169 else | |
| 170 testFailed('expected Promise argument to be an result'); | |
| 171 | |
| 172 if ('reason' in result) | |
| 173 testPassed('Promise result has "reason" key'); | |
| 174 else | |
| 175 testFailed('Promise result has no "reason" key'); | |
| 176 | |
| 177 if (result.reason == reason) | |
| 178 testPassed('got expected reason: ' + reason); | |
| 179 else | |
| 180 testFailed('wrong reason, expected: ' + reason + ', got: ' + result. error); | |
| 181 | |
| 182 onError(); | |
| 183 }; | |
| 184 } | |
| 185 | |
| 112 function onError() | 186 function onError() |
| 113 { | 187 { |
| 114 numErrors += 1; | 188 numErrors += 1; |
| 115 if (numErrors > numErrorsExpected) { | 189 if (numErrors == numErrorsExpected) { |
| 116 testFailed('too many error events'); | |
| 117 } else if (numErrors == numErrorsExpected) { | |
| 118 if (!eventsBubbleToBody) | 190 if (!eventsBubbleToBody) |
| 119 testFailed('no events bubbled to body'); | 191 testFailed('no events bubbled to body'); |
| 192 | |
| 120 if (!eventsBubbleToDocument) | 193 if (!eventsBubbleToDocument) |
| 121 testFailed('no events bubbled to document'); | 194 testFailed('no events bubbled to document'); |
| 195 | |
| 122 if (!eventsBubbleToWindow) | 196 if (!eventsBubbleToWindow) |
| 123 testFailed('no events bubbled to window'); | 197 testFailed('no events bubbled to window'); |
| 198 | |
| 124 if (eventsBubbleToBody && eventsBubbleToDocument && eventsBubbleToWindow ) | 199 if (eventsBubbleToBody && eventsBubbleToDocument && eventsBubbleToWindow ) |
| 125 testPassed('events bubbled as expected'); | 200 testPassed('events bubbled as expected'); |
| 201 | |
| 126 testPassed('got expected number of error events (' + numErrorsExpected + ')'); | 202 testPassed('got expected number of error events (' + numErrorsExpected + ')'); |
| 127 finishJSTest(); | 203 finishJSTest(); |
| 128 } | 204 } |
| 129 } | 205 } |
| 130 | 206 |
| 131 window.addEventListener('load', runTests, true); | 207 window.addEventListener('load', runTests, true); |
| 132 </script> | 208 </script> |
| 133 </head> | 209 </head> |
| 134 <body> | 210 <body> |
| 135 <p> <a href="https://code.google.com/p/chromium/issues/detail?id=159537">HTMLFor mElement#requestAutocomplete and associated events</a> </p> | 211 <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> | 212 <p> For this test to pass, you should see all PASSED below. </p> |
| 137 <form autocomplete="off" onautocompleteerror="onError();"></form> | 213 <form autocomplete="off" onautocompleteerror="onError();"></form> |
| 138 <p id="console"></p> | 214 <p id="console"></p> |
| 139 </body> | 215 </body> |
| 140 </html> | 216 </html> |
| OLD | NEW |