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*'],
69 files
: ['test/inject_comm_channel.js',
70 'test/inject_comm_channel_2.js']
72 run_at
: 'document_start'}]);
74 webview
.addEventListener('loadstop', function() {
75 console
.log('Step 2: postMessage to build connection.');
76 var msg
= [REQUEST_TO_COMM_CHANNEL_1
];
77 webview
.contentWindow
.postMessage(JSON
.stringify(msg
), '*');
80 window
.addEventListener('message', function(e
) {
81 if (e
.source
!= webview
.contentWindow
)
83 var data
= JSON
.parse(e
.data
);
84 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
86 'Step 3: A communication channel has been established with webview.');
87 chrome
.send('testResult', [true]);
90 console
.log('Unexpected message: \'' + data
[0] + '\'');
91 chrome
.send('testResult', [false]);
95 document
.body
.appendChild(webview
);
98 // Adds two content scripts with the same URL pattern to <webview> at the same
99 // time. This test verifies that both scripts are injected when the <webview>
100 // navigates to a URL that matches the URL pattern.
101 function testAddMultiContentScripts(url
) {
102 var webview
= document
.createElement('webview');
104 console
.log('Step 1: call <webview>.addContentScripts(myrule1 & myrule2)');
105 webview
.addContentScripts(
107 matches
: ['http://*/empty*'],
109 files
: ['test/inject_comm_channel.js']
111 run_at
: 'document_start'},
113 matches
: ['http://*/empty*'],
115 files
: ['test/inject_comm_channel_2.js']
117 run_at
: 'document_start'}]);
119 webview
.addEventListener('loadstop', function() {
120 console
.log('Step 2: postMessage to build connection.');
121 var msg1
= [REQUEST_TO_COMM_CHANNEL_1
];
122 webview
.contentWindow
.postMessage(JSON
.stringify(msg1
), '*');
123 console
.log('Step 3: postMessage to build connection to the other script.');
124 var msg2
= [REQUEST_TO_COMM_CHANNEL_2
];
125 webview
.contentWindow
.postMessage(JSON
.stringify(msg2
), '*');
128 var response_1
= false;
129 var response_2
= false;
130 window
.addEventListener('message', function(e
) {
131 if (e
.source
!= webview
.contentWindow
)
133 var data
= JSON
.parse(e
.data
);
134 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
136 'Step 4: A communication channel has been established with webview.');
138 if (response_1
&& response_2
)
139 chrome
.send('testResult', [true]);
141 } else if (data
== RESPONSE_FROM_COMM_CHANNEL_2
) {
143 'Step 5: A communication channel has been established with webview.');
145 if (response_1
&& response_2
)
146 chrome
.send('testResult', [true]);
149 console
.log('Unexpected message: \'' + data
[0] + '\'');
150 chrome
.send('testResult', [false]);
154 document
.body
.appendChild(webview
);
157 // Adds a content script to <webview> and navigates. After seeing the script is
158 // injected, we add another content script with the same name to the <webview>.
159 // This test verifies that the second script will replace the first one and be
160 // injected after navigating the <webview>. Meanwhile, the <webview> shouldn't
161 // get any message from the first script anymore.
162 function testAddContentScriptWithSameNameShouldOverwriteTheExistingOne(url
) {
163 var webview
= document
.createElement('webview');
165 console
.log('Step 1: call <webview>.addContentScripts(myrule1)');
166 webview
.addContentScripts(
168 matches
: ['http://*/empty*'],
170 files
: ['test/inject_comm_channel.js']
172 run_at
: 'document_start'}]);
173 var connect_script_1
= true;
174 var connect_script_2
= false;
176 webview
.addEventListener('loadstop', function() {
177 if (connect_script_1
) {
178 var msg1
= [REQUEST_TO_COMM_CHANNEL_1
];
179 webview
.contentWindow
.postMessage(JSON
.stringify(msg1
), '*');
180 connect_script_1
= false;
182 if (connect_script_2
) {
183 var msg2
= [REQUEST_TO_COMM_CHANNEL_2
];
184 webview
.contentWindow
.postMessage(JSON
.stringify(msg2
), '*');
185 connect_script_2
= false;
189 var should_get_response_from_script_1
= true;
190 window
.addEventListener('message', function(e
) {
191 if (e
.source
!= webview
.contentWindow
)
193 var data
= JSON
.parse(e
.data
);
194 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
195 if (should_get_response_from_script_1
) {
197 'Step 2: A communication channel has been established with webview.'
199 console
.log('Step 3: <webview>.addContentScripts() with a updated' +
201 webview
.addContentScripts(
203 matches
: ['http://*/empty*'],
205 files
: ['test/inject_comm_channel_2.js']
207 run_at
: 'document_start'}]);
208 connect_script_2
= true;
209 should_get_response_from_script_1
= false;
212 chrome
.send('testResult', [false]);
215 } else if (data
== RESPONSE_FROM_COMM_CHANNEL_2
) {
217 'Step 4: Another communication channel has been established ' +
219 setTimeout(function() {
220 chrome
.send('testResult', [true]);
224 console
.log('Unexpected message: \'' + data
[0] + '\'');
225 chrome
.send('testResult', [false]);
229 document
.body
.appendChild(webview
);
232 // There are two <webview>s are added to the DOM, and we add a content script
233 // to one of them. This test verifies that the script won't be injected in
234 // the other <webview>.
235 function testAddContentScriptToOneWebViewShouldNotInjectToTheOtherWebView(url
) {
236 var webview1
= document
.createElement('webview');
237 var webview2
= document
.createElement('webview');
239 console
.log('Step 1: call <webview1>.addContentScripts.');
240 webview1
.addContentScripts(
242 matches
: ['http://*/empty*'],
244 files
: ['test/inject_comm_channel.js']
246 run_at
: 'document_start'}]);
248 webview2
.addEventListener('loadstop', function() {
249 console
.log('Step 2: webview2 requests to build communication channel.');
250 var msg
= [REQUEST_TO_COMM_CHANNEL_1
];
251 webview2
.contentWindow
.postMessage(JSON
.stringify(msg
), '*');
252 setTimeout(function() {
253 chrome
.send('testResult', [true]);
257 window
.addEventListener('message', function(e
) {
258 if (e
.source
!= webview2
.contentWindow
)
260 var data
= JSON
.parse(e
.data
);
261 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
) {
262 chrome
.send('testResult', [false]);
265 console
.log('Unexpected message: \'' + data
[0] + '\'');
266 chrome
.send('testResult', [false]);
271 document
.body
.appendChild(webview1
);
272 document
.body
.appendChild(webview2
);
275 // Adds a content script to <webview> and navigates to a URL that matches the
276 // URL pattern defined in the script. After the first navigation, we remove this
277 // script from the <webview> and navigates to the same URL. This test verifies
278 // taht the script is injected during the first navigation, but isn't injected
279 // after removing it.
280 function testAddAndRemoveContentScripts(url
) {
281 var webview
= document
.createElement('webview');
283 console
.log('Step 1: call <webview>.addContentScripts.');
284 webview
.addContentScripts(
286 matches
: ['http://*/empty*'],
288 files
: ['test/inject_comm_channel.js']
290 run_at
: 'document_start'}]);
292 var should_get_response_from_script_1
= true;
295 webview
.addEventListener('loadstop', function() {
297 console
.log('Step 2: post message to build connect.');
298 var msg
= [REQUEST_TO_COMM_CHANNEL_1
];
299 webview
.contentWindow
.postMessage(JSON
.stringify(msg
), '*');
301 } else if (count
== 1) {
302 console
.log('Step 5: post message to build connect again.');
303 var msg
= [REQUEST_TO_COMM_CHANNEL_1
];
304 webview
.contentWindow
.postMessage(JSON
.stringify(msg
), '*');
305 setTimeout(function() {
306 chrome
.send('testResult', [true]);
311 window
.addEventListener('message', function(e
) {
312 if (e
.source
!= webview
.contentWindow
)
314 var data
= JSON
.parse(e
.data
);
315 if (data
[0] == RESPONSE_FROM_COMM_CHANNEL_1
&&
316 should_get_response_from_script_1
) {
317 console
.log('Step 3: A communication channel has been established ' +
319 should_get_response_from_script_1
= false;
321 'Step 4: call <webview>.removeContentScripts and navigate.');
322 webview
.removeContentScripts();
326 console
.log('Unexpected message: \'' + data
[0] + '\'');
327 chrome
.send('testResult', [false]);
331 document
.body
.appendChild(webview
);
334 // This test verifies that the addContentScripts API works with the new window
336 function testAddContentScriptsWithNewWindowAPI(url
) {
337 var webview
= document
.createElement('webview');
340 webview
.addEventListener('newwindow', function(e
) {
342 newwebview
= document
.createElement('webview');
344 console
.log('Step 2: call newwebview.addContentScripts.');
345 newwebview
.addContentScripts(
347 matches
: ['http://*/guest_from_opener*'],
349 files
: ['test/inject_comm_channel.js']
351 run_at
: 'document_start'}]);
353 newwebview
.addEventListener('loadstop', function(evt
) {
354 var msg
= [REQUEST_TO_COMM_CHANNEL_1
];
355 console
.log('Step 4: new webview postmessage to build communication ' +
357 newwebview
.contentWindow
.postMessage(JSON
.stringify(msg
), '*');
360 document
.body
.appendChild(newwebview
);
361 // attach the new window to the new <webview>.
362 console
.log('Step 3: attaches the new webview.');
363 e
.window
.attach(newwebview
);
366 window
.addEventListener('message', function(e
) {
367 if (!newwebview
|| e
.source
!= newwebview
.contentWindow
)
369 var data
= JSON
.parse(e
.data
);
370 if (data
== RESPONSE_FROM_COMM_CHANNEL_1
&&
371 e
.source
== newwebview
.contentWindow
) {
372 console
.log('Step 5: a communication channel has been established ' +
373 'with the new webview.');
374 chrome
.send('testResult', [true]);
377 chrome
.send('testResult', [false]);
380 console
.log('Unexpected message: \'' + data
[0] + '\'');
381 chrome
.send('testResult', [false]);
384 console
.log('Step 1: navigates the webview to window open guest URL.');
385 webview
.setAttribute('src', url
);
386 document
.body
.appendChild(webview
);
389 // Adds a content script to <webview>. This test verifies that the script is
390 // injected after terminate and reload <webview>.
391 function testContentScriptIsInjectedAfterTerminateAndReloadWebView(url
) {
392 var webview
= document
.createElement('webview');
394 console
.log('Step 1: call <webview>.addContentScripts.');
395 webview
.addContentScripts(
397 matches
: ['http://*/empty*'],
399 files
: ['test/webview_execute_script.js']
401 run_at
: 'document_end'}]);
404 webview
.addEventListener('loadstop', function() {
406 console
.log('Step 2: call webview.terminate().');
410 } else if (count
== 1) {
411 console
.log('Step 4: call <webview>.executeScript to check result.');
412 webview
.executeScript({
413 code
: 'document.body.style.backgroundColor;'
414 }, onGetBackgroundExecuted
);
418 webview
.addEventListener('exit', function() {
419 console
.log('Step 3: call webview.reload().');
424 document
.body
.appendChild(webview
);
427 // This test verifies the content script won't be removed when the guest is
428 // destroyed, i.e., removed <webview> from the DOM.
429 function testContentScriptExistsAsLongAsWebViewTagExists(url
) {
430 var webview
= document
.createElement('webview');
432 console
.log('Step 1: call <webview>.addContentScripts.');
433 webview
.addContentScripts(
435 matches
: ['http://*/empty*'],
437 files
: ['test/webview_execute_script.js']
439 run_at
: 'document_end'}]);
442 webview
.addEventListener('loadstop', function() {
444 console
.log('Step 2: check the result of content script injected.');
445 webview
.executeScript({
446 code
: 'document.body.style.backgroundColor;'
447 }, function(results
) {
448 assertEquals(1, results
.length
);
449 assertEquals('red', results
[0]);
451 console
.log('Step 3: remove webview from the DOM.');
452 document
.body
.removeChild(webview
);
453 console
.log('Step 4: add webview back to the DOM.');
454 document
.body
.appendChild(webview
);
457 } else if (count
== 1) {
458 console
.log('Step 5: check the result of content script injected again.');
459 webview
.executeScript({
460 code
: 'document.body.style.backgroundColor;'
461 }, onGetBackgroundExecuted
);
466 document
.body
.appendChild(webview
);
469 function testAddContentScriptWithCode(url
) {
470 var webview
= document
.createElement('webview');
472 console
.log('Step 1: call <webview>.addContentScripts.');
473 webview
.addContentScripts(
475 matches
: ['http://*/empty*'],
477 code
: 'document.body.style.backgroundColor = \'red\';'
479 run_at
: 'document_end'}]);
481 webview
.addEventListener('loadstop', function() {
482 console
.log('Step 2: call webview.executeScript() to check result.')
483 webview
.executeScript({
484 code
: 'document.body.style.backgroundColor;'
485 }, onGetBackgroundExecuted
);
489 document
.body
.appendChild(webview
);