OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 var util = {}; | 5 var util = {}; |
6 | 6 |
7 // Creates a <webview> tag in document.body and returns the reference to it. | 7 // Creates a <webview> tag in document.body and returns the reference to it. |
8 // It also sets a dummy src. The dummy src is significant because this makes | 8 // It also sets a dummy src. The dummy src is significant because this makes |
9 // sure that the <object> shim is created (asynchronously at this point) for the | 9 // sure that the <object> shim is created (asynchronously at this point) for the |
10 // <webview> tag. This makes the <webview> tag ready for add/removeEventListener | 10 // <webview> tag. This makes the <webview> tag ready for add/removeEventListener |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 chrome.test.assertEq(230, dynamicWebViewTag.offsetHeight); | 53 chrome.test.assertEq(230, dynamicWebViewTag.offsetHeight); |
54 | 54 |
55 chrome.test.succeed(); | 55 chrome.test.succeed(); |
56 }, 0); | 56 }, 0); |
57 }, | 57 }, |
58 | 58 |
59 function webViewApiMethodExistence() { | 59 function webViewApiMethodExistence() { |
60 var webview = document.createElement('webview'); | 60 var webview = document.createElement('webview'); |
61 webview.setAttribute('src', 'data:text/html,webview check api'); | 61 webview.setAttribute('src', 'data:text/html,webview check api'); |
62 var apiMethodsToCheck = [ | 62 var apiMethodsToCheck = [ |
63 'addEventListener', | |
64 'back', | 63 'back', |
65 'canGoBack', | 64 'canGoBack', |
66 'canGoForward', | 65 'canGoForward', |
67 'forward', | 66 'forward', |
68 'getProcessId', | 67 'getProcessId', |
69 'go', | 68 'go', |
70 'reload', | 69 'reload', |
71 'removeEventListener', | |
72 'stop', | 70 'stop', |
73 'terminate' | 71 'terminate' |
74 ]; | 72 ]; |
75 document.body.appendChild(webview); | 73 document.body.appendChild(webview); |
76 | 74 |
77 // Timeout is necessary to give the mutation observers of the webview tag | 75 // Timeout is necessary to give the mutation observers of the webview tag |
78 // shim a chance to fire. | 76 // shim a chance to fire. |
79 setTimeout(function() { | 77 setTimeout(function() { |
80 for (var i = 0; i < apiMethodsToCheck.length; ++i) { | 78 for (var i = 0; i < apiMethodsToCheck.length; ++i) { |
81 chrome.test.assertEq('function', | 79 chrome.test.assertEq('function', |
82 typeof webview[apiMethodsToCheck[i]]); | 80 typeof webview[apiMethodsToCheck[i]]); |
83 } | 81 } |
84 | 82 |
85 // Check contentWindow. | 83 // Check contentWindow. |
86 chrome.test.assertEq('object', typeof webview.contentWindow); | 84 chrome.test.assertEq('object', typeof webview.contentWindow); |
87 chrome.test.assertEq('function', | 85 chrome.test.assertEq('function', |
88 typeof webview.contentWindow.postMessage); | 86 typeof webview.contentWindow.postMessage); |
89 | 87 |
90 chrome.test.succeed(); | 88 chrome.test.succeed(); |
91 }, 0); | 89 }, 0); |
92 }, | 90 }, |
93 | 91 |
94 function webViewEventListeners() { | |
95 var webview = document.createElement('webview'); | |
96 webview.setAttribute('src', 'data:text/html,webview check api'); | |
97 document.body.appendChild(webview); | |
98 | |
99 var validEvents = [ | |
100 'exit', | |
101 'loadabort', | |
102 'loadredirect', | |
103 'loadstart', | |
104 'loadstop' | |
105 ]; | |
106 var invalidEvents = [ | |
107 'makemesandwich', | |
108 'sudomakemesandwich' | |
109 ]; | |
110 | |
111 // Timeout is necessary to give the mutation observers of the webview tag | |
112 // shim a chance to fire. | |
113 setTimeout(function() { | |
114 for (var i = 0; i < validEvents.length; ++i) { | |
115 chrome.test.assertTrue( | |
116 webview.addEventListener(validEvents[i], function() {})); | |
117 } | |
118 | |
119 for (var i = 0; i < invalidEvents.length; ++i) { | |
120 chrome.test.assertFalse( | |
121 webview.addEventListener(invalidEvents[i], function() {})); | |
122 } | |
123 | |
124 chrome.test.succeed(); | |
125 }, 0); | |
126 }, | |
127 | |
128 function webViewEventName() { | 92 function webViewEventName() { |
129 var webview = document.createElement('webview'); | 93 var webview = document.createElement('webview'); |
130 webview.setAttribute('src', 'data:text/html,webview check api'); | 94 webview.setAttribute('src', 'data:text/html,webview check api'); |
131 document.body.appendChild(webview); | 95 document.body.appendChild(webview); |
132 | 96 |
133 setTimeout(function() { | 97 webview.addEventListener('loadstart', function(evt) { |
134 webview.addEventListener('loadstart', function(evt) { | 98 chrome.test.assertEq('loadstart', evt.type); |
135 chrome.test.assertEq('loadstart', evt.name); | 99 }); |
136 }); | |
137 | 100 |
138 webview.addEventListener('loadstop', function(evt) { | 101 webview.addEventListener('loadstop', function(evt) { |
139 chrome.test.assertEq('loadstop', evt.name); | 102 chrome.test.assertEq('loadstop', evt.type); |
140 webview.terminate(); | 103 webview.terminate(); |
141 }); | 104 }); |
142 | 105 |
143 webview.addEventListener('exit', function(evt) { | 106 webview.addEventListener('exit', function(evt) { |
144 chrome.test.assertEq('exit', evt.name); | 107 chrome.test.assertEq('exit', evt.type); |
145 chrome.test.succeed(); | 108 chrome.test.succeed(); |
146 }); | 109 }); |
147 | 110 |
148 webview.setAttribute('src', 'data:text/html,trigger navigation'); | 111 webview.setAttribute('src', 'data:text/html,trigger navigation'); |
149 }, 0); | |
150 }, | 112 }, |
151 | 113 |
152 // This test registers two listeners on an event (loadcommit) and removes | 114 // This test registers two listeners on an event (loadcommit) and removes |
153 // the <webview> tag when the first listener fires. | 115 // the <webview> tag when the first listener fires. |
154 // Current expected behavior is that the second event listener will still | 116 // Current expected behavior is that the second event listener will still |
155 // fire (and we don't crash). | 117 // fire without crashing. |
156 function webviewDestroyOnEventListener() { | 118 function webviewDestroyOnEventListener() { |
157 var webview = util.createWebViewTagInDOM(); | 119 var webview = util.createWebViewTagInDOM(); |
158 var url = 'data:text/html,<body>Destroy test</body>'; | 120 var url = 'data:text/html,<body>Destroy test</body>'; |
159 | 121 |
160 var continuedAfterDelete = false; | |
161 var loadCommitCount = 0; | 122 var loadCommitCount = 0; |
162 var updateLoadCommitCount = function() { | 123 function loadCommitCommon(e) { |
| 124 chrome.test.assertEq('loadcommit', e.type); |
| 125 if (url != e.url) |
| 126 return; |
163 ++loadCommitCount; | 127 ++loadCommitCount; |
164 if (loadCommitCount == 1) { | 128 if (loadCommitCount == 1) { |
165 // We remove the <webview> tag when the first listener fires. | |
166 webview.parentNode.removeChild(webview); | 129 webview.parentNode.removeChild(webview); |
167 webview = null; | 130 webview = null; |
168 // Make sure the js executes after nulling |webview|. | 131 setTimeout(function() { |
169 continuedAfterDelete = true; | 132 chrome.test.succeed(); |
170 } else if (loadCommitCount == 2) { | 133 }, 0); |
171 chrome.test.assertTrue(continuedAfterDelete); | 134 } else if (loadCommitCount > 2) { |
172 chrome.test.succeed(); | |
173 } | |
174 }; | |
175 | |
176 var onLoadCommitA = function(e) { | |
177 chrome.test.assertEq('loadcommit', e.name); | |
178 if (e.url == url) { | |
179 updateLoadCommitCount(); | |
180 } | |
181 }; | |
182 var onLoadCommitB = function(e) { | |
183 chrome.test.assertEq('loadcommit', e.name); | |
184 if (e.url == url) { | |
185 updateLoadCommitCount(); | |
186 } | |
187 }; | |
188 | |
189 setTimeout(function() { | |
190 // The test starts from here, by setting the src to |url|. Event | |
191 // listener registration works because we already have a (dummy) src set | |
192 // on the <webview> tag. | |
193 webview.addEventListener('loadcommit', onLoadCommitA); | |
194 webview.addEventListener('loadcommit', onLoadCommitB); | |
195 webview.setAttribute('src', url); | |
196 }, 0); | |
197 }, | |
198 | |
199 // This test checks the current behavior of dynamic event listener | |
200 // registration 'during' an event listener fire. | |
201 // Once an event starts firing its listeners, any mutation to the list of | |
202 // event listeners for this event are deferred until all of the listeners | |
203 // have fired. | |
204 // | |
205 // Step1: Loads a guest with |urlStep1| with two listeners to 'loadcommit': | |
206 // onLoadCommitA and onLoadCommitB. When first of them fires, we try to | |
207 // remove the other and add a third listener (onLoadCommitC). | |
208 // Current expected behavior is these add/remove will be ignored and the | |
209 // original two listeners will fire. | |
210 // Step2: We change the guest to |urlStep2|. This will cause 'loadcommit' to | |
211 // fire with mutated event listeners list (that is one of | |
212 // onLoadCommitA/onLoadCommitB and onLoadCommitC). | |
213 function dynamicEventListenerRegistrationOnListenerFire() { | |
214 var urlStep1 = 'data:text/html,<body>Two</body>'; | |
215 var urlStep2 = 'data:text/html,<body>Three</body>'; | |
216 var webview = util.createWebViewTagInDOM(); | |
217 | |
218 var listenerFireCount1 = 0; // Step 1 listeners. | |
219 var listenerFireCount2 = 0; // Step 2 listeners. | |
220 | |
221 var loadCommitACalledStep1 = false; | |
222 var loadCommitBCalledStep1 = false; | |
223 | |
224 var loadCommitACalledStep2 = false; | |
225 var loadCommitBCalledStep2 = false; | |
226 var loadCommitCCalledStep2 = false; | |
227 | |
228 var expectAToFireInStep2; | |
229 var expectBToFireInStep2; | |
230 | |
231 var updateTestStateOnListenerStep1 = function() { | |
232 ++listenerFireCount1; | |
233 if (listenerFireCount1 == 1) { // First listener fire on Step 1. | |
234 chrome.test.assertTrue(loadCommitACalledStep1 || | |
235 loadCommitBCalledStep1); | |
236 // Add an event listener and remove one existing one when the first | |
237 // listener fires. Current implmementation does not expect any of | |
238 // these to be reflected before all event listeners are fired for the | |
239 // current event. | |
240 | |
241 // Remove. | |
242 if (loadCommitACalledStep1) { | |
243 webview.removeEventListener('loadcommit', onLoadCommitB); | |
244 expectAToFireInStep2 = true; | |
245 expectBToFireInStep2 = false; | |
246 } else { | |
247 webview.removeEventListener('loadcommit', onLoadCommitA); | |
248 expectAToFireInStep2 = false; | |
249 expectBToFireInStep2 = true; | |
250 } | |
251 // Add the other one. | |
252 webview.addEventListener('loadcommit', onLoadCommitC); | |
253 } else if (listenerFireCount1 == 2) { // Last listener fire on Step 1. | |
254 chrome.test.assertTrue(loadCommitACalledStep1 && | |
255 loadCommitBCalledStep1); | |
256 // Move to Step 2. | |
257 webview.setAttribute('src', urlStep2); | |
258 } else { | |
259 // More than expected listeners fired. | |
260 chrome.test.fail(); | 135 chrome.test.fail(); |
261 } | 136 } |
262 }; | 137 }; |
263 | 138 |
264 var updateTestStateOnListenerStep2 = function() { | 139 // The test starts from here, by setting the src to |url|. |
265 ++listenerFireCount2; | 140 webview.addEventListener('loadcommit', function(e) { |
266 if (listenerFireCount2 == 2) { | 141 loadCommitCommon(e); |
267 // Exactly one of onLoadCommitA and onLoadCommitB must be called. | 142 }); |
268 chrome.test.assertTrue(loadCommitACalledStep2 || | 143 webview.addEventListener('loadcommit', function(e) { |
269 loadCommitBCalledStep2); | 144 loadCommitCommon(e); |
270 // onLoadCommitC must be called. | 145 }); |
271 chrome.test.assertTrue(loadCommitCCalledStep2); | 146 webview.setAttribute('src', url); |
272 | |
273 chrome.test.succeed(); | |
274 } else if (listenerFireCount2 > 2) { | |
275 // More than expected listeners fired. | |
276 chrome.test.fail(); | |
277 } | |
278 }; | |
279 | |
280 var onLoadCommitA = function(e) { | |
281 chrome.test.assertEq('loadcommit', e.name); | |
282 switch (e.url) { | |
283 case urlStep1: // Step 1. | |
284 chrome.test.log('Step 1. onLoadCommitA'); | |
285 chrome.test.assertFalse(loadCommitACalledStep1); | |
286 loadCommitACalledStep1 = true; | |
287 | |
288 updateTestStateOnListenerStep1(); | |
289 break; | |
290 case urlStep2: // Step 2. | |
291 chrome.test.log('Step 2. onLoadCommitA'); | |
292 chrome.test.assertTrue(expectAToFireInStep2); | |
293 // Can be called at most once. | |
294 chrome.test.assertFalse(loadCommitACalledStep2); | |
295 loadCommitACalledStep2 = true; | |
296 | |
297 updateTestStateOnListenerStep2(); | |
298 break; | |
299 } | |
300 }; | |
301 | |
302 var onLoadCommitB = function(e) { | |
303 chrome.test.assertEq('loadcommit', e.name); | |
304 switch (e.url) { | |
305 case urlStep1: // Step 1. | |
306 chrome.test.log('Step 1. onLoadCommitB'); | |
307 chrome.test.assertFalse(loadCommitBCalledStep1); | |
308 loadCommitBCalledStep1 = true; | |
309 | |
310 updateTestStateOnListenerStep1(); | |
311 break; | |
312 case urlStep2: // Step 2. | |
313 chrome.test.log('Step 2. onLoadCommitB'); | |
314 chrome.test.assertTrue(expecBToFireInStep2); | |
315 // Can be called at most once. | |
316 chrome.test.assertFalse(loadCommitBCalledStep2); | |
317 loadCommitBCalledStep2 = true; | |
318 | |
319 updateTestStateOnListenerStep2(); | |
320 break; | |
321 } | |
322 }; | |
323 | |
324 var onLoadCommitC = function(e) { | |
325 chrome.test.assertEq('loadcommit', e.name); | |
326 switch (e.url) { | |
327 case urlStep1: // Step 1. | |
328 chrome.test.fail(); | |
329 break; | |
330 case urlStep2: // Step 2. | |
331 chrome.test.log('Step 2. onLoadCommitC'); | |
332 chrome.test.assertFalse(loadCommitCCalledStep2); | |
333 loadCommitCCalledStep2 = true; | |
334 | |
335 updateTestStateOnListenerStep2(); | |
336 break; | |
337 } | |
338 }; | |
339 | |
340 setTimeout(function() { | |
341 // The test starts from here, by setting the src to |urlStep1|. Event | |
342 // listener registration works because we already have a (dummy) src set | |
343 // on the <webview> tag. | |
344 webview.addEventListener('loadcommit', onLoadCommitA); | |
345 webview.addEventListener('loadcommit', onLoadCommitB); | |
346 webview.setAttribute('src', urlStep1); | |
347 }, 0); | |
348 }, | 147 }, |
349 | 148 |
350 // This test registers two event listeners on a same event (loadcommit). | 149 // This test registers two event listeners on a same event (loadcommit). |
351 // Each of the listener tries to change some properties on the event param, | 150 // Each of the listener tries to change some properties on the event param, |
352 // which should not be possible. | 151 // which should not be possible. |
353 function cannotMutateEventName() { | 152 function cannotMutateEventName() { |
354 var webview = util.createWebViewTagInDOM(); | 153 var webview = util.createWebViewTagInDOM(); |
355 var url = 'data:text/html,<body>Two</body>'; | 154 var url = 'data:text/html,<body>Two</body>'; |
356 | 155 |
357 var loadCommitACalled = false; | 156 var loadCommitACalled = false; |
358 var loadCommitBCalled = false; | 157 var loadCommitBCalled = false; |
359 | 158 |
360 var maybeFinishTest = function(e) { | 159 var maybeFinishTest = function(e) { |
361 if (loadCommitACalled && loadCommitBCalled) { | 160 if (loadCommitACalled && loadCommitBCalled) { |
362 chrome.test.assertEq('loadcommit', e.name); | 161 chrome.test.assertEq('loadcommit', e.type); |
363 chrome.test.assertTrue(e.isTopLevel); | |
364 chrome.test.succeed(); | 162 chrome.test.succeed(); |
365 } | 163 } |
366 }; | 164 }; |
367 | 165 |
368 var onLoadCommitA = function(e) { | 166 var onLoadCommitA = function(e) { |
369 if (e.url == url) { | 167 if (e.url == url) { |
370 chrome.test.assertEq('loadcommit', e.name); | 168 chrome.test.assertEq('loadcommit', e.type); |
371 chrome.test.assertTrue(e.isTopLevel); | 169 chrome.test.assertTrue(e.isTopLevel); |
372 chrome.test.assertFalse(loadCommitACalled); | 170 chrome.test.assertFalse(loadCommitACalled); |
373 loadCommitACalled = true; | 171 loadCommitACalled = true; |
374 // Try mucking with properities inside |e|. | 172 // Try mucking with properities inside |e|. |
375 e.name = 'modified'; | 173 e.type = 'modified'; |
376 e.isTopLevel = 'string-value'; | |
377 maybeFinishTest(e); | 174 maybeFinishTest(e); |
378 } | 175 } |
379 }; | 176 }; |
380 var onLoadCommitB = function(e) { | 177 var onLoadCommitB = function(e) { |
381 if (e.url == url) { | 178 if (e.url == url) { |
382 chrome.test.assertEq('loadcommit', e.name); | 179 chrome.test.assertEq('loadcommit', e.type); |
383 chrome.test.assertTrue(e.isTopLevel); | 180 chrome.test.assertTrue(e.isTopLevel); |
384 chrome.test.assertFalse(loadCommitBCalled); | 181 chrome.test.assertFalse(loadCommitBCalled); |
385 loadCommitBCalled = true; | 182 loadCommitBCalled = true; |
386 // Try mucking with properities inside |e|. | 183 // Try mucking with properities inside |e|. |
387 e.name = 'modified'; | 184 e.type = 'modified'; |
388 e.isTopLevel = 'string-value'; | |
389 maybeFinishTest(e); | 185 maybeFinishTest(e); |
390 } | 186 } |
391 }; | 187 }; |
392 | 188 |
393 setTimeout(function() { | 189 setTimeout(function() { |
394 // The test starts from here, by setting the src to |url|. Event | 190 // The test starts from here, by setting the src to |url|. Event |
395 // listener registration works because we already have a (dummy) src set | 191 // listener registration works because we already have a (dummy) src set |
396 // on the <webview> tag. | 192 // on the <webview> tag. |
397 webview.addEventListener('loadcommit', onLoadCommitA); | 193 webview.addEventListener('loadcommit', onLoadCommitA); |
398 webview.addEventListener('loadcommit', onLoadCommitB); | 194 webview.addEventListener('loadcommit', onLoadCommitB); |
399 webview.setAttribute('src', url); | 195 webview.setAttribute('src', url); |
400 }, 0); | 196 }, 0); |
401 } | 197 } |
402 ]); | 198 ]); |
403 }; | 199 }; |
OLD | NEW |