- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / data / extensions / platform_apps / web_view / newwindow / embedder.js
1 // Copyright 2013 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 embedder = {};
6 embedder.test = {};
7 embedder.baseGuestURL = '';
8 embedder.guestURL = '';
9 embedder.guestWithLinkURL = '';
10 embedder.newWindowURL = '';
11
12 window.runTest = function(testName) {
13   if (!embedder.test.testList[testName]) {
14     console.log('Incorrect testName: ' + testName);
15     embedder.test.fail();
16     return;
17   }
18
19   // Run the test.
20   embedder.test.testList[testName]();
21 };
22 // window.* exported functions end.
23
24 /** @private */
25 embedder.setUp_ = function(config) {
26   embedder.baseGuestURL = 'http://localhost:' + config.testServer.port;
27   embedder.guestURL = embedder.baseGuestURL +
28       '/extensions/platform_apps/web_view/newwindow' +
29       '/guest_opener.html';
30   embedder.newWindowURL = embedder.baseGuestURL +
31       '/extensions/platform_apps/web_view/newwindow' +
32       '/newwindow.html';
33   chrome.test.log('Guest url is: ' + embedder.guestURL);
34   embedder.guestWithLinkURL = embedder.baseGuestURL +
35       '/extensions/platform_apps/web_view/newwindow' +
36       '/guest_with_link.html';
37 };
38
39 /** @private */
40 embedder.setUpGuest_ = function(partitionName) {
41   document.querySelector('#webview-tag-container').innerHTML =
42       '<webview style="width: 100px; height: 100px;"></webview>';
43   var webview = document.querySelector('webview');
44   if (partitionName) {
45     webview.partition = partitionName;
46   }
47   if (!webview) {
48     embedder.test.fail('No <webview> element created');
49   }
50   return webview;
51 };
52
53 /** @private */
54 embedder.setUpNewWindowRequest_ = function(webview, url, frameName, testName) {
55   var onWebViewLoadStop = function(e) {
56     // Send post message to <webview> when it's ready to receive them.
57     var redirect = testName.indexOf("_blank") != -1;
58     webview.contentWindow.postMessage(
59         JSON.stringify(
60             ['open-window', '' + url, '' + frameName, redirect]), '*');
61   };
62   webview.addEventListener('loadstop', onWebViewLoadStop);
63   webview.setAttribute('src', embedder.guestURL);
64 };
65
66 embedder.test = {};
67 embedder.test.succeed = function() {
68   chrome.test.sendMessage('TEST_PASSED');
69 };
70
71 embedder.test.fail = function() {
72   chrome.test.sendMessage('TEST_FAILED');
73 };
74
75 embedder.test.assertEq = function(a, b) {
76   if (a != b) {
77     console.log('assertion failed: ' + a + ' != ' + b);
78     embedder.test.fail();
79   }
80 };
81
82 embedder.test.assertTrue = function(condition) {
83   if (!condition) {
84     console.log('assertion failed: true != ' + condition);
85     embedder.test.fail();
86   }
87 };
88
89 embedder.test.assertFalse = function(condition) {
90   if (condition) {
91     console.log('assertion failed: false != ' + condition);
92     embedder.test.fail();
93   }
94 };
95
96 /** @private */
97 embedder.requestFrameName_ =
98     function(webview, openerWebview, testName, expectedFrameName) {
99   var onWebViewLoadStop = function(e) {
100     // Send post message to <webview> when it's ready to receive them.
101     // Note that loadstop will get called twice if the test is opening
102     // a new window via a redirect: one for navigating to about:blank
103     // and another for navigating to the final destination.
104     // about:blank will not respond to the postMessage so it's OK
105     // to send it again on the second loadstop event.
106     webview.contentWindow.postMessage(
107         JSON.stringify(['get-frame-name', testName]), '*');
108   };
109   webview.addEventListener('loadstop', onWebViewLoadStop);
110   var onPostMessageReceived = function(e) {
111     var data = JSON.parse(e.data);
112     if (data[0] == 'get-frame-name') {
113       var name = data[1];
114       if (testName != name)
115         return;
116       var frameName = data[2];
117       embedder.test.assertEq(expectedFrameName, frameName);
118       embedder.test.assertEq(expectedFrameName, webview.name);
119       embedder.test.assertEq(openerWebview.partition, webview.partition);
120       window.removeEventListener('message', onPostMessageReceived);
121       embedder.test.succeed();
122     }
123   };
124   window.addEventListener('message', onPostMessageReceived);
125 };
126
127 /** @private */
128 embedder.requestClose_ = function(webview, testName) {
129   var onWebViewLoadStop = function(e) {
130     webview.contentWindow.postMessage(
131         JSON.stringify(['close', testName]), '*');
132   };
133   webview.addEventListener('loadstop', onWebViewLoadStop);
134   var onWebViewClose = function(e) {
135     webview.removeEventListener('close', onWebViewClose);
136     embedder.test.succeed();
137   };
138   webview.addEventListener('close', onWebViewClose);
139 };
140
141 /** @private */
142 embedder.requestExecuteScript_ =
143     function(webview, script, expectedResult, testName) {
144   var onWebViewLoadStop = function(e) {
145     webview.executeScript(
146       {code: script},
147       function(results) {
148         embedder.test.assertEq(1, results.length);
149         embedder.test.assertEq(expectedResult, results[0]);
150         embedder.test.succeed();
151       });
152   };
153   webview.addEventListener('loadstop', onWebViewLoadStop);
154 };
155
156 /** @private */
157 embedder.assertCorrectEvent_ = function(e, guestName) {
158   embedder.test.assertEq('newwindow', e.type);
159   embedder.test.assertTrue(!!e.targetUrl);
160   embedder.test.assertEq(guestName, e.name);
161 };
162
163 // Tests begin.
164
165 var testNewWindowName = function(testName,
166                                  webViewName,
167                                  guestName,
168                                  partitionName,
169                                  expectedFrameName) {
170   var webview = embedder.setUpGuest_(partitionName);
171
172   var onNewWindow = function(e) {
173     chrome.test.log('Embedder notified on newwindow');
174     embedder.assertCorrectEvent_(e, guestName);
175
176     var newwebview = document.createElement('webview');
177     newwebview.setAttribute('name', webViewName);
178     document.querySelector('#webview-tag-container').appendChild(newwebview);
179     embedder.requestFrameName_(
180         newwebview, webview, testName, expectedFrameName);
181     try {
182       e.window.attach(newwebview);
183     } catch (e) {
184       embedder.test.fail();
185     }
186   };
187   webview.addEventListener('newwindow', onNewWindow);
188
189   // Load a new window with the given name.
190   embedder.setUpNewWindowRequest_(webview, 'guest.html', guestName, testName);
191 };
192
193 // Loads a guest which requests a new window.
194 function testNewWindowNameTakesPrecedence() {
195   var webViewName = 'foo';
196   var guestName = 'bar';
197   var partitionName = 'foobar';
198   var expectedName = guestName;
199   testNewWindowName('testNewWindowNameTakesPrecedence',
200                     webViewName, guestName, partitionName, expectedName);
201 }
202
203 function testWebViewNameTakesPrecedence() {
204   var webViewName = 'foo';
205   var guestName = '';
206   var partitionName = 'persist:foobar';
207   var expectedName = webViewName;
208   testNewWindowName('testWebViewNameTakesPrecedence',
209                     webViewName, guestName, partitionName, expectedName);
210 }
211
212 function testNoName() {
213   var webViewName = '';
214   var guestName = '';
215   var partitionName = '';
216   var expectedName = '';
217   testNewWindowName('testNoName',
218                     webViewName, guestName, partitionName, expectedName);
219 }
220
221 // This test exercises the need for queuing events that occur prior to
222 // attachment. In this test a new window is opened that initially navigates to
223 // about:blank and then subsequently redirects to its final destination. This
224 // test responds to loadstop in the new <webview>. Since "about:blank" does not
225 // have any external resources, it loads immediately prior to attachment, and
226 // the <webview> that is eventually attached never gets a chance to see the
227 // event. GuestView solves this problem by queuing events that occur prior to
228 // attachment and firing them immediately after attachment.
229 function testNewWindowRedirect() {
230   var webViewName = 'foo';
231   var guestName = '';
232   var partitionName = 'persist:foobar';
233   var expectedName = webViewName;
234   testNewWindowName('testNewWindowRedirect_blank',
235                     webViewName, guestName, partitionName, expectedName);
236 }
237
238 function testNewWindowClose() {
239   var testName = 'testNewWindowClose';
240   var webview = embedder.setUpGuest_('foobar');
241
242   var onNewWindow = function(e) {
243     chrome.test.log('Embedder notified on newwindow');
244     embedder.assertCorrectEvent_(e, '');
245
246     var newwebview = document.createElement('webview');
247     document.querySelector('#webview-tag-container').appendChild(newwebview);
248     embedder.requestClose_(newwebview, testName);
249     try {
250       e.window.attach(newwebview);
251     } catch (e) {
252       embedder.test.fail();
253     }
254   };
255   webview.addEventListener('newwindow', onNewWindow);
256
257   // Load a new window with the given name.
258   embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
259 }
260
261 function testNewWindowExecuteScript() {
262   var testName = 'testNewWindowExecuteScript';
263   var webview = embedder.setUpGuest_('foobar');
264
265   var onNewWindow = function(e) {
266     chrome.test.log('Embedder notified on newwindow');
267     embedder.assertCorrectEvent_(e, '');
268
269     var newwebview = document.createElement('webview');
270     document.querySelector('#webview-tag-container').appendChild(newwebview);
271     embedder.requestExecuteScript_(
272         newwebview,
273         'document.body.style.backgroundColor = "red";',
274         'red',
275         testName);
276     try {
277       e.window.attach(newwebview);
278     } catch (e) {
279       embedder.test.fail();
280     }
281   };
282   webview.addEventListener('newwindow', onNewWindow);
283
284   // Load a new window with the given name.
285   embedder.setUpNewWindowRequest_(webview, 'about:blank', '', testName);
286 }
287
288 function testNewWindowOpenInNewTab() {
289   var webview = embedder.setUpGuest_('foobar');
290
291   webview.addEventListener('loadstop', function(e) {
292     webview.focus();
293     chrome.test.sendMessage('Loaded');
294   });
295   webview.addEventListener('newwindow', function(e) {
296     embedder.test.succeed();
297   });
298   webview.src = embedder.guestWithLinkURL;
299 }
300
301 function testNewWindowWebRequest() {
302   var testName = 'testNewWindowWebRequest';
303   var webview = embedder.setUpGuest_('foobar');
304
305   var onNewWindow = function(e) {
306     chrome.test.log('Embedder notified on newwindow');
307     embedder.assertCorrectEvent_(e, '');
308
309     var newwebview = new WebView();
310     var calledWebRequestEvent = false;
311     newwebview.request.onBeforeRequest.addListener(function(e) {
312       if (!calledWebRequestEvent) {
313         calledWebRequestEvent = true;
314         embedder.test.succeed();
315       }
316     }, {urls: ['<all_urls>']});
317     document.querySelector('#webview-tag-container').appendChild(newwebview);
318     e.preventDefault();
319     try {
320       e.window.attach(newwebview);
321     } catch (e) {
322       embedder.test.fail();
323     }
324   };
325   webview.addEventListener('newwindow', onNewWindow);
326
327   // Load a new window with the given name.
328   embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
329 }
330
331 // This test verifies that a WebRequest event listener's lifetime is not
332 // tied to the context in which it was created but instead at least the
333 // lifetime of the embedder window to which it was attached.
334 function testNewWindowWebRequestCloseWindow() {
335   var current = chrome.app.window.current();
336   var requestCount = 0;
337   var dataUrl = 'data:text/html,<body>foobar</body>';
338
339   var webview = new WebView();
340   webview.request.onBeforeRequest.addListener(function(e) {
341     console.log('url: ' + e.url);
342     ++requestCount;
343     if (requestCount == 1) {
344       // Close the existing window.
345       // TODO(fsamuel): This is currently broken and this test is disabled.
346       // Once we close the first window, the context in which the <webview> was
347       // created is gone and so the <webview> is no longer a custom element.
348       current.close();
349       // renavigate the webview.
350       webview.src = embedder.newWindowURL;
351     } else if (requestCount == 2) {
352       embedder.test.succeed();
353     }
354   }, {urls: ['<all_urls>']});
355   webview.addEventListener('loadcommit', function(e) {
356     console.log('loadcommit: ' + e.url);
357   });
358   webview.src = embedder.guestURL;
359
360   chrome.app.window.create('newwindow.html', {
361     width: 640,
362     height: 480
363   }, function(newwindow) {
364     newwindow.contentWindow.onload = function(evt) {
365       newwindow.contentWindow.document.body.appendChild(webview);
366     };
367   });
368 }
369
370 function testNewWindowWebRequestRemoveElement() {
371   var testName = 'testNewWindowWebRequestRemoveElement';
372   var dataUrl = 'data:text/html,<body>foobar</body>';
373   var webview = embedder.setUpGuest_('foobar');
374   var calledWebRequestEvent = false;
375   webview.request.onBeforeRequest.addListener(function(e) {
376     if (e.url == embedder.guestURL && calledWebRequestEvent) {
377       embedder.test.succeed();
378     }
379   }, {urls: ['<all_urls>']});
380
381   var onNewWindow = function(e) {
382     chrome.test.log('Embedder notified on newwindow');
383     embedder.assertCorrectEvent_(e, '');
384
385     e.preventDefault();
386     chrome.app.window.create('newwindow.html', {
387       width: 640,
388       height: 480
389     }, function(newwindow) {
390       newwindow.contentWindow.onload = function(evt) {
391         var newwebview =
392             newwindow.contentWindow.document.querySelector('webview');
393         newwebview.request.onBeforeRequest.addListener(function(e) {
394           if (!calledWebRequestEvent) {
395             calledWebRequestEvent = true;
396             newwebview.parentElement.removeChild(newwebview);
397             setTimeout(function() {
398               webview.src = embedder.guestURL;
399             }, 0);
400           }
401         }, {urls: ['<all_urls>']});
402         try {
403           e.window.attach(newwebview);
404         } catch (e) {
405           embedder.test.fail();
406         }
407       };
408     });
409   };
410   webview.addEventListener('newwindow', onNewWindow);
411
412   // Load a new window with the given name.
413   embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
414 }
415
416 embedder.test.testList = {
417   'testNewWindowNameTakesPrecedence': testNewWindowNameTakesPrecedence,
418   'testWebViewNameTakesPrecedence': testWebViewNameTakesPrecedence,
419   'testNoName': testNoName,
420   'testNewWindowRedirect':  testNewWindowRedirect,
421   'testNewWindowClose': testNewWindowClose,
422   'testNewWindowExecuteScript': testNewWindowExecuteScript,
423   'testNewWindowOpenInNewTab': testNewWindowOpenInNewTab,
424   'testNewWindowWebRequest': testNewWindowWebRequest,
425   'testNewWindowWebRequestCloseWindow': testNewWindowWebRequestCloseWindow,
426   'testNewWindowWebRequestRemoveElement': testNewWindowWebRequestRemoveElement
427 };
428
429 onload = function() {
430   chrome.test.getConfig(function(config) {
431     embedder.setUp_(config);
432     chrome.test.sendMessage('Launched');
433   });
434 };