Index: chrome/test/data/webui/webview_execute_script_test.js |
diff --git a/chrome/test/data/webui/webview_execute_script_test.js b/chrome/test/data/webui/webview_execute_script_test.js |
index 5485904dbba3086dfedfc3daab2b81433c21dd04..277c12ff565bf9fabc6549bb41f80abdd9e46306 100644 |
--- a/chrome/test/data/webui/webview_execute_script_test.js |
+++ b/chrome/test/data/webui/webview_execute_script_test.js |
@@ -2,6 +2,11 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+var REQUEST_TO_COMM_CHANNEL_1 = 'connect'; |
+var REQUEST_TO_COMM_CHANNEL_2 = 'connect_request'; |
+var RESPONSE_FROM_COMM_CHANNEL_1 = 'connected'; |
+var RESPONSE_FROM_COMM_CHANNEL_2 = 'connected_response'; |
+ |
function createWebview() { |
var webview = document.createElement('webview'); |
document.body.appendChild(webview); |
@@ -49,3 +54,393 @@ function testExecuteScriptCodeFromFile(url) { |
webview.addEventListener('loadstop', onLoadStop); |
webview.src = url; |
} |
+ |
+// This test verifies that a content script will be injected to the webview when |
+// the webview is navigated to a page that matches the URL pattern defined in |
+// the content sript. |
+function testAddContentScript(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview>.addContentScripts.'); |
+ webview.addContentScripts( |
+ [{'name': 'myrule', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel.js', 'test/inject_comm_channel_2.js'], |
+ 'run_at': 'document_start'}]); |
+ |
+ webview.addEventListener('loadstop', function() { |
+ console.log('Step 2: postMessage to build connection.'); |
+ var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
+ }); |
+ |
+ window.addEventListener('message', function(e) { |
+ if (e.source != webview.contentWindow) |
+ return; |
+ var data = JSON.parse(e.data); |
+ if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
+ console.log( |
+ 'Step 3: A communication channel has been established with webview.'); |
+ chrome.send('testResult', [true]); |
+ return; |
+ } |
+ console.log('Unexpected message: \'' + data[0] + '\''); |
+ chrome.send('testResult', [false]); |
+ }); |
+ |
+ webview.src = url; |
+ document.body.appendChild(webview); |
+} |
+ |
+// Adds two content scripts with the same URL pattern to <webview> at the same |
+// time. This test verifies that both scripts are injected when the <webview> |
+// navigates to a URL that matches the URL pattern. |
+function testAddMultiContentScripts(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview>.addContentScripts(myrule1 & myrule2)'); |
+ webview.addContentScripts( |
+ [{'name': 'myrule1', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel.js'], |
+ 'run_at': 'document_start'}, |
+ {'name': 'myrule2', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel_2.js'], |
+ 'run_at': 'document_start'}]); |
+ |
+ webview.addEventListener('loadstop', function() { |
+ console.log('Step 2: postMessage to build connection.'); |
+ var msg1 = [REQUEST_TO_COMM_CHANNEL_1]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg1), '*'); |
+ console.log('Step 3: postMessage to build connection to the other script.'); |
+ var msg2 = [REQUEST_TO_COMM_CHANNEL_2]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg2), '*'); |
+ }); |
+ |
+ var response_1 = false; |
+ var response_2 = false; |
+ window.addEventListener('message', function(e) { |
+ if (e.source != webview.contentWindow) |
+ return; |
+ var data = JSON.parse(e.data); |
+ if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
+ console.log( |
+ 'Step 4: A communication channel has been established with webview.'); |
+ response_1 = true; |
+ if (response_1 && response_2) |
+ chrome.send('testResult', [true]); |
+ return; |
+ } else if (data == RESPONSE_FROM_COMM_CHANNEL_2) { |
+ console.log( |
+ 'Step 5: A communication channel has been established with webview.'); |
+ response_2 = true; |
+ if (response_1 && response_2) |
+ chrome.send('testResult', [true]); |
+ return; |
+ } |
+ console.log('Unexpected message: \'' + data[0] + '\''); |
+ chrome.send('testResult', [false]); |
+ }); |
+ |
+ webview.src = url; |
+ document.body.appendChild(webview); |
+} |
+ |
+// Adds a content script to <webview> and navigates. After seeing the script is |
+// injected, we add another content script with the same name to the <webview>. |
+// This test verifies that the second script will replace the first one and be |
+// injected after navigating the <webview>. Meanwhile, the <webview> shouldn't |
+// get any message from the first script anymore. |
+function testAddContentScriptWithSameNameShouldOverwriteTheExistingOne(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview>.addContentScripts(myrule1)'); |
+ webview.addContentScripts( |
+ [{'name': 'myrule1', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel.js'], |
+ 'run_at': 'document_start'}]); |
+ var connect_script_1 = true; |
+ var connect_script_2 = false; |
+ |
+ webview.addEventListener('loadstop', function() { |
+ if (connect_script_1) { |
+ var msg1 = [REQUEST_TO_COMM_CHANNEL_1]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg1), '*'); |
+ connect_script_1 = false; |
+ } |
+ if (connect_script_2) { |
+ var msg2 = [REQUEST_TO_COMM_CHANNEL_2]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg2), '*'); |
+ connect_script_2 = false; |
+ } |
+ }); |
+ |
+ var should_get_response_from_script_1 = true; |
+ window.addEventListener('message', function(e) { |
+ if (e.source != webview.contentWindow) |
+ return; |
+ var data = JSON.parse(e.data); |
+ if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
+ if (should_get_response_from_script_1) { |
+ console.log( |
+ 'Step 2: A communication channel has been established with webview.' |
+ ); |
+ console.log('Step 3: <webview>.addContentScripts() with a updated' + |
+ ' \'myrule1\''); |
+ webview.addContentScripts( |
+ [{'name': 'myrule1', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel_2.js'], |
+ 'run_at': 'document_start'}]); |
+ connect_script_2 = true; |
+ should_get_response_from_script_1 = false; |
+ webview.src = url; |
+ } else { |
+ chrome.send('testResult', [false]); |
+ } |
+ return; |
+ } else if (data == RESPONSE_FROM_COMM_CHANNEL_2) { |
+ console.log( |
+ 'Step 4: Another communication channel has been established ' + |
+ 'with webview.'); |
+ setTimeout(function() { |
+ chrome.send('testResult', [true]); |
+ }, 0); |
+ return; |
+ } |
+ console.log('Unexpected message: \'' + data[0] + '\''); |
+ chrome.send('testResult', [false]); |
+ }); |
+ |
+ webview.src = url; |
+ document.body.appendChild(webview); |
+} |
+ |
+// There are two <webview>s are added to the DOM, and we add a content script |
+// to one of them. This test verifies that the script won't be injected in |
+// the other <webview>. |
+function testAddContentScriptToOneWebViewShouldNotInjectToTheOtherWebView(url) { |
+ var webview1 = document.createElement('webview'); |
+ var webview2 = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview1>.addContentScripts.'); |
+ webview1.addContentScripts( |
+ [{'name': 'myrule', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel.js'], |
+ 'run_at': 'document_start'}]); |
+ |
+ webview2.addEventListener('loadstop', function() { |
+ console.log('Step 2: webview2 requests to build communication channel.'); |
+ var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
+ webview2.contentWindow.postMessage(JSON.stringify(msg), '*'); |
+ setTimeout(function() { |
+ chrome.send('testResult', [true]); |
+ }, 0); |
+ }); |
+ |
+ window.addEventListener('message', function(e) { |
+ if (e.source != webview2.contentWindow) |
+ return; |
+ var data = JSON.parse(e.data); |
+ if (data == RESPONSE_FROM_COMM_CHANNEL_1) { |
+ chrome.send('testResult', [false]); |
+ return; |
+ } |
+ console.log('Unexpected message: \'' + data[0] + '\''); |
+ chrome.send('testResult', [false]); |
+ }); |
+ |
+ webview1.src = url; |
+ webview2.src = url; |
+ document.body.appendChild(webview1); |
+ document.body.appendChild(webview2); |
+} |
+ |
+// Adds a content script to <webview> and navigates to a URL that matches the |
+// URL pattern defined in the script. After the first navigation, we remove this |
+// script from the <webview> and navigates to the same URL. This test verifies |
+// taht the script is injected during the first navigation, but isn't injected |
+// after removing it. |
+function testAddAndRemoveContentScripts(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview>.addContentScripts.'); |
+ webview.addContentScripts( |
+ [{'name': 'myrule', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/inject_comm_channel.js'], |
+ 'run_at': 'document_start'}]); |
+ |
+ var should_get_response_from_script_1 = true; |
+ |
+ var count = 0; |
+ webview.addEventListener('loadstop', function() { |
+ if (count == 0) { |
+ console.log('Step 2: post message to build connect.'); |
+ var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
+ ++count; |
+ } else if (count == 1) { |
+ console.log('Step 5: post message to build connect again.'); |
+ var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
+ webview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
+ setTimeout(function() { |
+ chrome.send('testResult', [true]); |
+ }, 0); |
+ } |
+ }); |
+ |
+ window.addEventListener('message', function(e) { |
+ if (e.source != webview.contentWindow) |
+ return; |
+ var data = JSON.parse(e.data); |
+ if (data[0] == RESPONSE_FROM_COMM_CHANNEL_1 && |
+ should_get_response_from_script_1) { |
+ console.log('Step 3: A communication channel has been established ' + |
+ 'with webview.'); |
+ should_get_response_from_script_1 = false; |
+ console.log( |
+ 'Step 4: call <webview>.removeContentScripts and navigate.'); |
+ webview.removeContentScripts(); |
+ webview.src = url; |
+ return; |
+ } |
+ console.log('Unexpected message: \'' + data[0] + '\''); |
+ chrome.send('testResult', [false]); |
+ }); |
+ |
+ webview.src = url; |
+ document.body.appendChild(webview); |
+} |
+ |
+// This test verifies that the addContentScripts API works with the new window |
+// API. |
+function testAddContentScriptsWithNewWindowAPI(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ var newwebview; |
+ webview.addEventListener('newwindow', function(e) { |
+ e.preventDefault(); |
+ newwebview = document.createElement('webview'); |
+ |
+ console.log('Step 2: call newwebview.addContentScripts.'); |
+ newwebview.addContentScripts( |
+ [{'name': 'myrule', |
+ 'matches': ['http://*/guest_from_opener*'], |
+ 'js': ['test/inject_comm_channel.js'], |
+ 'run_at': 'document_start'}]); |
+ |
+ newwebview.addEventListener('loadstop', function(evt) { |
+ var msg = [REQUEST_TO_COMM_CHANNEL_1]; |
+ console.log('Step 4: new webview postmessage to build communication ' + |
+ 'channel.'); |
+ newwebview.contentWindow.postMessage(JSON.stringify(msg), '*'); |
+ }); |
+ |
+ document.body.appendChild(newwebview); |
+ // attach the new window to the new <webview>. |
+ console.log('Step 3: attaches the new webview.'); |
+ e.window.attach(newwebview); |
+ }); |
+ |
+ window.addEventListener('message', function(e) { |
+ if (e.source != newwebview.contentWindow) |
+ return; |
+ var data = JSON.parse(e.data); |
+ if (data == RESPONSE_FROM_COMM_CHANNEL_1 && |
+ e.source == newwebview.contentWindow) { |
+ console.log('Step 5: a communication channel has been established ' + |
+ 'with the new webview.'); |
+ chrome.send('testResult', [true]); |
+ return; |
+ } else { |
+ chrome.send('testResult', [false]); |
+ return; |
+ } |
+ console.log('Unexpected message: \'' + data[0] + '\''); |
+ chrome.send('testResult', [false]); |
+ }); |
+ |
+ console.log('Step 1: navigates the webview to window open guest URL.'); |
+ webview.setAttribute('src', url); |
+ document.body.appendChild(webview); |
+} |
+ |
+// Adds a content script to <webview>. This test verifies that the script is |
+// injected after terminate and reload <webview>. |
+function testContentScriptIsInjectedAfterTerminateAndReloadWebView(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview>.addContentScripts.'); |
+ webview.addContentScripts( |
+ [{'name': 'myrule', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/webview_execute_script.js'], |
+ 'run_at': 'document_end'}]); |
+ |
+ var count = 0; |
+ webview.addEventListener('loadstop', function() { |
+ if (count == 0) { |
+ console.log('Step 2: call webview.terminate().'); |
+ webview.terminate(); |
+ ++count; |
+ return; |
+ } else if (count == 1) { |
+ console.log('Step 4: call <webview>.executeScript to check result.'); |
+ webview.executeScript({ |
+ code: 'document.body.style.backgroundColor;' |
+ }, onGetBackgroundExecuted); |
+ } |
+ }); |
+ |
+ webview.addEventListener('exit', function() { |
+ console.log('Step 3: call webview.reload().'); |
+ webview.reload(); |
+ }); |
+ |
+ webview.src = url; |
+ document.body.appendChild(webview); |
+} |
+ |
+// This test verifies the content script won't be removed when the guest is |
+// destroyed, i.e., removed <webview> from the DOM. |
+function testContentScriptExistsAsLongAsWebViewTagExists(url) { |
+ var webview = document.createElement('webview'); |
+ |
+ console.log('Step 1: call <webview>.addContentScripts.'); |
+ webview.addContentScripts( |
+ [{'name': 'myrule', |
+ 'matches': ['http://*/empty*'], |
+ 'js': ['test/webview_execute_script.js'], |
+ 'run_at': 'document_end'}]); |
+ |
+ var count = 0; |
+ webview.addEventListener('loadstop', function() { |
+ if (count == 0) { |
+ console.log('Step 2: check the result of content script injected.'); |
+ webview.executeScript({ |
+ code: 'document.body.style.backgroundColor;' |
+ }, function(results) { |
+ assertEquals(1, results.length); |
+ assertEquals('red', results[0]); |
+ |
+ console.log('Step 3: remove webview from the DOM.'); |
+ document.body.removeChild(webview); |
+ console.log('Step 4: add webview back to the DOM.'); |
+ document.body.appendChild(webview); |
+ ++count; |
+ }); |
+ } else if (count == 1) { |
+ console.log('Step 5: check the result of content script injected again.'); |
+ webview.executeScript({ |
+ code: 'document.body.style.backgroundColor;' |
+ }, onGetBackgroundExecuted); |
+ } |
+ }); |
+ |
+ webview.src = url; |
+ document.body.appendChild(webview); |
+} |