OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 REQUEST_TO_COMM_CHANNEL_1 = 'connect'; |
| 6 var REQUEST_TO_COMM_CHANNEL_2 = 'connect_request'; |
| 7 var RESPONSE_FROM_COMM_CHANNEL_1 = 'connected'; |
| 8 var RESPONSE_FROM_COMM_CHANNEL_2 = 'connected_response'; |
| 9 |
5 function createWebview() { | 10 function createWebview() { |
6 var webview = document.createElement('webview'); | 11 var webview = document.createElement('webview'); |
7 document.body.appendChild(webview); | 12 document.body.appendChild(webview); |
8 return webview; | 13 return webview; |
9 } | 14 } |
10 | 15 |
11 function onGetBackgroundExecuted(results) { | 16 function onGetBackgroundExecuted(results) { |
12 chrome.send('testResult', [results.length == 1 && results[0] == 'red']); | 17 chrome.send('testResult', [results.length == 1 && results[0] == 'red']); |
13 }; | 18 }; |
14 | 19 |
(...skipping 27 matching lines...) Expand all Loading... |
42 | 47 |
43 var onLoadStop = function() { | 48 var onLoadStop = function() { |
44 webview.executeScript({ | 49 webview.executeScript({ |
45 file: 'test/webview_execute_script.js' | 50 file: 'test/webview_execute_script.js' |
46 }, onSetBackgroundExecuted); | 51 }, onSetBackgroundExecuted); |
47 }; | 52 }; |
48 | 53 |
49 webview.addEventListener('loadstop', onLoadStop); | 54 webview.addEventListener('loadstop', onLoadStop); |
50 webview.src = url; | 55 webview.src = url; |
51 } | 56 } |
| 57 |
| 58 // This test verifies that a content script will be injected to the webview when |
| 59 // the webview is navigated to a page that matches the URL pattern defined in |
| 60 // the content sript. |
| 61 function testAddContentScript(url) { |
| 62 var webview = document.createElement('webview'); |
| 63 |
| 64 console.log('Step 1: call <webview>.addContentScripts.'); |
| 65 webview.addContentScripts( |
| 66 [{'name': 'myrule', |
| 67 'matches': ['http://*/empty*'], |
| 68 'js': ['test/inject_comm_channel.js', 'test/inject_comm_channel_2.js'], |
| 69 'run_at': 'document_start'}]); |
| 70 |
| 71 webview.addEventListener('loadstop', function() { |
| 72 console.log('Step 2: postMessage to build connection.'); |
| 73 var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
| 74 webview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
| 75 }); |
| 76 |
| 77 window.addEventListener('message', function(e) { |
| 78 if (e.source != webview.contentWindow) |
| 79 return; |
| 80 var data = JSON.parse(e.data); |
| 81 if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
| 82 console.log( |
| 83 'Step 3: A communication channel has been established with webview.'); |
| 84 chrome.send('testResult', [true]); |
| 85 return; |
| 86 } |
| 87 console.log('Unexpected message: \'' + data[0] + '\''); |
| 88 chrome.send('testResult', [false]); |
| 89 }); |
| 90 |
| 91 webview.src = url; |
| 92 document.body.appendChild(webview); |
| 93 } |
| 94 |
| 95 // Adds two content scripts with the same URL pattern to <webview> at the same |
| 96 // time. This test verifies that both scripts are injected when the <webview> |
| 97 // navigates to a URL that matches the URL pattern. |
| 98 function testAddMultiContentScripts(url) { |
| 99 var webview = document.createElement('webview'); |
| 100 |
| 101 console.log('Step 1: call <webview>.addContentScripts(myrule1 & myrule2)'); |
| 102 webview.addContentScripts( |
| 103 [{'name': 'myrule1', |
| 104 'matches': ['http://*/empty*'], |
| 105 'js': ['test/inject_comm_channel.js'], |
| 106 'run_at': 'document_start'}, |
| 107 {'name': 'myrule2', |
| 108 'matches': ['http://*/empty*'], |
| 109 'js': ['test/inject_comm_channel_2.js'], |
| 110 'run_at': 'document_start'}]); |
| 111 |
| 112 webview.addEventListener('loadstop', function() { |
| 113 console.log('Step 2: postMessage to build connection.'); |
| 114 var msg1 = [REQUEST_TO_COMM_CHANNEL_1]; |
| 115 webview.contentWindow.postMessage(JSON.stringify(msg1), '*'); |
| 116 console.log('Step 3: postMessage to build connection to the other script.'); |
| 117 var msg2 = [REQUEST_TO_COMM_CHANNEL_2]; |
| 118 webview.contentWindow.postMessage(JSON.stringify(msg2), '*'); |
| 119 }); |
| 120 |
| 121 var response_1 = false; |
| 122 var response_2 = false; |
| 123 window.addEventListener('message', function(e) { |
| 124 if (e.source != webview.contentWindow) |
| 125 return; |
| 126 var data = JSON.parse(e.data); |
| 127 if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
| 128 console.log( |
| 129 'Step 4: A communication channel has been established with webview.'); |
| 130 response_1 = true; |
| 131 if (response_1 && response_2) |
| 132 chrome.send('testResult', [true]); |
| 133 return; |
| 134 } else if (data == RESPONSE_FROM_COMM_CHANNEL_2) { |
| 135 console.log( |
| 136 'Step 5: A communication channel has been established with webview.'); |
| 137 response_2 = true; |
| 138 if (response_1 && response_2) |
| 139 chrome.send('testResult', [true]); |
| 140 return; |
| 141 } |
| 142 console.log('Unexpected message: \'' + data[0] + '\''); |
| 143 chrome.send('testResult', [false]); |
| 144 }); |
| 145 |
| 146 webview.src = url; |
| 147 document.body.appendChild(webview); |
| 148 } |
| 149 |
| 150 // Adds a content script to <webview> and navigates. After seeing the script is |
| 151 // injected, we add another content script with the same name to the <webview>. |
| 152 // This test verifies that the second script will replace the first one and be |
| 153 // injected after navigating the <webview>. Meanwhile, the <webview> shouldn't |
| 154 // get any message from the first script anymore. |
| 155 function testAddContentScriptWithSameNameShouldOverwriteTheExistingOne(url) { |
| 156 var webview = document.createElement('webview'); |
| 157 |
| 158 console.log('Step 1: call <webview>.addContentScripts(myrule1)'); |
| 159 webview.addContentScripts( |
| 160 [{'name': 'myrule1', |
| 161 'matches': ['http://*/empty*'], |
| 162 'js': ['test/inject_comm_channel.js'], |
| 163 'run_at': 'document_start'}]); |
| 164 var connect_script_1 = true; |
| 165 var connect_script_2 = false; |
| 166 |
| 167 webview.addEventListener('loadstop', function() { |
| 168 if (connect_script_1) { |
| 169 var msg1 = [REQUEST_TO_COMM_CHANNEL_1]; |
| 170 webview.contentWindow.postMessage(JSON.stringify(msg1), '*'); |
| 171 connect_script_1 = false; |
| 172 } |
| 173 if (connect_script_2) { |
| 174 var msg2 = [REQUEST_TO_COMM_CHANNEL_2]; |
| 175 webview.contentWindow.postMessage(JSON.stringify(msg2), '*'); |
| 176 connect_script_2 = false; |
| 177 } |
| 178 }); |
| 179 |
| 180 var should_get_response_from_script_1 = true; |
| 181 window.addEventListener('message', function(e) { |
| 182 if (e.source != webview.contentWindow) |
| 183 return; |
| 184 var data = JSON.parse(e.data); |
| 185 if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
| 186 if (should_get_response_from_script_1) { |
| 187 console.log( |
| 188 'Step 2: A communication channel has been established with webview.' |
| 189 ); |
| 190 console.log('Step 3: <webview>.addContentScripts() with a updated' + |
| 191 ' \'myrule1\''); |
| 192 webview.addContentScripts( |
| 193 [{'name': 'myrule1', |
| 194 'matches': ['http://*/empty*'], |
| 195 'js': ['test/inject_comm_channel_2.js'], |
| 196 'run_at': 'document_start'}]); |
| 197 connect_script_2 = true; |
| 198 should_get_response_from_script_1 = false; |
| 199 webview.src = url; |
| 200 } else { |
| 201 chrome.send('testResult', [false]); |
| 202 } |
| 203 return; |
| 204 } else if (data == RESPONSE_FROM_COMM_CHANNEL_2) { |
| 205 console.log( |
| 206 'Step 4: Another communication channel has been established ' + |
| 207 'with webview.'); |
| 208 setTimeout(function() { |
| 209 chrome.send('testResult', [true]); |
| 210 }, 0); |
| 211 return; |
| 212 } |
| 213 console.log('Unexpected message: \'' + data[0] + '\''); |
| 214 chrome.send('testResult', [false]); |
| 215 }); |
| 216 |
| 217 webview.src = url; |
| 218 document.body.appendChild(webview); |
| 219 } |
| 220 |
| 221 // There are two <webview>s are added to the DOM, and we add a content script |
| 222 // to one of them. This test verifies that the script won't be injected in |
| 223 // the other <webview>. |
| 224 function testAddContentScriptToOneWebViewShouldNotInjectToTheOtherWebView(url) { |
| 225 var webview1 = document.createElement('webview'); |
| 226 var webview2 = document.createElement('webview'); |
| 227 |
| 228 console.log('Step 1: call <webview1>.addContentScripts.'); |
| 229 webview1.addContentScripts( |
| 230 [{'name': 'myrule', |
| 231 'matches': ['http://*/empty*'], |
| 232 'js': ['test/inject_comm_channel.js'], |
| 233 'run_at': 'document_start'}]); |
| 234 |
| 235 webview2.addEventListener('loadstop', function() { |
| 236 console.log('Step 2: webview2 requests to build communication channel.'); |
| 237 var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
| 238 webview2.contentWindow.postMessage(JSON.stringify(msg), '*'); |
| 239 setTimeout(function() { |
| 240 chrome.send('testResult', [true]); |
| 241 }, 0); |
| 242 }); |
| 243 |
| 244 window.addEventListener('message', function(e) { |
| 245 if (e.source != webview2.contentWindow) |
| 246 return; |
| 247 var data = JSON.parse(e.data); |
| 248 if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
| 249 chrome.send('testResult', [false]); |
| 250 return; |
| 251 } |
| 252 console.log('Unexpected message: \'' + data[0] + '\''); |
| 253 chrome.send('testResult', [false]); |
| 254 }); |
| 255 |
| 256 webview1.src = url; |
| 257 webview2.src = url; |
| 258 document.body.appendChild(webview1); |
| 259 document.body.appendChild(webview2); |
| 260 } |
| 261 |
| 262 // Adds a content script to <webview> and navigates to a URL that matches the |
| 263 // URL pattern defined in the script. After the first navigation, we remove this |
| 264 // script from the <webview> and navigates to the same URL. This test verifies |
| 265 // taht the script is injected during the first navigation, but isn't injected |
| 266 // after removing it. |
| 267 function testAddAndRemoveContentScripts(url) { |
| 268 var webview = document.createElement('webview'); |
| 269 |
| 270 console.log('Step 1: call <webview>.addContentScripts.'); |
| 271 webview.addContentScripts( |
| 272 [{'name': 'myrule', |
| 273 'matches': ['http://*/empty*'], |
| 274 'js': ['test/inject_comm_channel.js'], |
| 275 'run_at': 'document_start'}]); |
| 276 |
| 277 var should_get_response_from_script_1 = true; |
| 278 |
| 279 var count = 0; |
| 280 webview.addEventListener('loadstop', function() { |
| 281 if (count == 0) { |
| 282 console.log('Step 2: post message to build connect.'); |
| 283 var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
| 284 webview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
| 285 ++count; |
| 286 } else if (count == 1) { |
| 287 console.log('Step 5: post message to build connect again.'); |
| 288 var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
| 289 webview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
| 290 setTimeout(function() { |
| 291 chrome.send('testResult', [true]); |
| 292 }, 0); |
| 293 } |
| 294 }); |
| 295 |
| 296 window.addEventListener('message', function(e) { |
| 297 if (e.source != webview.contentWindow) |
| 298 return; |
| 299 var data = JSON.parse(e.data); |
| 300 if (data[0] == RESPONSE_FROM_COMM_CHANNEL_1 && |
| 301 should_get_response_from_script_1) { |
| 302 console.log('Step 3: A communication channel has been established ' + |
| 303 'with webview.'); |
| 304 should_get_response_from_script_1 = false; |
| 305 console.log( |
| 306 'Step 4: call <webview>.removeContentScripts and navigate.'); |
| 307 webview.removeContentScripts(); |
| 308 webview.src = url; |
| 309 return; |
| 310 } |
| 311 console.log('Unexpected message: \'' + data[0] + '\''); |
| 312 chrome.send('testResult', [false]); |
| 313 }); |
| 314 |
| 315 webview.src = url; |
| 316 document.body.appendChild(webview); |
| 317 } |
| 318 |
| 319 // This test verifies that the addContentScripts API works with the new window |
| 320 // API. |
| 321 function testAddContentScriptsWithNewWindowAPI(url) { |
| 322 var webview = document.createElement('webview'); |
| 323 |
| 324 var newwebview; |
| 325 webview.addEventListener('newwindow', function(e) { |
| 326 e.preventDefault(); |
| 327 newwebview = document.createElement('webview'); |
| 328 |
| 329 console.log('Step 2: call newwebview.addContentScripts.'); |
| 330 newwebview.addContentScripts( |
| 331 [{'name': 'myrule', |
| 332 'matches': ['http://*/guest_from_opener*'], |
| 333 'js': ['test/inject_comm_channel.js'], |
| 334 'run_at': 'document_start'}]); |
| 335 |
| 336 newwebview.addEventListener('loadstop', function(evt) { |
| 337 var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
| 338 console.log('Step 4: new webview postmessage to build communication ' + |
| 339 'channel.'); |
| 340 newwebview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
| 341 }); |
| 342 |
| 343 document.body.appendChild(newwebview); |
| 344 // attach the new window to the new <webview>. |
| 345 console.log('Step 3: attaches the new webview.'); |
| 346 e.window.attach(newwebview); |
| 347 }); |
| 348 |
| 349 window.addEventListener('message', function(e) { |
| 350 if (e.source != newwebview.contentWindow) |
| 351 return; |
| 352 var data = JSON.parse(e.data); |
| 353 if (data == RESPONSE_FROM_COMM_CHANNEL_1 && |
| 354 e.source == newwebview.contentWindow) { |
| 355 console.log('Step 5: a communication channel has been established ' + |
| 356 'with the new webview.'); |
| 357 chrome.send('testResult', [true]); |
| 358 return; |
| 359 } else { |
| 360 chrome.send('testResult', [false]); |
| 361 return; |
| 362 } |
| 363 console.log('Unexpected message: \'' + data[0] + '\''); |
| 364 chrome.send('testResult', [false]); |
| 365 }); |
| 366 |
| 367 console.log('Step 1: navigates the webview to window open guest URL.'); |
| 368 webview.setAttribute('src', url); |
| 369 document.body.appendChild(webview); |
| 370 } |
| 371 |
| 372 // Adds a content script to <webview>. This test verifies that the script is |
| 373 // injected after terminate and reload <webview>. |
| 374 function testContentScriptIsInjectedAfterTerminateAndReloadWebView(url) { |
| 375 var webview = document.createElement('webview'); |
| 376 |
| 377 console.log('Step 1: call <webview>.addContentScripts.'); |
| 378 webview.addContentScripts( |
| 379 [{'name': 'myrule', |
| 380 'matches': ['http://*/empty*'], |
| 381 'js': ['test/webview_execute_script.js'], |
| 382 'run_at': 'document_end'}]); |
| 383 |
| 384 var count = 0; |
| 385 webview.addEventListener('loadstop', function() { |
| 386 if (count == 0) { |
| 387 console.log('Step 2: call webview.terminate().'); |
| 388 webview.terminate(); |
| 389 ++count; |
| 390 return; |
| 391 } else if (count == 1) { |
| 392 console.log('Step 4: call <webview>.executeScript to check result.'); |
| 393 webview.executeScript({ |
| 394 code: 'document.body.style.backgroundColor;' |
| 395 }, onGetBackgroundExecuted); |
| 396 } |
| 397 }); |
| 398 |
| 399 webview.addEventListener('exit', function() { |
| 400 console.log('Step 3: call webview.reload().'); |
| 401 webview.reload(); |
| 402 }); |
| 403 |
| 404 webview.src = url; |
| 405 document.body.appendChild(webview); |
| 406 } |
| 407 |
| 408 // This test verifies the content script won't be removed when the guest is |
| 409 // destroyed, i.e., removed <webview> from the DOM. |
| 410 function testContentScriptExistsAsLongAsWebViewTagExists(url) { |
| 411 var webview = document.createElement('webview'); |
| 412 |
| 413 console.log('Step 1: call <webview>.addContentScripts.'); |
| 414 webview.addContentScripts( |
| 415 [{'name': 'myrule', |
| 416 'matches': ['http://*/empty*'], |
| 417 'js': ['test/webview_execute_script.js'], |
| 418 'run_at': 'document_end'}]); |
| 419 |
| 420 var count = 0; |
| 421 webview.addEventListener('loadstop', function() { |
| 422 if (count == 0) { |
| 423 console.log('Step 2: check the result of content script injected.'); |
| 424 webview.executeScript({ |
| 425 code: 'document.body.style.backgroundColor;' |
| 426 }, function(results) { |
| 427 assertEquals(1, results.length); |
| 428 assertEquals('red', results[0]); |
| 429 |
| 430 console.log('Step 3: remove webview from the DOM.'); |
| 431 document.body.removeChild(webview); |
| 432 console.log('Step 4: add webview back to the DOM.'); |
| 433 document.body.appendChild(webview); |
| 434 ++count; |
| 435 }); |
| 436 } else if (count == 1) { |
| 437 console.log('Step 5: check the result of content script injected again.'); |
| 438 webview.executeScript({ |
| 439 code: 'document.body.style.backgroundColor;' |
| 440 }, onGetBackgroundExecuted); |
| 441 } |
| 442 }); |
| 443 |
| 444 webview.src = url; |
| 445 document.body.appendChild(webview); |
| 446 } |
OLD | NEW |