| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 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 | |
| 10 function createWebview() { | |
| 11 var webview = document.createElement('webview'); | |
| 12 document.body.appendChild(webview); | |
| 13 return webview; | |
| 14 } | |
| 15 | |
| 16 function onGetBackgroundExecuted(results) { | |
| 17 chrome.send('testResult', [results.length == 1 && results[0] == 'red']); | |
| 18 }; | |
| 19 | |
| 20 function testExecuteScriptCode(url) { | |
| 21 var webview = createWebview(); | |
| 22 | |
| 23 var onSetBackgroundExecuted = function() { | |
| 24 webview.executeScript({ | |
| 25 code: 'document.body.style.backgroundColor;' | |
| 26 }, onGetBackgroundExecuted); | |
| 27 }; | |
| 28 | |
| 29 var onLoadStop = function() { | |
| 30 webview.executeScript({ | |
| 31 code: 'document.body.style.backgroundColor = \'red\';' | |
| 32 }, onSetBackgroundExecuted); | |
| 33 }; | |
| 34 | |
| 35 webview.addEventListener('loadstop', onLoadStop); | |
| 36 webview.src = url; | |
| 37 } | |
| 38 | |
| 39 function testExecuteScriptCodeFromFile(url) { | |
| 40 var webview = createWebview(); | |
| 41 | |
| 42 var onSetBackgroundExecuted = function() { | |
| 43 webview.executeScript({ | |
| 44 code: 'document.body.style.backgroundColor;' | |
| 45 }, onGetBackgroundExecuted); | |
| 46 }; | |
| 47 | |
| 48 var onLoadStop = function() { | |
| 49 webview.executeScript({ | |
| 50 file: 'test/webview_execute_script.js' | |
| 51 }, onSetBackgroundExecuted); | |
| 52 }; | |
| 53 | |
| 54 webview.addEventListener('loadstop', onLoadStop); | |
| 55 webview.src = url; | |
| 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 |