blob: 09a0e0c627419103b4eb66927141363d40944dfa [file] [log] [blame]
[email protected]c333e792012-01-06 16:57:391// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]3a8eecb2010-04-22 23:56:302// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]b65d4bdcc2013-07-31 00:37:335#include "base/command_line.h"
[email protected]fdf40f3e2013-07-11 23:55:466#include "chrome/browser/chrome_notification_types.h"
[email protected]3a8eecb2010-04-22 23:56:307#include "chrome/browser/extensions/extension_apitest.h"
[email protected]6f371442011-11-09 06:45:468#include "chrome/browser/extensions/extension_service.h"
[email protected]8ecad5e2010-12-02 21:18:339#include "chrome/browser/profiles/profile.h"
[email protected]e0731d72013-07-25 12:39:4610#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
[email protected]7b5dc002010-11-16 23:08:1011#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1012#include "chrome/browser/ui/browser_commands.h"
[email protected]d8748142012-05-16 21:13:4313#include "chrome/browser/ui/browser_finder.h"
[email protected]71b73f02011-04-06 15:57:2914#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3615#include "chrome/browser/ui/browser_window.h"
[email protected]e0448872013-01-11 19:35:0216#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]3a8eecb2010-04-22 23:56:3017#include "chrome/common/chrome_switches.h"
[email protected]b65d4bdcc2013-07-31 00:37:3318#include "chrome/test/base/test_switches.h"
[email protected]af44e7fb2011-07-29 18:32:3219#include "chrome/test/base/ui_test_utils.h"
[email protected]ad23a092011-12-28 07:02:0420#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0721#include "content/public/browser/notification_service.h"
[email protected]c333e792012-01-06 16:57:3922#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3323#include "content/public/browser/render_view_host.h"
[email protected]2aca9a92013-12-03 05:16:0724#include "content/public/browser/site_instance.h"
[email protected]6acde6352012-01-04 16:52:2025#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4226#include "content/public/test/browser_test_utils.h"
[email protected]5b8ff1c2012-06-02 20:42:2027#include "content/public/test/test_navigation_observer.h"
[email protected]22401dc2014-03-21 01:38:5728#include "extensions/browser/extension_host.h"
[email protected]59b0e602014-01-30 00:41:2429#include "extensions/browser/extension_system.h"
[email protected]4a1d9c0d2014-06-13 12:50:1130#include "extensions/browser/install_flag.h"
[email protected]50de9aa22013-11-14 06:30:3431#include "extensions/browser/process_map.h"
[email protected]e4452d32013-11-15 23:07:4132#include "extensions/common/extension.h"
[email protected]85df9d12014-04-15 17:02:1433#include "extensions/common/file_util.h"
[email protected]558878cc82013-11-09 01:25:5134#include "extensions/common/switches.h"
[email protected]f2cb3cf2013-03-21 01:40:5335#include "net/dns/mock_host_resolver.h"
[email protected]c1dffe82013-06-26 20:59:0536#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]36b643212012-09-07 12:53:0037#include "sync/api/string_ordinal.h"
[email protected]3a8eecb2010-04-22 23:56:3038
[email protected]c5eed492012-01-04 17:07:5039using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1140using content::RenderViewHost;
[email protected]2aca9a92013-12-03 05:16:0741using content::SiteInstance;
[email protected]4ca15302012-01-03 05:53:2042using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3443using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2044
[email protected]7b54ca02012-03-02 18:06:5345class AppApiTest : public ExtensionApiTest {
46 protected:
47 // Gets the base URL for files for a specific test, making sure that it uses
48 // "localhost" as the hostname, since that is what the extent is declared
49 // as in the test apps manifests.
[email protected]0bb29bd2014-04-30 21:39:1850 GURL GetTestBaseURL(const std::string& test_directory) {
[email protected]7b54ca02012-03-02 18:06:5351 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:1852 replace_host.SetHostStr("localhost");
[email protected]c1dffe82013-06-26 20:59:0553 GURL base_url = embedded_test_server()->GetURL(
54 "/extensions/api_test/" + test_directory + "/");
[email protected]7b54ca02012-03-02 18:06:5355 return base_url.ReplaceComponents(replace_host);
56 }
57
58 // Pass flags to make testing apps easier.
avi3ef9ec9e2014-12-22 22:50:1759 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]7b54ca02012-03-02 18:06:5360 ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:1761 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]7b54ca02012-03-02 18:06:5362 switches::kDisablePopupBlocking);
avi3ef9ec9e2014-12-22 22:50:1763 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:5164 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]7b54ca02012-03-02 18:06:5365 }
66
67 // Helper function to test that independent tabs of the named app are loaded
68 // into separate processes.
[email protected]0bb29bd2014-04-30 21:39:1869 void TestAppInstancesHelper(const std::string& app_name) {
[email protected]7b54ca02012-03-02 18:06:5370 LOG(INFO) << "Start of test.";
71
[email protected]fafdc842014-01-17 18:09:0872 extensions::ProcessMap* process_map =
73 extensions::ProcessMap::Get(browser()->profile());
[email protected]7b54ca02012-03-02 18:06:5374
75 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:0576 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]7b54ca02012-03-02 18:06:5377
78 ASSERT_TRUE(LoadExtension(
79 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2780 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5381
82 // Open two tabs in the app, one outside it.
83 GURL base_url = GetTestBaseURL(app_name);
84
85 // Test both opening a URL in a new tab, and opening a tab and then
86 // navigating it. Either way, app tabs should be considered extension
87 // processes, but they have no elevated privileges and thus should not
88 // have WebUI bindings.
89 ui_test_utils::NavigateToURLWithDisposition(
90 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
91 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
92 LOG(INFO) << "Nav 1.";
93 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:0294 browser()->tab_strip_model()->GetWebContentsAt(1)->
95 GetRenderProcessHost()->GetID()));
96 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:5397
[email protected]a7fe9112012-07-20 02:34:4598 content::WindowedNotificationObserver tab_added_observer(
[email protected]19506d542013-10-15 23:11:0699 chrome::NOTIFICATION_TAB_ADDED,
[email protected]7b54ca02012-03-02 18:06:53100 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10101 chrome::NewTab(browser());
[email protected]7b54ca02012-03-02 18:06:53102 tab_added_observer.Wait();
103 LOG(INFO) << "New tab.";
104 ui_test_utils::NavigateToURL(browser(),
105 base_url.Resolve("path2/empty.html"));
106 LOG(INFO) << "Nav 2.";
107 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02108 browser()->tab_strip_model()->GetWebContentsAt(2)->
109 GetRenderProcessHost()->GetID()));
110 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53111
112 // We should have opened 2 new extension tabs. Including the original blank
113 // tab, we now have 3 tabs. The two app tabs should not be in the same
114 // process, since they do not have the background permission. (Thus, we
115 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02116 ASSERT_EQ(3, browser()->tab_strip_model()->count());
117 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
118 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
[email protected]19da16a92012-05-23 17:11:29119 EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
[email protected]7b54ca02012-03-02 18:06:53120
121 // Opening tabs with window.open should keep the page in the opener's
122 // process.
[email protected]c987a242013-02-28 01:17:41123 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
124 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29125 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53126 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29127 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53128 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27129 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53130 }
131};
132
[email protected]079b3cc2012-09-26 19:59:13133// Omits the disable-popup-blocking flag so we can cover that case.
134class BlockedAppApiTest : public AppApiTest {
135 protected:
avi3ef9ec9e2014-12-22 22:50:17136 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]079b3cc2012-09-26 19:59:13137 ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:17138 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:51139 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]079b3cc2012-09-26 19:59:13140 }
141};
142
[email protected]7b54ca02012-03-02 18:06:53143// Tests that hosted apps with the background permission get a process-per-app
144// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56145// http://crbug.com/172750
[email protected]2340a3c2013-06-17 20:54:36146IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41147 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59148
[email protected]fafdc842014-01-17 18:09:08149 extensions::ProcessMap* process_map =
150 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52151
[email protected]3a8eecb2010-04-22 23:56:30152 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05153 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]3a8eecb2010-04-22 23:56:30154
[email protected]cbf4d1912010-08-12 18:24:57155 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30156
[email protected]87c7c292011-10-27 16:16:41157 LOG(INFO) << "Loaded extension.";
158
[email protected]cbf4d1912010-08-12 18:24:57159 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53160 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59161
[email protected]f0e13332011-05-20 22:41:14162 // Test both opening a URL in a new tab, and opening a tab and then navigating
163 // it. Either way, app tabs should be considered extension processes, but
164 // they have no elevated privileges and thus should not have WebUI bindings.
165 ui_test_utils::NavigateToURLWithDisposition(
166 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
167 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46168 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02169 browser()->tab_strip_model()->GetWebContentsAt(1)->
170 GetRenderProcessHost()->GetID()));
171 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41172 LOG(INFO) << "Nav 1.";
173
174 ui_test_utils::NavigateToURLWithDisposition(
175 browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
176 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46177 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02178 browser()->tab_strip_model()->GetWebContentsAt(2)->
179 GetRenderProcessHost()->GetID()));
180 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41181 LOG(INFO) << "Nav 2.";
182
[email protected]a7fe9112012-07-20 02:34:45183 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42184 chrome::NOTIFICATION_TAB_ADDED,
[email protected]87c7c292011-10-27 16:16:41185 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10186 chrome::NewTab(browser());
[email protected]87c7c292011-10-27 16:16:41187 tab_added_observer.Wait();
188 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57189 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41190 LOG(INFO) << "Nav 3.";
[email protected]6f371442011-11-09 06:45:46191 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02192 browser()->tab_strip_model()->GetWebContentsAt(3)->
193 GetRenderProcessHost()->GetID()));
194 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30195
[email protected]056ad2a2011-07-12 02:13:55196 // We should have opened 3 new extension tabs. Including the original blank
197 // tab, we now have 4 tabs. Because the app_process app has the background
198 // permission, all of its instances are in the same process. Thus two tabs
199 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02200 ASSERT_EQ(4, browser()->tab_strip_model()->count());
201 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57202
[email protected]19da16a92012-05-23 17:11:29203 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02204 browser()->tab_strip_model()->GetWebContentsAt(2)->
205 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29206 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02207 browser()->tab_strip_model()->GetWebContentsAt(3)->
208 GetRenderProcessHost());
[email protected]3a8eecb2010-04-22 23:56:30209
210 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41211 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
212 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29213 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41214 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29215 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41216 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15217 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17218 // argument), but we temporarily avoid swapping processes away from a hosted
219 // app if it has an opener, because some OAuth providers make script calls
220 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15221 // See crbug.com/59285.
[email protected]19da16a92012-05-23 17:11:29222 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41223 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30224
225 // Now let's have these pages navigate, into or out of the extension web
226 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36227 const GURL& app_url(base_url.Resolve("path1/empty.html"));
228 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02229 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
230 non_app_url);
[email protected]87c7c292011-10-27 16:16:41231 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02232 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
233 app_url);
[email protected]87c7c292011-10-27 16:16:41234 LOG(INFO) << "NavigateTabHelper 2.";
[email protected]ea7b7d82012-05-25 17:29:17235 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02236 browser()->tab_strip_model()->GetWebContentsAt(2)->
237 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29238 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02239 browser()->tab_strip_model()->GetWebContentsAt(3)->
240 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04241
242 // If one of the popup tabs navigates back to the app, window.opener should
243 // be valid.
[email protected]e0448872013-01-11 19:35:02244 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
245 app_url);
[email protected]87c7c292011-10-27 16:16:41246 LOG(INFO) << "NavigateTabHelper 3.";
[email protected]19da16a92012-05-23 17:11:29247 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02248 browser()->tab_strip_model()->GetWebContentsAt(6)->
249 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04250 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43251 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02252 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13253 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04254 &windowOpenerValid));
255 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41256
257 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30258}
[email protected]faf407b2011-01-05 01:24:32259
[email protected]056ad2a2011-07-12 02:13:55260// Test that hosted apps without the background permission use a process per app
261// instance model, such that separate instances are in separate processes.
[email protected]4ef849e2013-06-10 08:36:59262// Flaky on Windows. http://crbug.com/248047
263#if defined(OS_WIN)
264#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
265#else
266#define MAYBE_AppProcessInstances AppProcessInstances
267#endif
268IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53269 TestAppInstancesHelper("app_process_instances");
270}
[email protected]87c7c292011-10-27 16:16:41271
[email protected]7b54ca02012-03-02 18:06:53272// Test that hosted apps with the background permission but that set
273// allow_js_access to false also use a process per app instance model.
274// Separate instances should be in separate processes.
[email protected]0d70b7d42012-12-13 01:14:20275// Flaky on XP: http://crbug.com/165834
[email protected]0cfb748b2012-12-13 01:10:11276#if defined(OS_WIN)
277#define MAYBE_AppProcessBackgroundInstances \
278 DISABLED_AppProcessBackgroundInstances
279#else
280#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
281#endif
282IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53283 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55284}
285
[email protected]15877ca2011-11-18 22:40:52286// Tests that bookmark apps do not use the app process model and are treated
287// like normal web pages instead. http://crbug.com/104636.
[email protected]19506d542013-10-15 23:11:06288// Timing out on Windows. http://crbug.com/238777
289#if defined(OS_WIN)
290#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
291#else
292#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
293#endif
294IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
[email protected]06bdd2b2012-11-30 18:47:13295 ExtensionService* service = extensions::ExtensionSystem::Get(
296 browser()->profile())->extension_service();
[email protected]fafdc842014-01-17 18:09:08297 extensions::ProcessMap* process_map =
298 extensions::ProcessMap::Get(browser()->profile());
[email protected]15877ca2011-11-18 22:40:52299
300 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05301 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]15877ca2011-11-18 22:40:52302 GURL base_url = GetTestBaseURL("app_process");
303
[email protected]c2f36e3a2011-12-14 01:27:19304 // Load an app as a bookmark app.
305 std::string error;
[email protected]85df9d12014-04-15 17:02:14306 scoped_refptr<const Extension> extension(extensions::file_util::LoadExtension(
[email protected]c2f36e3a2011-12-14 01:27:19307 test_data_dir_.AppendASCII("app_process"),
[email protected]12075d12013-02-27 05:38:05308 extensions::Manifest::UNPACKED,
[email protected]c2f36e3a2011-12-14 01:27:19309 Extension::FROM_BOOKMARK,
310 &error));
[email protected]dc24976f2013-06-02 21:15:09311 service->OnExtensionInstalled(extension.get(),
[email protected]98270432012-09-11 20:51:24312 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]4a1d9c0d2014-06-13 12:50:11313 extensions::kInstallFlagInstallImmediately);
[email protected]c2f36e3a2011-12-14 01:27:19314 ASSERT_TRUE(extension.get());
315 ASSERT_TRUE(extension->from_bookmark());
316
[email protected]15877ca2011-11-18 22:40:52317 // Test both opening a URL in a new tab, and opening a tab and then navigating
318 // it. Either way, bookmark app tabs should be considered normal processes
319 // with no elevated privileges and no WebUI bindings.
320 ui_test_utils::NavigateToURLWithDisposition(
321 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
322 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
323 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02324 browser()->tab_strip_model()->GetWebContentsAt(1)->
325 GetRenderProcessHost()->GetID()));
326 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52327
[email protected]a7fe9112012-07-20 02:34:45328 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42329 chrome::NOTIFICATION_TAB_ADDED,
[email protected]15877ca2011-11-18 22:40:52330 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10331 chrome::NewTab(browser());
[email protected]15877ca2011-11-18 22:40:52332 tab_added_observer.Wait();
333 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
334 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02335 browser()->tab_strip_model()->GetWebContentsAt(2)->
336 GetRenderProcessHost()->GetID()));
337 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52338
339 // We should have opened 2 new bookmark app tabs. Including the original blank
340 // tab, we now have 3 tabs. Because normal pages use the
341 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02342 ASSERT_EQ(3, browser()->tab_strip_model()->count());
343 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]19da16a92012-05-23 17:11:29344 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02345 browser()->tab_strip_model()->GetWebContentsAt(2)->
346 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52347
348 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41349 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
350 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29351 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
352 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]15877ca2011-11-18 22:40:52353
354 // Now let's have a tab navigate out of and back into the app's web
355 // extent. Neither navigation should switch processes.
356 const GURL& app_url(base_url.Resolve("path1/empty.html"));
357 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03358 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02359 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
360 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
361 non_app_url);
[email protected]9f76c1e2012-03-05 15:15:58362 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02363 browser()->tab_strip_model()->GetWebContentsAt(2)->
364 GetRenderProcessHost());
365 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
366 app_url);
[email protected]9f76c1e2012-03-05 15:15:58367 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02368 browser()->tab_strip_model()->GetWebContentsAt(2)->
369 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52370}
371
[email protected]faf407b2011-01-05 01:24:32372// Tests that app process switching works properly in the following scenario:
373// 1. navigate to a page1 in the app
374// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
375// 3. page2 redirects back to a page in the app
376// The final navigation should end up in the app process.
377// See http://crbug.com/61757
John Abd-El-Malek3f7aec312014-08-27 03:18:10378// Flaky. http://crbug.com/341898
379IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32380 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05381 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]faf407b2011-01-05 01:24:32382
383 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
384
385 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53386 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32387
[email protected]a37d4b02012-06-25 21:56:10388 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32389 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10390 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17391 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48392 // 1. We navigate to redirect.html
393 // 2. Renderer navigates and finishes, counting as a load stop.
394 // 3. Renderer issues the meta refresh to navigate to server-redirect.
395 // 4. Renderer is now in a "provisional load", waiting for navigation to
396 // complete.
397 // 5. Browser sees a redirect response from server-redirect to empty.html, and
398 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17399 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
400 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48401 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17402 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32403
404 // 3 tabs, including the initial about:blank. The last 2 should be the same
405 // process.
[email protected]e0448872013-01-11 19:35:02406 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]c1dffe82013-06-26 20:59:05407 EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02408 browser()->tab_strip_model()->GetWebContentsAt(2)->
409 GetController().GetLastCommittedEntry()->GetURL().path());
410 EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
411 GetRenderProcessHost(),
412 browser()->tab_strip_model()->GetWebContentsAt(2)->
413 GetRenderProcessHost());
[email protected]faf407b2011-01-05 01:24:32414}
[email protected]d292d8a2011-05-25 03:47:11415
[email protected]aaef4752013-03-02 10:10:51416// Ensure that re-navigating to a URL after installing or uninstalling it as an
417// app correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36418//
[email protected]bc857a62013-05-08 16:44:53419// Fails on Windows. http://crbug.com/238670
[email protected]4c9d02082013-05-15 15:38:36420// Added logging to help diagnose the location of the problem.
[email protected]11170a772013-12-13 11:38:32421IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08422 extensions::ProcessMap* process_map =
423 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52424
[email protected]d292d8a2011-05-25 03:47:11425 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05426 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]d292d8a2011-05-25 03:47:11427
428 // The app under test acts on URLs whose host is "localhost",
429 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53430 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11431
432 // Load an app URL before loading the app.
[email protected]4c9d02082013-05-15 15:38:36433 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11434 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36435 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]e0448872013-01-11 19:35:02436 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46437 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52438 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11439
[email protected]aaef4752013-03-02 10:10:51440 // Load app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36441 LOG(INFO) << "Loading extension.";
[email protected]d292d8a2011-05-25 03:47:11442 const Extension* app =
443 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36444 LOG(INFO) << "Loading extension - done.";
[email protected]d292d8a2011-05-25 03:47:11445 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36446 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11447 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36448 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46449 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52450 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11451
[email protected]aaef4752013-03-02 10:10:51452 // Disable app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36453 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11454 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36455 LOG(INFO) << "Disabling extension - done.";
456 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11457 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36458 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46459 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52460 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51461}
462
463// Ensure that reloading a URL after installing or uninstalling it as an app
464// correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36465//
466// Added logging to help diagnose the location of the problem.
467// http://crbug.com/238670
[email protected]aaef4752013-03-02 10:10:51468IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08469 extensions::ProcessMap* process_map =
470 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51471
472 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05473 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]aaef4752013-03-02 10:10:51474
475 // The app under test acts on URLs whose host is "localhost",
476 // so the URLs we navigate to must have host "localhost".
477 GURL base_url = GetTestBaseURL("app_process");
478
479 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36480 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51481 const Extension* app =
482 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36483 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51484 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36485 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51486 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36487 LOG(INFO) << "Disabling extension - done.";
488 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51489 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36490 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51491 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
492 EXPECT_FALSE(process_map->Contains(
493 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11494
[email protected]8d3132f62011-10-12 07:13:42495 // Enable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36496 LOG(INFO) << "Enabling extension.";
[email protected]8d3132f62011-10-12 07:13:42497 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36498 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45499 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42500 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50501 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02502 &browser()->tab_strip_model()->GetActiveWebContents()->
503 GetController()));
[email protected]4c9d02082013-05-15 15:38:36504 LOG(INFO) << "Reloading.";
[email protected]a37d4b02012-06-25 21:56:10505 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42506 reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36507 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46508 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52509 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42510
511 // Disable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36512 LOG(INFO) << "Disabling extension.";
[email protected]8d3132f62011-10-12 07:13:42513 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36514 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45515 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42516 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50517 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02518 &browser()->tab_strip_model()->GetActiveWebContents()->
519 GetController()));
[email protected]4c9d02082013-05-15 15:38:36520 LOG(INFO) << "Reloading.";
[email protected]a37d4b02012-06-25 21:56:10521 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42522 reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36523 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46524 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52525 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51526}
527
528// Ensure that reloading a URL with JavaScript after installing or uninstalling
529// it as an app correctly swaps the process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36530//
531// Crashes on Windows and Mac. http://crbug.com/238670
532// Added logging to help diagnose the location of the problem.
533IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
[email protected]fafdc842014-01-17 18:09:08534 extensions::ProcessMap* process_map =
535 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51536
537 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05538 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]aaef4752013-03-02 10:10:51539
540 // The app under test acts on URLs whose host is "localhost",
541 // so the URLs we navigate to must have host "localhost".
542 GURL base_url = GetTestBaseURL("app_process");
543
544 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36545 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51546 const Extension* app =
547 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36548 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51549 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36550 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51551 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36552 LOG(INFO) << "Disabling extension - done.";
553 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51554 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36555 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51556 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
557 EXPECT_FALSE(process_map->Contains(
558 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42559
[email protected]d292d8a2011-05-25 03:47:11560 // Enable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36561 LOG(INFO) << "Enabling extension.";
[email protected]d292d8a2011-05-25 03:47:11562 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36563 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45564 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42565 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50566 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02567 &browser()->tab_strip_model()->GetActiveWebContents()->
568 GetController()));
[email protected]4c9d02082013-05-15 15:38:36569 LOG(INFO) << "Executing location.reload().";
[email protected]b6987e02013-01-04 18:30:43570 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42571 js_reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36572 LOG(INFO) << "Executing location.reload() - done.";
[email protected]6f371442011-11-09 06:45:46573 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52574 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11575
576 // Disable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36577 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11578 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36579 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45580 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42581 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50582 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02583 &browser()->tab_strip_model()->GetActiveWebContents()->
584 GetController()));
[email protected]4c9d02082013-05-15 15:38:36585 LOG(INFO) << "Executing location = location.";
[email protected]b6987e02013-01-04 18:30:43586 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42587 js_reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36588 LOG(INFO) << "Executing location = location - done.";
[email protected]6f371442011-11-09 06:45:46589 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52590 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11591}
[email protected]118d3122011-08-10 17:09:53592
[email protected]118d3122011-08-10 17:09:53593// Tests that if we have a non-app process (path3/container.html) that has an
594// iframe with a URL in the app's extent (path1/iframe.html), then opening a
595// link from that iframe to a new window to a URL in the app's extent (path1/
596// empty.html) results in the new window being in an app process. See
597// http://crbug.com/89272 for more details.
[email protected]1f4495b2012-10-12 05:51:05598IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
[email protected]988e6582013-07-22 19:32:47599#if defined(OS_WIN) && defined(USE_ASH)
600 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
avi3ef9ec9e2014-12-22 22:50:17601 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
602 switches::kAshBrowserTests))
[email protected]988e6582013-07-22 19:32:47603 return;
604#endif
605
[email protected]fafdc842014-01-17 18:09:08606 extensions::ProcessMap* process_map =
607 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52608
[email protected]118d3122011-08-10 17:09:53609 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05610 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]118d3122011-08-10 17:09:53611
612 GURL base_url = GetTestBaseURL("app_process");
613
614 // Load app and start URL (not in the app).
615 const Extension* app =
616 LoadExtension(test_data_dir_.AppendASCII("app_process"));
617 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29618
[email protected]19da16a92012-05-23 17:11:29619 ui_test_utils::NavigateToURL(browser(),
620 base_url.Resolve("path3/container.html"));
[email protected]6f371442011-11-09 06:45:46621 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02622 browser()->tab_strip_model()->GetWebContentsAt(0)->
623 GetRenderProcessHost()->GetID()));
[email protected]118d3122011-08-10 17:09:53624
[email protected]415dc61612013-10-29 04:35:27625 const BrowserList* active_browser_list =
626 BrowserList::GetInstance(chrome::GetActiveDesktop());
627 EXPECT_EQ(2U, active_browser_list->size());
628 content::WebContents* popup_contents =
629 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
630 content::WaitForLoadStop(popup_contents);
631
[email protected]118d3122011-08-10 17:09:53632 // Popup window should be in the app's process.
[email protected]415dc61612013-10-29 04:35:27633 RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
[email protected]19da16a92012-05-23 17:11:29634 EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
[email protected]118d3122011-08-10 17:09:53635}
[email protected]a09add52011-08-12 03:59:23636
[email protected]079b3cc2012-09-26 19:59:13637// Similar to the previous test, but ensure that popup blocking bypass
638// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05639#if defined(OS_CHROMEOS)
640// http://crbug.com/153513
641#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
642#else
643#define MAYBE_OpenAppFromIframe OpenAppFromIframe
644#endif
645IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13646 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05647 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]079b3cc2012-09-26 19:59:13648
649 // Load app and start URL (not in the app).
650 const Extension* app =
651 LoadExtension(test_data_dir_.AppendASCII("app_process"));
652 ASSERT_TRUE(app);
653
[email protected]079b3cc2012-09-26 19:59:13654 ui_test_utils::NavigateToURL(
655 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
656
[email protected]e0448872013-01-11 19:35:02657 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]e0731d72013-07-25 12:39:46658 PopupBlockerTabHelper* popup_blocker_tab_helper =
659 PopupBlockerTabHelper::FromWebContents(tab);
[email protected]992e2912013-08-19 15:05:24660 if (!popup_blocker_tab_helper->GetBlockedPopupsCount()) {
[email protected]e0731d72013-07-25 12:39:46661 content::WindowedNotificationObserver observer(
662 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
663 content::NotificationService::AllSources());
664 observer.Wait();
665 }
666
[email protected]992e2912013-08-19 15:05:24667 EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
[email protected]079b3cc2012-09-26 19:59:13668}
669
[email protected]88aae972011-12-16 01:14:18670// Tests that if an extension launches an app via chrome.tabs.create with an URL
[email protected]b0a29f22013-05-30 23:00:09671// that's not in the app's extent but that server redirects to it, we still end
672// up with an app process. See http://crbug.com/99349 for more details.
673IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
[email protected]88aae972011-12-16 01:14:18674 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05675 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]88aae972011-12-16 01:14:18676
677 LoadExtension(test_data_dir_.AppendASCII("app_process"));
678 const Extension* launcher =
679 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
680
[email protected]6169a5772013-05-29 17:41:14681 // There should be two navigations by the time the app page is loaded.
[email protected]88aae972011-12-16 01:14:18682 // 1. The extension launcher page.
[email protected]6169a5772013-05-29 17:41:14683 // 2. The app's URL (which includes a server redirect).
684 // Note that the server redirect does not generate a navigation event.
[email protected]5b8ff1c2012-06-02 20:42:20685 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46686 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]6169a5772013-05-29 17:41:14687 2);
[email protected]cbb1ef592013-06-05 19:49:46688 test_navigation_observer.StartWatchingNewWebContents();
[email protected]88aae972011-12-16 01:14:18689
690 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18691 ui_test_utils::NavigateToURL(
692 browser(), launcher->GetResourceURL("server_redirect.html"));
[email protected]b0a29f22013-05-30 23:00:09693
694 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59695 test_navigation_observer.Wait();
[email protected]b0a29f22013-05-30 23:00:09696
697 // App has loaded, and chrome.app.isInstalled should be true.
698 bool is_installed = false;
699 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
700 browser()->tab_strip_model()->GetActiveWebContents(),
701 "window.domAutomationController.send(chrome.app.isInstalled)",
702 &is_installed));
703 ASSERT_TRUE(is_installed);
704}
705
706// Tests that if an extension launches an app via chrome.tabs.create with an URL
707// that's not in the app's extent but that client redirects to it, we still end
708// up with an app process.
709IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
710 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05711 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]b0a29f22013-05-30 23:00:09712
713 LoadExtension(test_data_dir_.AppendASCII("app_process"));
714 const Extension* launcher =
715 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
716
717 // There should be three navigations by the time the app page is loaded.
718 // 1. The extension launcher page.
719 // 2. The URL that the extension launches, which client redirects.
720 // 3. The app's URL.
721 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46722 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]b0a29f22013-05-30 23:00:09723 3);
[email protected]cbb1ef592013-06-05 19:49:46724 test_navigation_observer.StartWatchingNewWebContents();
[email protected]b0a29f22013-05-30 23:00:09725
726 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18727 ui_test_utils::NavigateToURL(
728 browser(), launcher->GetResourceURL("client_redirect.html"));
[email protected]88aae972011-12-16 01:14:18729
730 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59731 test_navigation_observer.Wait();
[email protected]88aae972011-12-16 01:14:18732
733 // App has loaded, and chrome.app.isInstalled should be true.
734 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43735 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02736 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13737 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18738 &is_installed));
739 ASSERT_TRUE(is_installed);
740}
741
[email protected]d55c2382011-08-18 23:10:36742// Tests that if we have an app process (path1/container.html) with a non-app
743// iframe (path3/iframe.html), then opening a link from that iframe to a new
744// window to a same-origin non-app URL (path3/empty.html) should keep the window
745// in the app process.
746// This is in contrast to OpenAppFromIframe, since here the popup will not be
747// missing special permissions and should be scriptable from the iframe.
748// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29749IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]fafdc842014-01-17 18:09:08750 extensions::ProcessMap* process_map =
751 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52752
[email protected]d55c2382011-08-18 23:10:36753 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05754 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]d55c2382011-08-18 23:10:36755
756 GURL base_url = GetTestBaseURL("app_process");
757
758 // Load app and start URL (in the app).
759 const Extension* app =
760 LoadExtension(test_data_dir_.AppendASCII("app_process"));
761 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29762
[email protected]19da16a92012-05-23 17:11:29763 ui_test_utils::NavigateToURL(browser(),
764 base_url.Resolve("path1/container.html"));
[email protected]f3b1a082011-11-18 00:34:30765 content::RenderProcessHost* process =
[email protected]e0448872013-01-11 19:35:02766 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
[email protected]f3b1a082011-11-18 00:34:30767 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36768
[email protected]d55c2382011-08-18 23:10:36769 // Popup window should be in the app's process.
[email protected]415dc61612013-10-29 04:35:27770 const BrowserList* active_browser_list =
771 BrowserList::GetInstance(chrome::GetActiveDesktop());
772 EXPECT_EQ(2U, active_browser_list->size());
773 content::WebContents* popup_contents =
774 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
775 content::WaitForLoadStop(popup_contents);
776
777 RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
[email protected]19da16a92012-05-23 17:11:29778 EXPECT_EQ(process, popup_host->GetProcess());
[email protected]d55c2382011-08-18 23:10:36779}
780
[email protected]a344b762012-03-16 18:53:49781// http://crbug.com/118502
782#if defined(OS_MACOSX) || defined(OS_LINUX)
783#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
784#else
785#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
786#endif
787IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]fafdc842014-01-17 18:09:08788 extensions::ProcessMap* process_map =
789 extensions::ProcessMap::Get(browser()->profile());
[email protected]6f371442011-11-09 06:45:46790
[email protected]a09add52011-08-12 03:59:23791 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05792 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]a09add52011-08-12 03:59:23793
794 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
795
796 GURL base_url = GetTestBaseURL("app_process");
797
798 // Load the app, chrome.app.isInstalled should be true.
799 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02800 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46801 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52802 contents->GetRenderProcessHost()->GetID()));
[email protected]a09add52011-08-12 03:59:23803 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43804 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
805 contents,
[email protected]06bc5d92013-01-02 22:44:13806 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23807 &is_installed));
808 ASSERT_TRUE(is_installed);
809
810 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02811 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45812 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37813 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50814 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02815 &browser()->tab_strip_model()->GetActiveWebContents()->
816 GetController()));
[email protected]a37d4b02012-06-25 21:56:10817 chrome::Reload(browser(), CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37818 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43819 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
820 contents,
[email protected]06bc5d92013-01-02 22:44:13821 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23822 &is_installed));
823 ASSERT_TRUE(is_installed);
824}
[email protected]2aca9a92013-12-03 05:16:07825
826// Test that a cross-process navigation away from a hosted app stays in the same
827// BrowsingInstance, so that postMessage calls to the app's other windows still
828// work.
829IN_PROC_BROWSER_TEST_F(AppApiTest, SameBrowsingInstanceAfterSwap) {
[email protected]fafdc842014-01-17 18:09:08830 extensions::ProcessMap* process_map =
831 extensions::ProcessMap::Get(browser()->profile());
[email protected]2aca9a92013-12-03 05:16:07832
833 host_resolver()->AddRule("*", "127.0.0.1");
834 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
835
836 GURL base_url = GetTestBaseURL("app_process");
837
838 // Load app and start URL (in the app).
839 const Extension* app =
840 LoadExtension(test_data_dir_.AppendASCII("app_process"));
841 ASSERT_TRUE(app);
842
843 ui_test_utils::NavigateToURL(browser(),
844 base_url.Resolve("path1/iframe.html"));
845 content::SiteInstance* app_instance =
846 browser()->tab_strip_model()->GetWebContentsAt(0)->GetSiteInstance();
847 EXPECT_TRUE(process_map->Contains(app_instance->GetProcess()->GetID()));
848
849 // Popup window should be in the app's process.
850 const BrowserList* active_browser_list =
851 BrowserList::GetInstance(chrome::GetActiveDesktop());
852 EXPECT_EQ(2U, active_browser_list->size());
853 content::WebContents* popup_contents =
854 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
855 content::WaitForLoadStop(popup_contents);
856
857 SiteInstance* popup_instance = popup_contents->GetSiteInstance();
858 EXPECT_EQ(app_instance, popup_instance);
859
860 // Navigate the popup to another process outside the app.
861 GURL non_app_url(base_url.Resolve("path3/empty.html"));
862 ui_test_utils::NavigateToURL(active_browser_list->get(1), non_app_url);
863 SiteInstance* new_instance = popup_contents->GetSiteInstance();
864 EXPECT_NE(app_instance, new_instance);
865
866 // It should still be in the same BrowsingInstance, allowing postMessage to
867 // work.
868 EXPECT_TRUE(app_instance->IsRelatedSiteInstance(new_instance));
869}