Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / apps / app_url_redirector_browsertest.cc
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 #include "base/strings/stringprintf.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "base/win/windows_version.h"
8 #include "chrome/browser/apps/app_browsertest_util.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/extension_test_message_listener.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "content/public/common/page_transition_types.h"
15 #include "content/public/test/browser_test_base.h"
16 #include "content/public/test/browser_test_utils.h"
17 #include "net/test/embedded_test_server/embedded_test_server.h"
18
19 namespace extensions {
20
21 class PlatformAppUrlRedirectorBrowserTest : public PlatformAppBrowserTest {
22  public:
23   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
24
25  protected:
26   // Performs the following sequence:
27   // - installs the app |handler| (a relative path under the platform_apps
28   // subdirectory);
29   // - navigates the current tab to the HTML page |lancher_page| (ditto);
30   // - then waits for |handler| to launch and send back a |handler_ack_message|;
31   // - finally checks that the resulting app window count is as expected.
32   // The |launcher_page| is supposed to trigger a navigation matching one of the
33   // url_handlers in the |handler|'s manifest, and thereby launch the |handler|.
34   void TestNavigationInTab(const char* launcher_page,
35                            const char* handler,
36                            const char* handler_start_message);
37
38   // The same as above, but does not expect the |handler| to launch. Verifies
39   // that it didn't, and that the navigation has opened in a new tab instead.
40   void TestMismatchingNavigationInTab(const char* launcher_page,
41                                       const char* success_tab_title,
42                                       const char* handler);
43
44   // - installs the app |handler|;
45   // - opens the page |xhr_opening_page| in the current tab;
46   // - the page sends an XHR to a local resouce, whose URL matches one of the
47   //   url_handlers in |handler|;
48   // - waits until |xhr_opening_page| gets a response back and changes the tab's
49   //   title to a value indicating success/failure of the XHR;
50   // - verifies that no app windows have been opened, i.e. |handler| wasn't
51   //   launched even though its url_handlers match the URL.
52   void TestNegativeXhrInTab(const char* xhr_opening_page,
53                             const char* success_tab_title,
54                             const char* failure_tab_title,
55                             const char* handler);
56
57   // Performs the following sequence:
58   // - installs the app |handler| (a relative path under the platform_apps
59   // subdirectory);
60   // - loads and launches the app |launcher| (ditto);
61   // - waits for the |launcher| to launch and send back a |launcher_ack_message|
62   //   (to make sure it's not the failing entity, if the test fails overall);
63   // - waits for the |handler| to launch and send back a |handler_ack_message|;
64   // - finally checks that the resulting app window count is as expected.
65   // The |launcher| is supposed to trigger a navigation matching one of the
66   // url_handlers in the |handler|'s manifest, and thereby launch the |handler|.
67   void TestNavigationInApp(const char* launcher,
68                            const char* launcher_done_message,
69                            const char* handler,
70                            const char* handler_start_message);
71
72   // The same as above, but does not expect the |handler| to launch. Verifies
73   // that it didn't, and that the navigation has opened in a new tab instead.
74   void TestMismatchingNavigationInApp(const char* launcher,
75                                       const char* launcher_done_message,
76                                       const char* handler);
77
78   // - installs the |handler| app;
79   // - loads and launches the |launcher| app;
80   // - waits until the |launcher| sends back a |launcher_done_message|;
81   // - the launcher performs a navigation to a URL that mismatches the
82   //   |handler|'s url_handlers;
83   // - verifies that the |handler| hasn't been launched as a result of the
84   //   navigation.
85   void TestNegativeNavigationInApp(const char* launcher,
86                                    const char* launcher_done_message,
87                                    const char* handler);
88
89   // - installs the app |handler|;
90   // - navigates the current tab to the HTML page |matching_target_page| with
91   //   page transition |transition|;
92   // - waits for |handler| to launch and send back a |handler_start_message|;
93   // - finally checks that the resulting app window count is as expected.
94   void TestNavigationInBrowser(const char* matching_target_page,
95                                content::PageTransition transition,
96                                const char* handler,
97                                const char* handler_start_message);
98
99   // Same as above, but does not expect |handler| to launch. This is used, e.g.
100   // for form submissions, where the URL would normally match the url_handlers
101   // but should not launch it.
102   void TestNegativeNavigationInBrowser(const char* matching_target_page,
103                                        content::PageTransition transition,
104                                        const char* success_tab_title,
105                                        const char* handler);
106
107   // Same as above, but expects the |mismatching_target_page| should not match
108   // any of the |handler|'s url_handlers, and therefor not launch the app.
109   void TestMismatchingNavigationInBrowser(const char* mismatching_target_page,
110                                           content::PageTransition transition,
111                                           const char* success_tab_title,
112                                           const char* handler);
113 };
114
115
116 void PlatformAppUrlRedirectorBrowserTest::SetUpCommandLine(
117     CommandLine* command_line) {
118   PlatformAppBrowserTest::SetUpCommandLine(command_line);
119   command_line->AppendSwitch(::switches::kDisablePopupBlocking);
120 }
121
122 // TODO(sergeygs): Factor out common functionality from TestXyz,
123 // TestNegativeXyz, and TestMismatchingXyz versions.
124
125 // TODO(sergeys): Return testing::AssertionErrors from these methods to
126 // preserve line numbers and (if applicable) failure messages.
127
128 void PlatformAppUrlRedirectorBrowserTest::TestNavigationInTab(
129     const char* launcher_page,
130     const char* handler,
131     const char* handler_start_message) {
132   ASSERT_TRUE(StartEmbeddedTestServer());
133
134   InstallPlatformApp(handler);
135
136   ExtensionTestMessageListener handler_listener(handler_start_message, false);
137
138   ui_test_utils::NavigateToURLWithDisposition(
139       browser(),
140       embedded_test_server()->GetURL(base::StringPrintf(
141           "/extensions/platform_apps/%s", launcher_page)),
142       CURRENT_TAB,
143       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
144
145   ASSERT_TRUE(handler_listener.WaitUntilSatisfied());
146
147   ASSERT_EQ(1U, GetAppWindowCount());
148 }
149
150 void PlatformAppUrlRedirectorBrowserTest::TestMismatchingNavigationInTab(
151     const char* launcher_page,
152     const char* success_tab_title,
153     const char* handler) {
154   ASSERT_TRUE(StartEmbeddedTestServer());
155
156   InstallPlatformApp(handler);
157
158   const base::string16 success_title = base::ASCIIToUTF16(success_tab_title);
159   content::WebContents* tab =
160       browser()->tab_strip_model()->GetActiveWebContents();
161   content::TitleWatcher title_watcher(tab, success_title);
162
163   ui_test_utils::NavigateToURLWithDisposition(
164       browser(),
165       embedded_test_server()->GetURL(base::StringPrintf(
166           "/extensions/platform_apps/%s", launcher_page)),
167       CURRENT_TAB,
168       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
169
170   ASSERT_EQ(success_title, title_watcher.WaitAndGetTitle());
171   ASSERT_EQ(1, browser()->tab_strip_model()->count());
172   ASSERT_EQ(0U, GetAppWindowCount());
173 }
174
175 void PlatformAppUrlRedirectorBrowserTest::TestNegativeXhrInTab(
176     const char* launcher_page,
177     const char* success_tab_title,
178     const char* failure_tab_title,
179     const char* handler) {
180   ASSERT_TRUE(StartEmbeddedTestServer());
181
182   InstallPlatformApp(handler);
183
184   const base::string16 success_title = base::ASCIIToUTF16(success_tab_title);
185   const base::string16 failure_title = base::ASCIIToUTF16(failure_tab_title);
186   content::WebContents* tab =
187       browser()->tab_strip_model()->GetActiveWebContents();
188   content::TitleWatcher title_watcher(tab, success_title);
189   title_watcher.AlsoWaitForTitle(failure_title);
190
191   ui_test_utils::NavigateToURLWithDisposition(
192       browser(),
193       embedded_test_server()->GetURL(base::StringPrintf(
194           "/extensions/platform_apps/%s", launcher_page)),
195       CURRENT_TAB,
196       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
197
198   ASSERT_EQ(success_title, title_watcher.WaitAndGetTitle());
199   ASSERT_EQ(1, browser()->tab_strip_model()->count());
200   ASSERT_EQ(0U, GetAppWindowCount());
201 }
202
203 void PlatformAppUrlRedirectorBrowserTest::TestNavigationInApp(
204     const char* launcher,
205     const char* launcher_done_message,
206     const char* handler,
207     const char* handler_start_message) {
208   ASSERT_TRUE(StartEmbeddedTestServer());
209
210   InstallPlatformApp(handler);
211
212   ExtensionTestMessageListener launcher_listener(launcher_done_message, false);
213   ExtensionTestMessageListener handler_listener(handler_start_message, false);
214
215   LoadAndLaunchPlatformApp(launcher);
216
217   ASSERT_TRUE(launcher_listener.WaitUntilSatisfied());
218   ASSERT_TRUE(handler_listener.WaitUntilSatisfied());
219
220   ASSERT_EQ(2U, GetAppWindowCount());
221 }
222
223 void PlatformAppUrlRedirectorBrowserTest::TestNegativeNavigationInApp(
224     const char* launcher,
225     const char* launcher_done_message,
226     const char* handler) {
227   ASSERT_TRUE(StartEmbeddedTestServer());
228
229   InstallPlatformApp(handler);
230
231   content::WindowedNotificationObserver observer(
232       chrome::NOTIFICATION_TAB_ADDED,
233       content::Source<content::WebContentsDelegate>(browser()));
234
235   ExtensionTestMessageListener launcher_done_listener(launcher_done_message,
236                                                       false);
237   LoadAndLaunchPlatformApp(launcher);
238
239   ASSERT_TRUE(launcher_done_listener.WaitUntilSatisfied());
240
241   observer.Wait();
242
243   ASSERT_EQ(1U, GetAppWindowCount());
244 }
245
246 void PlatformAppUrlRedirectorBrowserTest::TestMismatchingNavigationInApp(
247     const char* launcher,
248     const char* launcher_done_message,
249     const char* handler) {
250   ASSERT_TRUE(StartEmbeddedTestServer());
251
252   InstallPlatformApp(handler);
253
254   content::WindowedNotificationObserver observer(
255       chrome::NOTIFICATION_TAB_ADDED,
256       content::Source<content::WebContentsDelegate>(browser()));
257
258   ExtensionTestMessageListener launcher_listener(launcher_done_message, false);
259   LoadAndLaunchPlatformApp(launcher);
260
261   ASSERT_TRUE(launcher_listener.WaitUntilSatisfied());
262
263   observer.Wait();
264   ASSERT_EQ(1U, GetAppWindowCount());
265   ASSERT_EQ(2, browser()->tab_strip_model()->count());
266 }
267
268 void PlatformAppUrlRedirectorBrowserTest::TestNavigationInBrowser(
269     const char* matching_target_page,
270     content::PageTransition transition,
271     const char* handler,
272     const char* handler_start_message) {
273   ASSERT_TRUE(StartEmbeddedTestServer());
274
275   InstallPlatformApp(handler);
276
277   ExtensionTestMessageListener handler_listener(handler_start_message, false);
278
279   chrome::NavigateParams params(
280       browser(),
281       embedded_test_server()->GetURL(base::StringPrintf(
282            "/extensions/platform_apps/%s", matching_target_page)),
283       transition);
284   ui_test_utils::NavigateToURL(&params);
285
286   ASSERT_TRUE(handler_listener.WaitUntilSatisfied());
287
288   ASSERT_EQ(1U, GetAppWindowCount());
289 }
290
291 void PlatformAppUrlRedirectorBrowserTest::TestNegativeNavigationInBrowser(
292     const char* matching_target_page,
293     content::PageTransition transition,
294     const char* success_tab_title,
295     const char* handler) {
296   ASSERT_TRUE(StartEmbeddedTestServer());
297
298   InstallPlatformApp(handler);
299
300   const base::string16 success_title = base::ASCIIToUTF16(success_tab_title);
301   content::WebContents* tab =
302       browser()->tab_strip_model()->GetActiveWebContents();
303   content::TitleWatcher title_watcher(tab, success_title);
304
305   chrome::NavigateParams params(
306       browser(),
307       embedded_test_server()->GetURL(base::StringPrintf(
308            "/extensions/platform_apps/%s", matching_target_page)),
309       transition);
310   ui_test_utils::NavigateToURL(&params);
311
312   ASSERT_EQ(success_title, title_watcher.WaitAndGetTitle());
313   ASSERT_EQ(0U, GetAppWindowCount());
314 }
315
316 void PlatformAppUrlRedirectorBrowserTest::TestMismatchingNavigationInBrowser(
317     const char* mismatching_target_page,
318     content::PageTransition transition,
319     const char* success_tab_title,
320     const char* handler) {
321   TestNegativeNavigationInBrowser(
322       mismatching_target_page, transition, success_tab_title, handler);
323 }
324
325 // Test that a click on a regular link in a tab launches an app that has
326 // matching url_handlers.
327 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
328                        ClickInTabIntercepted) {
329 #if defined (OS_WIN)
330   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
331 #endif
332   TestNavigationInTab(
333       "url_handlers/launching_pages/click_link.html",
334       "url_handlers/handlers/simple",
335       "Handler launched");
336 }
337
338 // Test that a click on a target='_blank' link in a tab launches an app that has
339 // matching url_handlers.
340 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
341                        BlankClickInTabIntercepted) {
342 #if defined (OS_WIN)
343   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
344 #endif
345   TestNavigationInTab(
346       "url_handlers/launching_pages/click_blank_link.html",
347       "url_handlers/handlers/simple",
348       "Handler launched");
349 }
350
351 // Test that a call to window.open() in a tab launches an app that has
352 // matching url_handlers.
353 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
354                        WindowOpenInTabIntercepted) {
355 #if defined (OS_WIN)
356   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
357 #endif
358   TestNavigationInTab(
359       "url_handlers/launching_pages/call_window_open.html",
360       "url_handlers/handlers/simple",
361       "Handler launched");
362 }
363
364 // Test that a click on a regular link in a tab launches an app that has
365 // matching url_handlers.
366 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
367                        MismatchingClickInTabNotIntercepted) {
368 #if defined (OS_WIN)
369   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
370 #endif
371   TestMismatchingNavigationInTab(
372       "url_handlers/launching_pages/click_mismatching_link.html",
373       "Mismatching link target loaded",
374       "url_handlers/handlers/simple");
375 }
376
377 // Test that a click on target='_blank' link in an app's window launches
378 // another app that has matching url_handlers.
379 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
380                        BlankClickInAppIntercepted) {
381 #if defined (OS_WIN)
382   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
383 #endif
384   TestNavigationInApp(
385       "url_handlers/launchers/click_blank_link",
386       "Launcher done",
387       "url_handlers/handlers/simple",
388       "Handler launched");
389 }
390
391 // Test that a call to window.open() in the app's foreground page launches
392 // another app that has matching url_handlers.
393 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
394                        WindowOpenInAppIntercepted) {
395 #if defined (OS_WIN)
396   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
397 #endif
398   TestNavigationInApp(
399       "url_handlers/launchers/call_window_open",
400       "Launcher done",
401       "url_handlers/handlers/simple",
402       "Handler launched");
403 }
404
405 // Test that an app with url_handlers does not intercept a mismatching
406 // click on a target='_blank' link in another app's window.
407 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
408                        MismatchingWindowOpenInAppNotIntercepted) {
409 #if defined (OS_WIN)
410   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
411 #endif
412   TestMismatchingNavigationInApp(
413       "url_handlers/launchers/call_mismatching_window_open",
414       "Launcher done",
415       "url_handlers/handlers/simple");
416 }
417
418 // Test that a webview in an app can be navigated to a URL without interception
419 // even when there are other (or the same) apps that have matching url_handlers.
420 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
421                        WebviewNavigationNotIntercepted) {
422 #if defined (OS_WIN)
423   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
424 #endif
425   // The launcher clicks on a link, which gets intercepted and launches the
426   // handler. The handler also redirects an embedded webview to the URL. The
427   // webview should just navigate without creating an endless loop of
428   // navigate-intercept-launch sequences with multiplying handler's windows.
429   // There should be 2 windows only: launcher's and handler's.
430   TestNavigationInApp(
431       "url_handlers/launchers/click_blank_link",
432       "Launcher done",
433       "url_handlers/handlers/navigate_webview_to_url",
434       "Handler launched");
435 }
436
437 // Test that a webview in an app can be navigated to a URL without interception
438 // even when there are other (or the same) apps that have matching url_handlers.
439 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
440                        MismatchingBlankClickInAppNotIntercepted) {
441 #if defined (OS_WIN)
442   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
443 #endif
444   // The launcher clicks on a link, which gets intercepted and launches the
445   // handler. The handler also redirects an embedded webview to the URL. The
446   // webview should just navigate without creating an endless loop of
447   // navigate-intercept-launch sequences with multiplying handler's windows.
448   // There should be 2 windows only: launcher's and handler's.
449   TestMismatchingNavigationInApp(
450       "url_handlers/launchers/click_mismatching_blank_link",
451       "Launcher done",
452       "url_handlers/handlers/simple");
453 }
454
455 // Test that a URL entry in the omnibar launches an app that has matching
456 // url_handlers.
457 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
458                        EntryInOmnibarIntercepted) {
459 #if defined (OS_WIN)
460   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
461 #endif
462   TestNavigationInBrowser(
463       "url_handlers/common/target.html",
464       content::PAGE_TRANSITION_TYPED,
465       "url_handlers/handlers/simple",
466       "Handler launched");
467 }
468
469 // Test that an app with url_handlers does not intercept a mismatching
470 // URL entry in the omnibar.
471 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
472                        MismatchingEntryInOmnibarNotIntercepted) {
473 #if defined (OS_WIN)
474   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
475 #endif
476   TestMismatchingNavigationInBrowser(
477       "url_handlers/common/mismatching_target.html",
478       content::PAGE_TRANSITION_TYPED,
479       "Mismatching link target loaded",
480       "url_handlers/handlers/simple");
481 }
482
483 // Test that a form submission in a page is never subject to interception
484 // by apps even with matching url_handlers.
485 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
486                        FormSubmissionInTabNotIntercepted) {
487 #if defined (OS_WIN)
488   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
489 #endif
490   TestMismatchingNavigationInTab(
491       "url_handlers/launching_pages/submit_form.html",
492       "Link target loaded",
493       "url_handlers/handlers/simple");
494 }
495
496 // Test that a form submission in a page is never subject to interception
497 // by apps even with matching url_handlers.
498 IN_PROC_BROWSER_TEST_F(PlatformAppUrlRedirectorBrowserTest,
499                        XhrInTabNotIntercepted) {
500 #if defined (OS_WIN)
501   if (base::win::GetVersion() < base::win::VERSION_VISTA) return;  // Bug 301638
502 #endif
503   TestNegativeXhrInTab(
504       "url_handlers/xhr_downloader/main.html",
505       "XHR succeeded",
506       "XHR failed",
507       "url_handlers/handlers/steal_xhr_target");
508 }
509
510 }  // namespace extensions