blob: 26308a6a7733e4b8b63a72647e6b31dd68fe44ad [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"
8#include "chrome/browser/extensions/extension_host.h"
[email protected]6f371442011-11-09 06:45:469#include "chrome/browser/extensions/extension_service.h"
[email protected]06bdd2b2012-11-30 18:47:1310#include "chrome/browser/extensions/extension_system.h"
[email protected]6f371442011-11-09 06:45:4611#include "chrome/browser/extensions/process_map.h"
[email protected]8ecad5e2010-12-02 21:18:3312#include "chrome/browser/profiles/profile.h"
[email protected]e0731d72013-07-25 12:39:4613#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
[email protected]7b5dc002010-11-16 23:08:1014#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1015#include "chrome/browser/ui/browser_commands.h"
[email protected]d8748142012-05-16 21:13:4316#include "chrome/browser/ui/browser_finder.h"
[email protected]71b73f02011-04-06 15:57:2917#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3618#include "chrome/browser/ui/browser_window.h"
[email protected]e0448872013-01-11 19:35:0219#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]3a8eecb2010-04-22 23:56:3020#include "chrome/common/chrome_switches.h"
[email protected]814a7bf0f2011-08-13 05:30:5921#include "chrome/common/extensions/extension.h"
[email protected]c2f36e3a2011-12-14 01:27:1922#include "chrome/common/extensions/extension_file_util.h"
[email protected]b65d4bdcc2013-07-31 00:37:3323#include "chrome/test/base/test_switches.h"
[email protected]af44e7fb2011-07-29 18:32:3224#include "chrome/test/base/ui_test_utils.h"
[email protected]ad23a092011-12-28 07:02:0425#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0726#include "content/public/browser/notification_service.h"
[email protected]c333e792012-01-06 16:57:3927#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3328#include "content/public/browser/render_view_host.h"
[email protected]6acde6352012-01-04 16:52:2029#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4230#include "content/public/test/browser_test_utils.h"
[email protected]5b8ff1c2012-06-02 20:42:2031#include "content/public/test/test_navigation_observer.h"
[email protected]f2cb3cf2013-03-21 01:40:5332#include "net/dns/mock_host_resolver.h"
[email protected]c1dffe82013-06-26 20:59:0533#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]36b643212012-09-07 12:53:0034#include "sync/api/string_ordinal.h"
[email protected]3a8eecb2010-04-22 23:56:3035
[email protected]c5eed492012-01-04 17:07:5036using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1137using content::RenderViewHost;
[email protected]4ca15302012-01-03 05:53:2038using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3439using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2040
[email protected]7b54ca02012-03-02 18:06:5341class AppApiTest : public ExtensionApiTest {
42 protected:
43 // Gets the base URL for files for a specific test, making sure that it uses
44 // "localhost" as the hostname, since that is what the extent is declared
45 // as in the test apps manifests.
46 GURL GetTestBaseURL(std::string test_directory) {
47 GURL::Replacements replace_host;
48 std::string host_str("localhost"); // must stay in scope with replace_host
49 replace_host.SetHostStr(host_str);
[email protected]c1dffe82013-06-26 20:59:0550 GURL base_url = embedded_test_server()->GetURL(
51 "/extensions/api_test/" + test_directory + "/");
[email protected]7b54ca02012-03-02 18:06:5352 return base_url.ReplaceComponents(replace_host);
53 }
54
55 // Pass flags to make testing apps easier.
[email protected]49aeab62013-02-07 02:53:1156 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
[email protected]7b54ca02012-03-02 18:06:5357 ExtensionApiTest::SetUpCommandLine(command_line);
58 CommandLine::ForCurrentProcess()->AppendSwitch(
59 switches::kDisablePopupBlocking);
60 CommandLine::ForCurrentProcess()->AppendSwitch(
61 switches::kAllowHTTPBackgroundPage);
62 }
63
64 // Helper function to test that independent tabs of the named app are loaded
65 // into separate processes.
66 void TestAppInstancesHelper(std::string app_name) {
67 LOG(INFO) << "Start of test.";
68
[email protected]06bdd2b2012-11-30 18:47:1369 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
70 browser()->profile())->extension_service()->process_map();
[email protected]7b54ca02012-03-02 18:06:5371
72 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:0573 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]7b54ca02012-03-02 18:06:5374
75 ASSERT_TRUE(LoadExtension(
76 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2777 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5378
79 // Open two tabs in the app, one outside it.
80 GURL base_url = GetTestBaseURL(app_name);
81
82 // Test both opening a URL in a new tab, and opening a tab and then
83 // navigating it. Either way, app tabs should be considered extension
84 // processes, but they have no elevated privileges and thus should not
85 // have WebUI bindings.
86 ui_test_utils::NavigateToURLWithDisposition(
87 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
88 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
89 LOG(INFO) << "Nav 1.";
90 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:0291 browser()->tab_strip_model()->GetWebContentsAt(1)->
92 GetRenderProcessHost()->GetID()));
93 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:5394
[email protected]a7fe9112012-07-20 02:34:4595 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:4296 chrome::NOTIFICATION_TAB_ADDED,
[email protected]7b54ca02012-03-02 18:06:5397 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:1098 chrome::NewTab(browser());
[email protected]7b54ca02012-03-02 18:06:5399 tab_added_observer.Wait();
100 LOG(INFO) << "New tab.";
101 ui_test_utils::NavigateToURL(browser(),
102 base_url.Resolve("path2/empty.html"));
103 LOG(INFO) << "Nav 2.";
104 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02105 browser()->tab_strip_model()->GetWebContentsAt(2)->
106 GetRenderProcessHost()->GetID()));
107 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53108
109 // We should have opened 2 new extension tabs. Including the original blank
110 // tab, we now have 3 tabs. The two app tabs should not be in the same
111 // process, since they do not have the background permission. (Thus, we
112 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02113 ASSERT_EQ(3, browser()->tab_strip_model()->count());
114 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
115 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
[email protected]19da16a92012-05-23 17:11:29116 EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
[email protected]7b54ca02012-03-02 18:06:53117
118 // Opening tabs with window.open should keep the page in the opener's
119 // process.
[email protected]c987a242013-02-28 01:17:41120 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
121 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29122 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53123 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29124 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53125 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27126 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53127 }
128};
129
[email protected]079b3cc2012-09-26 19:59:13130// Omits the disable-popup-blocking flag so we can cover that case.
131class BlockedAppApiTest : public AppApiTest {
132 protected:
[email protected]49aeab62013-02-07 02:53:11133 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
[email protected]079b3cc2012-09-26 19:59:13134 ExtensionApiTest::SetUpCommandLine(command_line);
135 CommandLine::ForCurrentProcess()->AppendSwitch(
136 switches::kAllowHTTPBackgroundPage);
137 }
138};
139
[email protected]7b54ca02012-03-02 18:06:53140// Tests that hosted apps with the background permission get a process-per-app
141// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56142// http://crbug.com/172750
[email protected]2340a3c2013-06-17 20:54:36143IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41144 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59145
[email protected]06bdd2b2012-11-30 18:47:13146 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
147 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52148
[email protected]3a8eecb2010-04-22 23:56:30149 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05150 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]3a8eecb2010-04-22 23:56:30151
[email protected]cbf4d1912010-08-12 18:24:57152 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30153
[email protected]87c7c292011-10-27 16:16:41154 LOG(INFO) << "Loaded extension.";
155
[email protected]cbf4d1912010-08-12 18:24:57156 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53157 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59158
[email protected]f0e13332011-05-20 22:41:14159 // Test both opening a URL in a new tab, and opening a tab and then navigating
160 // it. Either way, app tabs should be considered extension processes, but
161 // they have no elevated privileges and thus should not have WebUI bindings.
162 ui_test_utils::NavigateToURLWithDisposition(
163 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
164 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46165 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02166 browser()->tab_strip_model()->GetWebContentsAt(1)->
167 GetRenderProcessHost()->GetID()));
168 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41169 LOG(INFO) << "Nav 1.";
170
171 ui_test_utils::NavigateToURLWithDisposition(
172 browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
173 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46174 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02175 browser()->tab_strip_model()->GetWebContentsAt(2)->
176 GetRenderProcessHost()->GetID()));
177 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41178 LOG(INFO) << "Nav 2.";
179
[email protected]a7fe9112012-07-20 02:34:45180 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42181 chrome::NOTIFICATION_TAB_ADDED,
[email protected]87c7c292011-10-27 16:16:41182 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10183 chrome::NewTab(browser());
[email protected]87c7c292011-10-27 16:16:41184 tab_added_observer.Wait();
185 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57186 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41187 LOG(INFO) << "Nav 3.";
[email protected]6f371442011-11-09 06:45:46188 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02189 browser()->tab_strip_model()->GetWebContentsAt(3)->
190 GetRenderProcessHost()->GetID()));
191 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30192
[email protected]056ad2a2011-07-12 02:13:55193 // We should have opened 3 new extension tabs. Including the original blank
194 // tab, we now have 4 tabs. Because the app_process app has the background
195 // permission, all of its instances are in the same process. Thus two tabs
196 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02197 ASSERT_EQ(4, browser()->tab_strip_model()->count());
198 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57199
[email protected]19da16a92012-05-23 17:11:29200 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02201 browser()->tab_strip_model()->GetWebContentsAt(2)->
202 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29203 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02204 browser()->tab_strip_model()->GetWebContentsAt(3)->
205 GetRenderProcessHost());
[email protected]3a8eecb2010-04-22 23:56:30206
207 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41208 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
209 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29210 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41211 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29212 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41213 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15214 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17215 // argument), but we temporarily avoid swapping processes away from a hosted
216 // app if it has an opener, because some OAuth providers make script calls
217 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15218 // See crbug.com/59285.
[email protected]19da16a92012-05-23 17:11:29219 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41220 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30221
222 // Now let's have these pages navigate, into or out of the extension web
223 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36224 const GURL& app_url(base_url.Resolve("path1/empty.html"));
225 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02226 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
227 non_app_url);
[email protected]87c7c292011-10-27 16:16:41228 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02229 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
230 app_url);
[email protected]87c7c292011-10-27 16:16:41231 LOG(INFO) << "NavigateTabHelper 2.";
[email protected]ea7b7d82012-05-25 17:29:17232 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02233 browser()->tab_strip_model()->GetWebContentsAt(2)->
234 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29235 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02236 browser()->tab_strip_model()->GetWebContentsAt(3)->
237 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04238
239 // If one of the popup tabs navigates back to the app, window.opener should
240 // be valid.
[email protected]e0448872013-01-11 19:35:02241 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
242 app_url);
[email protected]87c7c292011-10-27 16:16:41243 LOG(INFO) << "NavigateTabHelper 3.";
[email protected]19da16a92012-05-23 17:11:29244 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02245 browser()->tab_strip_model()->GetWebContentsAt(6)->
246 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04247 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43248 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02249 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13250 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04251 &windowOpenerValid));
252 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41253
254 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30255}
[email protected]faf407b2011-01-05 01:24:32256
[email protected]056ad2a2011-07-12 02:13:55257// Test that hosted apps without the background permission use a process per app
258// instance model, such that separate instances are in separate processes.
[email protected]4ef849e2013-06-10 08:36:59259// Flaky on Windows. http://crbug.com/248047
260#if defined(OS_WIN)
261#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
262#else
263#define MAYBE_AppProcessInstances AppProcessInstances
264#endif
265IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53266 TestAppInstancesHelper("app_process_instances");
267}
[email protected]87c7c292011-10-27 16:16:41268
[email protected]7b54ca02012-03-02 18:06:53269// Test that hosted apps with the background permission but that set
270// allow_js_access to false also use a process per app instance model.
271// Separate instances should be in separate processes.
[email protected]0d70b7d42012-12-13 01:14:20272// Flaky on XP: http://crbug.com/165834
[email protected]0cfb748b2012-12-13 01:10:11273#if defined(OS_WIN)
274#define MAYBE_AppProcessBackgroundInstances \
275 DISABLED_AppProcessBackgroundInstances
276#else
277#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
278#endif
279IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53280 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55281}
282
[email protected]15877ca2011-11-18 22:40:52283// Tests that bookmark apps do not use the app process model and are treated
284// like normal web pages instead. http://crbug.com/104636.
[email protected]b3b39672013-05-07 20:02:43285// Timing out on Windows. http://crbug.com/238777
286#if defined(OS_WIN)
287#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
288#else
289#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
290#endif
291IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
[email protected]06bdd2b2012-11-30 18:47:13292 ExtensionService* service = extensions::ExtensionSystem::Get(
293 browser()->profile())->extension_service();
[email protected]c2f36e3a2011-12-14 01:27:19294 extensions::ProcessMap* process_map = service->process_map();
[email protected]15877ca2011-11-18 22:40:52295
296 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05297 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]15877ca2011-11-18 22:40:52298 GURL base_url = GetTestBaseURL("app_process");
299
[email protected]c2f36e3a2011-12-14 01:27:19300 // Load an app as a bookmark app.
301 std::string error;
302 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
303 test_data_dir_.AppendASCII("app_process"),
[email protected]12075d12013-02-27 05:38:05304 extensions::Manifest::UNPACKED,
[email protected]c2f36e3a2011-12-14 01:27:19305 Extension::FROM_BOOKMARK,
306 &error));
[email protected]dc24976f2013-06-02 21:15:09307 service->OnExtensionInstalled(extension.get(),
[email protected]98270432012-09-11 20:51:24308 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]0db124b02012-11-07 04:55:05309 false /* no requirement errors */,
[email protected]9f3c8532013-07-31 19:52:07310 extensions::Blacklist::NOT_BLACKLISTED,
[email protected]0db124b02012-11-07 04:55:05311 false /* don't wait for idle */);
[email protected]c2f36e3a2011-12-14 01:27:19312 ASSERT_TRUE(extension.get());
313 ASSERT_TRUE(extension->from_bookmark());
314
[email protected]15877ca2011-11-18 22:40:52315 // Test both opening a URL in a new tab, and opening a tab and then navigating
316 // it. Either way, bookmark app tabs should be considered normal processes
317 // with no elevated privileges and no WebUI bindings.
318 ui_test_utils::NavigateToURLWithDisposition(
319 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
320 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
321 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02322 browser()->tab_strip_model()->GetWebContentsAt(1)->
323 GetRenderProcessHost()->GetID()));
324 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52325
[email protected]a7fe9112012-07-20 02:34:45326 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42327 chrome::NOTIFICATION_TAB_ADDED,
[email protected]15877ca2011-11-18 22:40:52328 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10329 chrome::NewTab(browser());
[email protected]15877ca2011-11-18 22:40:52330 tab_added_observer.Wait();
331 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
332 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02333 browser()->tab_strip_model()->GetWebContentsAt(2)->
334 GetRenderProcessHost()->GetID()));
335 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52336
337 // We should have opened 2 new bookmark app tabs. Including the original blank
338 // tab, we now have 3 tabs. Because normal pages use the
339 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02340 ASSERT_EQ(3, browser()->tab_strip_model()->count());
341 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]19da16a92012-05-23 17:11:29342 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02343 browser()->tab_strip_model()->GetWebContentsAt(2)->
344 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52345
346 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41347 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
348 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29349 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
350 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]15877ca2011-11-18 22:40:52351
352 // Now let's have a tab navigate out of and back into the app's web
353 // extent. Neither navigation should switch processes.
354 const GURL& app_url(base_url.Resolve("path1/empty.html"));
355 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03356 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02357 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
358 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
359 non_app_url);
[email protected]9f76c1e2012-03-05 15:15:58360 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02361 browser()->tab_strip_model()->GetWebContentsAt(2)->
362 GetRenderProcessHost());
363 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
364 app_url);
[email protected]9f76c1e2012-03-05 15:15:58365 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02366 browser()->tab_strip_model()->GetWebContentsAt(2)->
367 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52368}
369
[email protected]faf407b2011-01-05 01:24:32370// Tests that app process switching works properly in the following scenario:
371// 1. navigate to a page1 in the app
372// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
373// 3. page2 redirects back to a page in the app
374// The final navigation should end up in the app process.
375// See http://crbug.com/61757
[email protected]ea7b7d82012-05-25 17:29:17376IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32377 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05378 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]faf407b2011-01-05 01:24:32379
380 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
381
382 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53383 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32384
[email protected]a37d4b02012-06-25 21:56:10385 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32386 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10387 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17388 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48389 // 1. We navigate to redirect.html
390 // 2. Renderer navigates and finishes, counting as a load stop.
391 // 3. Renderer issues the meta refresh to navigate to server-redirect.
392 // 4. Renderer is now in a "provisional load", waiting for navigation to
393 // complete.
394 // 5. Browser sees a redirect response from server-redirect to empty.html, and
395 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17396 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
397 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48398 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17399 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32400
401 // 3 tabs, including the initial about:blank. The last 2 should be the same
402 // process.
[email protected]e0448872013-01-11 19:35:02403 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]c1dffe82013-06-26 20:59:05404 EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02405 browser()->tab_strip_model()->GetWebContentsAt(2)->
406 GetController().GetLastCommittedEntry()->GetURL().path());
407 EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
408 GetRenderProcessHost(),
409 browser()->tab_strip_model()->GetWebContentsAt(2)->
410 GetRenderProcessHost());
[email protected]faf407b2011-01-05 01:24:32411}
[email protected]d292d8a2011-05-25 03:47:11412
[email protected]aaef4752013-03-02 10:10:51413// Ensure that re-navigating to a URL after installing or uninstalling it as an
414// app correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36415//
[email protected]bc857a62013-05-08 16:44:53416// Fails on Windows. http://crbug.com/238670
[email protected]4c9d02082013-05-15 15:38:36417// Added logging to help diagnose the location of the problem.
418IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]06bdd2b2012-11-30 18:47:13419 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
420 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52421
[email protected]d292d8a2011-05-25 03:47:11422 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05423 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]d292d8a2011-05-25 03:47:11424
425 // The app under test acts on URLs whose host is "localhost",
426 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53427 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11428
429 // Load an app URL before loading the app.
[email protected]4c9d02082013-05-15 15:38:36430 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11431 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36432 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]e0448872013-01-11 19:35:02433 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46434 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52435 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11436
[email protected]aaef4752013-03-02 10:10:51437 // Load app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36438 LOG(INFO) << "Loading extension.";
[email protected]d292d8a2011-05-25 03:47:11439 const Extension* app =
440 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36441 LOG(INFO) << "Loading extension - done.";
[email protected]d292d8a2011-05-25 03:47:11442 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36443 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11444 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36445 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46446 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52447 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11448
[email protected]aaef4752013-03-02 10:10:51449 // Disable app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36450 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11451 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36452 LOG(INFO) << "Disabling extension - done.";
453 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11454 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36455 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46456 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52457 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51458}
459
460// Ensure that reloading a URL after installing or uninstalling it as an app
461// correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36462//
463// Added logging to help diagnose the location of the problem.
464// http://crbug.com/238670
[email protected]aaef4752013-03-02 10:10:51465IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
466 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
467 browser()->profile())->extension_service()->process_map();
468
469 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05470 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]aaef4752013-03-02 10:10:51471
472 // The app under test acts on URLs whose host is "localhost",
473 // so the URLs we navigate to must have host "localhost".
474 GURL base_url = GetTestBaseURL("app_process");
475
476 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36477 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51478 const Extension* app =
479 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36480 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51481 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36482 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51483 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36484 LOG(INFO) << "Disabling extension - done.";
485 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51486 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36487 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51488 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
489 EXPECT_FALSE(process_map->Contains(
490 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11491
[email protected]8d3132f62011-10-12 07:13:42492 // Enable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36493 LOG(INFO) << "Enabling extension.";
[email protected]8d3132f62011-10-12 07:13:42494 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36495 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45496 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42497 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50498 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02499 &browser()->tab_strip_model()->GetActiveWebContents()->
500 GetController()));
[email protected]4c9d02082013-05-15 15:38:36501 LOG(INFO) << "Reloading.";
[email protected]a37d4b02012-06-25 21:56:10502 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42503 reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36504 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46505 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52506 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42507
508 // Disable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36509 LOG(INFO) << "Disabling extension.";
[email protected]8d3132f62011-10-12 07:13:42510 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36511 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45512 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42513 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50514 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02515 &browser()->tab_strip_model()->GetActiveWebContents()->
516 GetController()));
[email protected]4c9d02082013-05-15 15:38:36517 LOG(INFO) << "Reloading.";
[email protected]a37d4b02012-06-25 21:56:10518 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42519 reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36520 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46521 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52522 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51523}
524
525// Ensure that reloading a URL with JavaScript after installing or uninstalling
526// it as an app correctly swaps the process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36527//
528// Crashes on Windows and Mac. http://crbug.com/238670
529// Added logging to help diagnose the location of the problem.
530IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
[email protected]aaef4752013-03-02 10:10:51531 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
532 browser()->profile())->extension_service()->process_map();
533
534 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05535 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]aaef4752013-03-02 10:10:51536
537 // The app under test acts on URLs whose host is "localhost",
538 // so the URLs we navigate to must have host "localhost".
539 GURL base_url = GetTestBaseURL("app_process");
540
541 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36542 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51543 const Extension* app =
544 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36545 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51546 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36547 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51548 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36549 LOG(INFO) << "Disabling extension - done.";
550 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51551 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36552 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51553 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
554 EXPECT_FALSE(process_map->Contains(
555 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42556
[email protected]d292d8a2011-05-25 03:47:11557 // Enable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36558 LOG(INFO) << "Enabling extension.";
[email protected]d292d8a2011-05-25 03:47:11559 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36560 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45561 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42562 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50563 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02564 &browser()->tab_strip_model()->GetActiveWebContents()->
565 GetController()));
[email protected]4c9d02082013-05-15 15:38:36566 LOG(INFO) << "Executing location.reload().";
[email protected]b6987e02013-01-04 18:30:43567 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42568 js_reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36569 LOG(INFO) << "Executing location.reload() - done.";
[email protected]6f371442011-11-09 06:45:46570 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52571 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11572
573 // Disable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36574 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11575 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36576 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45577 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42578 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50579 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02580 &browser()->tab_strip_model()->GetActiveWebContents()->
581 GetController()));
[email protected]4c9d02082013-05-15 15:38:36582 LOG(INFO) << "Executing location = location.";
[email protected]b6987e02013-01-04 18:30:43583 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42584 js_reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36585 LOG(INFO) << "Executing location = location - done.";
[email protected]6f371442011-11-09 06:45:46586 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52587 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11588}
[email protected]118d3122011-08-10 17:09:53589
[email protected]eab29432013-04-09 21:30:47590namespace {
591
592void RenderViewHostCreated(std::vector<content::RenderViewHost*>* rvh_vector,
593 content::RenderViewHost* rvh) {
594 rvh_vector->push_back(rvh);
595}
596
597} // namespace
598
[email protected]118d3122011-08-10 17:09:53599// Tests that if we have a non-app process (path3/container.html) that has an
600// iframe with a URL in the app's extent (path1/iframe.html), then opening a
601// link from that iframe to a new window to a URL in the app's extent (path1/
602// empty.html) results in the new window being in an app process. See
603// http://crbug.com/89272 for more details.
[email protected]1f4495b2012-10-12 05:51:05604IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
[email protected]988e6582013-07-22 19:32:47605#if defined(OS_WIN) && defined(USE_ASH)
606 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
[email protected]b65d4bdcc2013-07-31 00:37:33607 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
[email protected]988e6582013-07-22 19:32:47608 return;
609#endif
610
[email protected]06bdd2b2012-11-30 18:47:13611 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
612 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52613
[email protected]118d3122011-08-10 17:09:53614 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05615 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]118d3122011-08-10 17:09:53616
617 GURL base_url = GetTestBaseURL("app_process");
618
619 // Load app and start URL (not in the app).
620 const Extension* app =
621 LoadExtension(test_data_dir_.AppendASCII("app_process"));
622 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29623
[email protected]eab29432013-04-09 21:30:47624 std::vector<content::RenderViewHost*> rvh_vector;
625 content::RenderViewHost::CreatedCallback rvh_callback(
626 base::Bind(&RenderViewHostCreated, &rvh_vector));
627 content::RenderViewHost::AddCreatedCallback(rvh_callback);
[email protected]19da16a92012-05-23 17:11:29628 ui_test_utils::NavigateToURL(browser(),
629 base_url.Resolve("path3/container.html"));
[email protected]eab29432013-04-09 21:30:47630 content::RenderViewHost::RemoveCreatedCallback(rvh_callback);
[email protected]6f371442011-11-09 06:45:46631 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02632 browser()->tab_strip_model()->GetWebContentsAt(0)->
633 GetRenderProcessHost()->GetID()));
[email protected]118d3122011-08-10 17:09:53634
635 // Popup window should be in the app's process.
[email protected]eab29432013-04-09 21:30:47636 ASSERT_EQ(3U, rvh_vector.size());
637 RenderViewHost* popup_host = rvh_vector[2];
[email protected]19da16a92012-05-23 17:11:29638 EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
[email protected]118d3122011-08-10 17:09:53639}
[email protected]a09add52011-08-12 03:59:23640
[email protected]079b3cc2012-09-26 19:59:13641// Similar to the previous test, but ensure that popup blocking bypass
642// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05643#if defined(OS_CHROMEOS)
644// http://crbug.com/153513
645#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
646#else
647#define MAYBE_OpenAppFromIframe OpenAppFromIframe
648#endif
649IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13650 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05651 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]079b3cc2012-09-26 19:59:13652
653 // Load app and start URL (not in the app).
654 const Extension* app =
655 LoadExtension(test_data_dir_.AppendASCII("app_process"));
656 ASSERT_TRUE(app);
657
[email protected]079b3cc2012-09-26 19:59:13658 ui_test_utils::NavigateToURL(
659 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
660
[email protected]e0448872013-01-11 19:35:02661 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]e0731d72013-07-25 12:39:46662 PopupBlockerTabHelper* popup_blocker_tab_helper =
663 PopupBlockerTabHelper::FromWebContents(tab);
[email protected]992e2912013-08-19 15:05:24664 if (!popup_blocker_tab_helper->GetBlockedPopupsCount()) {
[email protected]e0731d72013-07-25 12:39:46665 content::WindowedNotificationObserver observer(
666 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
667 content::NotificationService::AllSources());
668 observer.Wait();
669 }
670
[email protected]992e2912013-08-19 15:05:24671 EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
[email protected]079b3cc2012-09-26 19:59:13672}
673
[email protected]88aae972011-12-16 01:14:18674// Tests that if an extension launches an app via chrome.tabs.create with an URL
[email protected]b0a29f22013-05-30 23:00:09675// that's not in the app's extent but that server redirects to it, we still end
676// up with an app process. See http://crbug.com/99349 for more details.
677IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
[email protected]88aae972011-12-16 01:14:18678 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05679 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]88aae972011-12-16 01:14:18680
681 LoadExtension(test_data_dir_.AppendASCII("app_process"));
682 const Extension* launcher =
683 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
684
[email protected]6169a5772013-05-29 17:41:14685 // There should be two navigations by the time the app page is loaded.
[email protected]88aae972011-12-16 01:14:18686 // 1. The extension launcher page.
[email protected]6169a5772013-05-29 17:41:14687 // 2. The app's URL (which includes a server redirect).
688 // Note that the server redirect does not generate a navigation event.
[email protected]5b8ff1c2012-06-02 20:42:20689 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46690 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]6169a5772013-05-29 17:41:14691 2);
[email protected]cbb1ef592013-06-05 19:49:46692 test_navigation_observer.StartWatchingNewWebContents();
[email protected]88aae972011-12-16 01:14:18693
694 // Load the launcher extension, which should launch the app.
695 ui_test_utils::NavigateToURLWithDisposition(
696 browser(),
[email protected]b0a29f22013-05-30 23:00:09697 launcher->GetResourceURL("server_redirect.html"),
698 CURRENT_TAB,
699 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
700
701 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59702 test_navigation_observer.Wait();
[email protected]b0a29f22013-05-30 23:00:09703
704 // App has loaded, and chrome.app.isInstalled should be true.
705 bool is_installed = false;
706 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
707 browser()->tab_strip_model()->GetActiveWebContents(),
708 "window.domAutomationController.send(chrome.app.isInstalled)",
709 &is_installed));
710 ASSERT_TRUE(is_installed);
711}
712
713// Tests that if an extension launches an app via chrome.tabs.create with an URL
714// that's not in the app's extent but that client redirects to it, we still end
715// up with an app process.
716IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
717 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05718 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]b0a29f22013-05-30 23:00:09719
720 LoadExtension(test_data_dir_.AppendASCII("app_process"));
721 const Extension* launcher =
722 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
723
724 // There should be three navigations by the time the app page is loaded.
725 // 1. The extension launcher page.
726 // 2. The URL that the extension launches, which client redirects.
727 // 3. The app's URL.
728 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46729 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]b0a29f22013-05-30 23:00:09730 3);
[email protected]cbb1ef592013-06-05 19:49:46731 test_navigation_observer.StartWatchingNewWebContents();
[email protected]b0a29f22013-05-30 23:00:09732
733 // Load the launcher extension, which should launch the app.
734 ui_test_utils::NavigateToURLWithDisposition(
735 browser(),
736 launcher->GetResourceURL("client_redirect.html"),
[email protected]88aae972011-12-16 01:14:18737 CURRENT_TAB,
738 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
739
740 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59741 test_navigation_observer.Wait();
[email protected]88aae972011-12-16 01:14:18742
743 // App has loaded, and chrome.app.isInstalled should be true.
744 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43745 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02746 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13747 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18748 &is_installed));
749 ASSERT_TRUE(is_installed);
750}
751
[email protected]d55c2382011-08-18 23:10:36752// Tests that if we have an app process (path1/container.html) with a non-app
753// iframe (path3/iframe.html), then opening a link from that iframe to a new
754// window to a same-origin non-app URL (path3/empty.html) should keep the window
755// in the app process.
756// This is in contrast to OpenAppFromIframe, since here the popup will not be
757// missing special permissions and should be scriptable from the iframe.
758// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29759IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]06bdd2b2012-11-30 18:47:13760 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
761 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52762
[email protected]d55c2382011-08-18 23:10:36763 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05764 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]d55c2382011-08-18 23:10:36765
766 GURL base_url = GetTestBaseURL("app_process");
767
768 // Load app and start URL (in the app).
769 const Extension* app =
770 LoadExtension(test_data_dir_.AppendASCII("app_process"));
771 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29772
[email protected]eab29432013-04-09 21:30:47773 std::vector<content::RenderViewHost*> rvh_vector;
774 content::RenderViewHost::CreatedCallback rvh_callback(
775 base::Bind(&RenderViewHostCreated, &rvh_vector));
776 content::RenderViewHost::AddCreatedCallback(rvh_callback);
[email protected]19da16a92012-05-23 17:11:29777 ui_test_utils::NavigateToURL(browser(),
778 base_url.Resolve("path1/container.html"));
[email protected]eab29432013-04-09 21:30:47779 content::RenderViewHost::RemoveCreatedCallback(rvh_callback);
[email protected]f3b1a082011-11-18 00:34:30780 content::RenderProcessHost* process =
[email protected]e0448872013-01-11 19:35:02781 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
[email protected]f3b1a082011-11-18 00:34:30782 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36783
[email protected]d55c2382011-08-18 23:10:36784 // Popup window should be in the app's process.
[email protected]eab29432013-04-09 21:30:47785 ASSERT_EQ(2U, rvh_vector.size());
786 RenderViewHost* popup_host = rvh_vector[1];
[email protected]19da16a92012-05-23 17:11:29787 EXPECT_EQ(process, popup_host->GetProcess());
[email protected]d55c2382011-08-18 23:10:36788}
789
[email protected]a344b762012-03-16 18:53:49790// http://crbug.com/118502
791#if defined(OS_MACOSX) || defined(OS_LINUX)
792#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
793#else
794#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
795#endif
796IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]06bdd2b2012-11-30 18:47:13797 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
798 browser()->profile())->extension_service()->process_map();
[email protected]6f371442011-11-09 06:45:46799
[email protected]a09add52011-08-12 03:59:23800 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05801 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]a09add52011-08-12 03:59:23802
803 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
804
805 GURL base_url = GetTestBaseURL("app_process");
806
807 // Load the app, chrome.app.isInstalled should be true.
808 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02809 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46810 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52811 contents->GetRenderProcessHost()->GetID()));
[email protected]a09add52011-08-12 03:59:23812 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43813 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
814 contents,
[email protected]06bc5d92013-01-02 22:44:13815 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23816 &is_installed));
817 ASSERT_TRUE(is_installed);
818
819 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02820 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45821 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37822 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50823 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02824 &browser()->tab_strip_model()->GetActiveWebContents()->
825 GetController()));
[email protected]a37d4b02012-06-25 21:56:10826 chrome::Reload(browser(), CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37827 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43828 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
829 contents,
[email protected]06bc5d92013-01-02 22:44:13830 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23831 &is_installed));
832 ASSERT_TRUE(is_installed);
833}