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.
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';
10 function createWebview() {
11 var webview
= document
.createElement('webview');
12 document
.body
.appendChild(webview
);
16 function onGetBackgroundExecuted(results
) {
17 chrome
.send('testResult', [results
.length
== 1 && results
[0] == 'red']);
20 function testExecuteScriptCode(url
) {
21 var webview
= createWebview();
23 var onSetBackgroundExecuted = function() {
24 webview
.executeScript({
25 code
: 'document.body.style.backgroundColor;'
26 }, onGetBackgroundExecuted
);
29 var onLoadStop = function() {
30 webview
.executeScript({
31 code
: 'document.body.style.backgroundColor = \'red\';'
32 }, onSetBackgroundExecuted
);
35 webview
.addEventListener('loadstop', onLoadStop
);
39 function testExecuteScriptCodeFromFile(url
) {
40 var webview
= createWebview();
42 var onSetBackgroundExecuted = function() {
43 webview
.executeScript({
44 code
: 'document.body.style.backgroundColor;'
45 }, onGetBackgroundExecuted
);
48 var onLoadStop = function() {
49 webview
.executeScript({
50 file
: 'test/webview_execute_script.js'
51 }, onSetBackgroundExecuted
);
54 webview
.addEventListener('loadstop', onLoadStop
);
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
61 function testAddContentScript(url
) {
62 var webview
= document
.createElement('webview');
64 console
.log('Step 1: call <webview>.addContentScripts.');
65 webview
.addContentScripts(
67 'matches': ['http://*/empty*'],
68 'js': ['test/inject_comm_channel.js', 'test/inject_comm_channel_2.js'],
69 'run_at': 'document_start'}]);
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
), '*');
77 window
.addEventListener('message', function(e
) {
78 if (e
.source
!= webview
.contentWindow
)
80 var data
= JSON
.parse(e
.data
);
81 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
83 'Step 3: A communication channel has been established with webview.');
84 chrome
.send('testResult', [true]);
87 console
.log('Unexpected message: \'' + data
[0] + '\'');
88 chrome
.send('testResult', [false]);
92 document
.body
.appendChild(webview
);
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');
101 console
.log('Step 1: call <webview>.addContentScripts(myrule1 & myrule2)');
102 webview
.addContentScripts(
104 'matches': ['http://*/empty*'],
105 'js': ['test/inject_comm_channel.js'],
106 'run_at': 'document_start'},
108 'matches': ['http://*/empty*'],
109 'js': ['test/inject_comm_channel_2.js'],
110 'run_at': 'document_start'}]);
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
), '*');
121 var response_1
= false;
122 var response_2
= false;
123 window
.addEventListener('message', function(e
) {
124 if (e
.source
!= webview
.contentWindow
)
126 var data
= JSON
.parse(e
.data
);
127 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
129 'Step 4: A communication channel has been established with webview.');
131 if (response_1
&& response_2
)
132 chrome
.send('testResult', [true]);
134 } else if (data
== RESPONSE_FROM_COMM_CHANNEL_2
) {
136 'Step 5: A communication channel has been established with webview.');
138 if (response_1
&& response_2
)
139 chrome
.send('testResult', [true]);
142 console
.log('Unexpected message: \'' + data
[0] + '\'');
143 chrome
.send('testResult', [false]);
147 document
.body
.appendChild(webview
);
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');
158 console
.log('Step 1: call <webview>.addContentScripts(myrule1)');
159 webview
.addContentScripts(
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;
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;
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;
180 var should_get_response_from_script_1
= true;
181 window
.addEventListener('message', function(e
) {
182 if (e
.source
!= webview
.contentWindow
)
184 var data
= JSON
.parse(e
.data
);
185 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
186 if (should_get_response_from_script_1
) {
188 'Step 2: A communication channel has been established with webview.'
190 console
.log('Step 3: <webview>.addContentScripts() with a updated' +
192 webview
.addContentScripts(
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;
201 chrome
.send('testResult', [false]);
204 } else if (data
== RESPONSE_FROM_COMM_CHANNEL_2
) {
206 'Step 4: Another communication channel has been established ' +
208 setTimeout(function() {
209 chrome
.send('testResult', [true]);
213 console
.log('Unexpected message: \'' + data
[0] + '\'');
214 chrome
.send('testResult', [false]);
218 document
.body
.appendChild(webview
);
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');
228 console
.log('Step 1: call <webview1>.addContentScripts.');
229 webview1
.addContentScripts(
231 'matches': ['http://*/empty*'],
232 'js': ['test/inject_comm_channel.js'],
233 'run_at': 'document_start'}]);
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]);
244 window
.addEventListener('message', function(e
) {
245 if (e
.source
!= webview2
.contentWindow
)
247 var data
= JSON
.parse(e
.data
);
248 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
249 chrome
.send('testResult', [false]);
252 console
.log('Unexpected message: \'' + data
[0] + '\'');
253 chrome
.send('testResult', [false]);
258 document
.body
.appendChild(webview1
);
259 document
.body
.appendChild(webview2
);
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');
270 console
.log('Step 1: call <webview>.addContentScripts.');
271 webview
.addContentScripts(
273 'matches': ['http://*/empty*'],
274 'js': ['test/inject_comm_channel.js'],
275 'run_at': 'document_start'}]);
277 var should_get_response_from_script_1
= true;
280 webview
.addEventListener('loadstop', function() {
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
), '*');
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]);
296 window
.addEventListener('message', function(e
) {
297 if (e
.source
!= webview
.contentWindow
)
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 ' +
304 should_get_response_from_script_1
= false;
306 'Step 4: call <webview>.removeContentScripts and navigate.');
307 webview
.removeContentScripts();
311 console
.log('Unexpected message: \'' + data
[0] + '\'');
312 chrome
.send('testResult', [false]);
316 document
.body
.appendChild(webview
);
319 // This test verifies that the addContentScripts API works with the new window
321 function testAddContentScriptsWithNewWindowAPI(url
) {
322 var webview
= document
.createElement('webview');
325 webview
.addEventListener('newwindow', function(e
) {
327 newwebview
= document
.createElement('webview');
329 console
.log('Step 2: call newwebview.addContentScripts.');
330 newwebview
.addContentScripts(
332 'matches': ['http://*/guest_from_opener*'],
333 'js': ['test/inject_comm_channel.js'],
334 'run_at': 'document_start'}]);
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 ' +
340 newwebview
.contentWindow
.postMessage(JSON
.stringify(msg
), '*');
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
);
349 window
.addEventListener('message', function(e
) {
350 if (!newwebview
|| e
.source
!= newwebview
.contentWindow
)
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]);
360 chrome
.send('testResult', [false]);
363 console
.log('Unexpected message: \'' + data
[0] + '\'');
364 chrome
.send('testResult', [false]);
367 console
.log('Step 1: navigates the webview to window open guest URL.');
368 webview
.setAttribute('src', url
);
369 document
.body
.appendChild(webview
);
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');
377 console
.log('Step 1: call <webview>.addContentScripts.');
378 webview
.addContentScripts(
380 'matches': ['http://*/empty*'],
381 'js': ['test/webview_execute_script.js'],
382 'run_at': 'document_end'}]);
385 webview
.addEventListener('loadstop', function() {
387 console
.log('Step 2: call webview.terminate().');
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
);
399 webview
.addEventListener('exit', function() {
400 console
.log('Step 3: call webview.reload().');
405 document
.body
.appendChild(webview
);
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');
413 console
.log('Step 1: call <webview>.addContentScripts.');
414 webview
.addContentScripts(
416 'matches': ['http://*/empty*'],
417 'js': ['test/webview_execute_script.js'],
418 'run_at': 'document_end'}]);
421 webview
.addEventListener('loadstop', function() {
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]);
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
);
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
);
445 document
.body
.appendChild(webview
);
448 function testAddContentScriptWithCode(url
) {
449 var webview
= document
.createElement('webview');
451 console
.log('Step 1: call <webview>.addContentScripts.');
452 webview
.addContentScripts(
454 'matches': ['http://*/empty*'],
455 'code': 'document.body.style.backgroundColor = \'red\';',
456 'run_at': 'document_end'}]);
458 webview
.addEventListener('loadstop', function() {
459 console
.log('Step 2: call webview.executeScript() to check result.')
460 webview
.executeScript({
461 code
: 'document.body.style.backgroundColor;'
462 }, onGetBackgroundExecuted
);
466 document
.body
.appendChild(webview
);