blob: 7f4dd7bbb2b0ec36e250b6f193b940b9e7704245 [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]fdf40f3e2013-07-11 23:55:465#include "chrome/browser/chrome_notification_types.h"
[email protected]3a8eecb2010-04-22 23:56:306#include "chrome/browser/extensions/extension_apitest.h"
7#include "chrome/browser/extensions/extension_host.h"
[email protected]6f371442011-11-09 06:45:468#include "chrome/browser/extensions/extension_service.h"
[email protected]06bdd2b2012-11-30 18:47:139#include "chrome/browser/extensions/extension_system.h"
[email protected]6f371442011-11-09 06:45:4610#include "chrome/browser/extensions/process_map.h"
[email protected]8ecad5e2010-12-02 21:18:3311#include "chrome/browser/profiles/profile.h"
[email protected]079b3cc2012-09-26 19:59:1312#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]7b5dc002010-11-16 23:08:1013#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1014#include "chrome/browser/ui/browser_commands.h"
[email protected]d8748142012-05-16 21:13:4315#include "chrome/browser/ui/browser_finder.h"
[email protected]71b73f02011-04-06 15:57:2916#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3617#include "chrome/browser/ui/browser_window.h"
[email protected]e0448872013-01-11 19:35:0218#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]3a8eecb2010-04-22 23:56:3019#include "chrome/common/chrome_switches.h"
[email protected]814a7bf0f2011-08-13 05:30:5920#include "chrome/common/extensions/extension.h"
[email protected]c2f36e3a2011-12-14 01:27:1921#include "chrome/common/extensions/extension_file_util.h"
[email protected]af44e7fb2011-07-29 18:32:3222#include "chrome/test/base/ui_test_utils.h"
[email protected]ad23a092011-12-28 07:02:0423#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0724#include "content/public/browser/notification_service.h"
[email protected]c333e792012-01-06 16:57:3925#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3326#include "content/public/browser/render_view_host.h"
[email protected]6acde6352012-01-04 16:52:2027#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4228#include "content/public/test/browser_test_utils.h"
[email protected]5b8ff1c2012-06-02 20:42:2029#include "content/public/test/test_navigation_observer.h"
[email protected]f2cb3cf2013-03-21 01:40:5330#include "net/dns/mock_host_resolver.h"
[email protected]c1dffe82013-06-26 20:59:0531#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]36b643212012-09-07 12:53:0032#include "sync/api/string_ordinal.h"
[email protected]3a8eecb2010-04-22 23:56:3033
[email protected]c5eed492012-01-04 17:07:5034using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1135using content::RenderViewHost;
[email protected]4ca15302012-01-03 05:53:2036using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3437using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2038
[email protected]7b54ca02012-03-02 18:06:5339class AppApiTest : public ExtensionApiTest {
40 protected:
41 // Gets the base URL for files for a specific test, making sure that it uses
42 // "localhost" as the hostname, since that is what the extent is declared
43 // as in the test apps manifests.
44 GURL GetTestBaseURL(std::string test_directory) {
45 GURL::Replacements replace_host;
46 std::string host_str("localhost"); // must stay in scope with replace_host
47 replace_host.SetHostStr(host_str);
[email protected]c1dffe82013-06-26 20:59:0548 GURL base_url = embedded_test_server()->GetURL(
49 "/extensions/api_test/" + test_directory + "/");
[email protected]7b54ca02012-03-02 18:06:5350 return base_url.ReplaceComponents(replace_host);
51 }
52
53 // Pass flags to make testing apps easier.
[email protected]49aeab62013-02-07 02:53:1154 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
[email protected]7b54ca02012-03-02 18:06:5355 ExtensionApiTest::SetUpCommandLine(command_line);
56 CommandLine::ForCurrentProcess()->AppendSwitch(
57 switches::kDisablePopupBlocking);
58 CommandLine::ForCurrentProcess()->AppendSwitch(
59 switches::kAllowHTTPBackgroundPage);
60 }
61
62 // Helper function to test that independent tabs of the named app are loaded
63 // into separate processes.
64 void TestAppInstancesHelper(std::string app_name) {
65 LOG(INFO) << "Start of test.";
66
[email protected]06bdd2b2012-11-30 18:47:1367 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
68 browser()->profile())->extension_service()->process_map();
[email protected]7b54ca02012-03-02 18:06:5369
70 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:0571 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]7b54ca02012-03-02 18:06:5372
73 ASSERT_TRUE(LoadExtension(
74 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2775 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5376
77 // Open two tabs in the app, one outside it.
78 GURL base_url = GetTestBaseURL(app_name);
79
80 // Test both opening a URL in a new tab, and opening a tab and then
81 // navigating it. Either way, app tabs should be considered extension
82 // processes, but they have no elevated privileges and thus should not
83 // have WebUI bindings.
84 ui_test_utils::NavigateToURLWithDisposition(
85 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
86 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
87 LOG(INFO) << "Nav 1.";
88 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:0289 browser()->tab_strip_model()->GetWebContentsAt(1)->
90 GetRenderProcessHost()->GetID()));
91 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:5392
[email protected]a7fe9112012-07-20 02:34:4593 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:4294 chrome::NOTIFICATION_TAB_ADDED,
[email protected]7b54ca02012-03-02 18:06:5395 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:1096 chrome::NewTab(browser());
[email protected]7b54ca02012-03-02 18:06:5397 tab_added_observer.Wait();
98 LOG(INFO) << "New tab.";
99 ui_test_utils::NavigateToURL(browser(),
100 base_url.Resolve("path2/empty.html"));
101 LOG(INFO) << "Nav 2.";
102 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02103 browser()->tab_strip_model()->GetWebContentsAt(2)->
104 GetRenderProcessHost()->GetID()));
105 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53106
107 // We should have opened 2 new extension tabs. Including the original blank
108 // tab, we now have 3 tabs. The two app tabs should not be in the same
109 // process, since they do not have the background permission. (Thus, we
110 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02111 ASSERT_EQ(3, browser()->tab_strip_model()->count());
112 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
113 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
[email protected]19da16a92012-05-23 17:11:29114 EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
[email protected]7b54ca02012-03-02 18:06:53115
116 // Opening tabs with window.open should keep the page in the opener's
117 // process.
[email protected]c987a242013-02-28 01:17:41118 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
119 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29120 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53121 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29122 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53123 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27124 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53125 }
126};
127
[email protected]079b3cc2012-09-26 19:59:13128// Omits the disable-popup-blocking flag so we can cover that case.
129class BlockedAppApiTest : public AppApiTest {
130 protected:
[email protected]49aeab62013-02-07 02:53:11131 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
[email protected]079b3cc2012-09-26 19:59:13132 ExtensionApiTest::SetUpCommandLine(command_line);
133 CommandLine::ForCurrentProcess()->AppendSwitch(
134 switches::kAllowHTTPBackgroundPage);
135 }
136};
137
[email protected]7b54ca02012-03-02 18:06:53138// Tests that hosted apps with the background permission get a process-per-app
139// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56140// http://crbug.com/172750
[email protected]2340a3c2013-06-17 20:54:36141IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41142 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59143
[email protected]06bdd2b2012-11-30 18:47:13144 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
145 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52146
[email protected]3a8eecb2010-04-22 23:56:30147 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05148 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]3a8eecb2010-04-22 23:56:30149
[email protected]cbf4d1912010-08-12 18:24:57150 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30151
[email protected]87c7c292011-10-27 16:16:41152 LOG(INFO) << "Loaded extension.";
153
[email protected]cbf4d1912010-08-12 18:24:57154 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53155 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59156
[email protected]f0e13332011-05-20 22:41:14157 // Test both opening a URL in a new tab, and opening a tab and then navigating
158 // it. Either way, app tabs should be considered extension processes, but
159 // they have no elevated privileges and thus should not have WebUI bindings.
160 ui_test_utils::NavigateToURLWithDisposition(
161 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
162 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46163 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02164 browser()->tab_strip_model()->GetWebContentsAt(1)->
165 GetRenderProcessHost()->GetID()));
166 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41167 LOG(INFO) << "Nav 1.";
168
169 ui_test_utils::NavigateToURLWithDisposition(
170 browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
171 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46172 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02173 browser()->tab_strip_model()->GetWebContentsAt(2)->
174 GetRenderProcessHost()->GetID()));
175 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41176 LOG(INFO) << "Nav 2.";
177
[email protected]a7fe9112012-07-20 02:34:45178 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42179 chrome::NOTIFICATION_TAB_ADDED,
[email protected]87c7c292011-10-27 16:16:41180 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10181 chrome::NewTab(browser());
[email protected]87c7c292011-10-27 16:16:41182 tab_added_observer.Wait();
183 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57184 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41185 LOG(INFO) << "Nav 3.";
[email protected]6f371442011-11-09 06:45:46186 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02187 browser()->tab_strip_model()->GetWebContentsAt(3)->
188 GetRenderProcessHost()->GetID()));
189 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30190
[email protected]056ad2a2011-07-12 02:13:55191 // We should have opened 3 new extension tabs. Including the original blank
192 // tab, we now have 4 tabs. Because the app_process app has the background
193 // permission, all of its instances are in the same process. Thus two tabs
194 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02195 ASSERT_EQ(4, browser()->tab_strip_model()->count());
196 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57197
[email protected]19da16a92012-05-23 17:11:29198 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02199 browser()->tab_strip_model()->GetWebContentsAt(2)->
200 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29201 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02202 browser()->tab_strip_model()->GetWebContentsAt(3)->
203 GetRenderProcessHost());
[email protected]3a8eecb2010-04-22 23:56:30204
205 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41206 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
207 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29208 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41209 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29210 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41211 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15212 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17213 // argument), but we temporarily avoid swapping processes away from a hosted
214 // app if it has an opener, because some OAuth providers make script calls
215 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15216 // See crbug.com/59285.
[email protected]19da16a92012-05-23 17:11:29217 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41218 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30219
220 // Now let's have these pages navigate, into or out of the extension web
221 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36222 const GURL& app_url(base_url.Resolve("path1/empty.html"));
223 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02224 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
225 non_app_url);
[email protected]87c7c292011-10-27 16:16:41226 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02227 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
228 app_url);
[email protected]87c7c292011-10-27 16:16:41229 LOG(INFO) << "NavigateTabHelper 2.";
[email protected]ea7b7d82012-05-25 17:29:17230 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02231 browser()->tab_strip_model()->GetWebContentsAt(2)->
232 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29233 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02234 browser()->tab_strip_model()->GetWebContentsAt(3)->
235 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04236
237 // If one of the popup tabs navigates back to the app, window.opener should
238 // be valid.
[email protected]e0448872013-01-11 19:35:02239 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
240 app_url);
[email protected]87c7c292011-10-27 16:16:41241 LOG(INFO) << "NavigateTabHelper 3.";
[email protected]19da16a92012-05-23 17:11:29242 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02243 browser()->tab_strip_model()->GetWebContentsAt(6)->
244 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04245 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43246 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02247 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13248 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04249 &windowOpenerValid));
250 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41251
252 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30253}
[email protected]faf407b2011-01-05 01:24:32254
[email protected]056ad2a2011-07-12 02:13:55255// Test that hosted apps without the background permission use a process per app
256// instance model, such that separate instances are in separate processes.
[email protected]4ef849e2013-06-10 08:36:59257// Flaky on Windows. http://crbug.com/248047
258#if defined(OS_WIN)
259#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
260#else
261#define MAYBE_AppProcessInstances AppProcessInstances
262#endif
263IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53264 TestAppInstancesHelper("app_process_instances");
265}
[email protected]87c7c292011-10-27 16:16:41266
[email protected]7b54ca02012-03-02 18:06:53267// Test that hosted apps with the background permission but that set
268// allow_js_access to false also use a process per app instance model.
269// Separate instances should be in separate processes.
[email protected]0d70b7d42012-12-13 01:14:20270// Flaky on XP: http://crbug.com/165834
[email protected]0cfb748b2012-12-13 01:10:11271#if defined(OS_WIN)
272#define MAYBE_AppProcessBackgroundInstances \
273 DISABLED_AppProcessBackgroundInstances
274#else
275#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
276#endif
277IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53278 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55279}
280
[email protected]15877ca2011-11-18 22:40:52281// Tests that bookmark apps do not use the app process model and are treated
282// like normal web pages instead. http://crbug.com/104636.
[email protected]b3b39672013-05-07 20:02:43283// Timing out on Windows. http://crbug.com/238777
284#if defined(OS_WIN)
285#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
286#else
287#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
288#endif
289IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
[email protected]06bdd2b2012-11-30 18:47:13290 ExtensionService* service = extensions::ExtensionSystem::Get(
291 browser()->profile())->extension_service();
[email protected]c2f36e3a2011-12-14 01:27:19292 extensions::ProcessMap* process_map = service->process_map();
[email protected]15877ca2011-11-18 22:40:52293
294 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05295 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]15877ca2011-11-18 22:40:52296 GURL base_url = GetTestBaseURL("app_process");
297
[email protected]c2f36e3a2011-12-14 01:27:19298 // Load an app as a bookmark app.
299 std::string error;
300 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
301 test_data_dir_.AppendASCII("app_process"),
[email protected]12075d12013-02-27 05:38:05302 extensions::Manifest::UNPACKED,
[email protected]c2f36e3a2011-12-14 01:27:19303 Extension::FROM_BOOKMARK,
304 &error));
[email protected]dc24976f2013-06-02 21:15:09305 service->OnExtensionInstalled(extension.get(),
[email protected]98270432012-09-11 20:51:24306 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]0db124b02012-11-07 04:55:05307 false /* no requirement errors */,
308 false /* don't wait for idle */);
[email protected]c2f36e3a2011-12-14 01:27:19309 ASSERT_TRUE(extension.get());
310 ASSERT_TRUE(extension->from_bookmark());
311
[email protected]15877ca2011-11-18 22:40:52312 // Test both opening a URL in a new tab, and opening a tab and then navigating
313 // it. Either way, bookmark app tabs should be considered normal processes
314 // with no elevated privileges and no WebUI bindings.
315 ui_test_utils::NavigateToURLWithDisposition(
316 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
317 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
318 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02319 browser()->tab_strip_model()->GetWebContentsAt(1)->
320 GetRenderProcessHost()->GetID()));
321 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52322
[email protected]a7fe9112012-07-20 02:34:45323 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42324 chrome::NOTIFICATION_TAB_ADDED,
[email protected]15877ca2011-11-18 22:40:52325 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10326 chrome::NewTab(browser());
[email protected]15877ca2011-11-18 22:40:52327 tab_added_observer.Wait();
328 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
329 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02330 browser()->tab_strip_model()->GetWebContentsAt(2)->
331 GetRenderProcessHost()->GetID()));
332 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52333
334 // We should have opened 2 new bookmark app tabs. Including the original blank
335 // tab, we now have 3 tabs. Because normal pages use the
336 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02337 ASSERT_EQ(3, browser()->tab_strip_model()->count());
338 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]19da16a92012-05-23 17:11:29339 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02340 browser()->tab_strip_model()->GetWebContentsAt(2)->
341 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52342
343 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41344 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
345 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29346 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
347 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]15877ca2011-11-18 22:40:52348
349 // Now let's have a tab navigate out of and back into the app's web
350 // extent. Neither navigation should switch processes.
351 const GURL& app_url(base_url.Resolve("path1/empty.html"));
352 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03353 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02354 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
355 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
356 non_app_url);
[email protected]9f76c1e2012-03-05 15:15:58357 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02358 browser()->tab_strip_model()->GetWebContentsAt(2)->
359 GetRenderProcessHost());
360 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
361 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());
[email protected]15877ca2011-11-18 22:40:52365}
366
[email protected]faf407b2011-01-05 01:24:32367// Tests that app process switching works properly in the following scenario:
368// 1. navigate to a page1 in the app
369// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
370// 3. page2 redirects back to a page in the app
371// The final navigation should end up in the app process.
372// See http://crbug.com/61757
[email protected]ea7b7d82012-05-25 17:29:17373IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32374 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05375 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]faf407b2011-01-05 01:24:32376
377 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
378
379 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53380 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32381
[email protected]a37d4b02012-06-25 21:56:10382 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32383 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10384 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17385 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48386 // 1. We navigate to redirect.html
387 // 2. Renderer navigates and finishes, counting as a load stop.
388 // 3. Renderer issues the meta refresh to navigate to server-redirect.
389 // 4. Renderer is now in a "provisional load", waiting for navigation to
390 // complete.
391 // 5. Browser sees a redirect response from server-redirect to empty.html, and
392 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17393 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
394 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48395 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17396 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32397
398 // 3 tabs, including the initial about:blank. The last 2 should be the same
399 // process.
[email protected]e0448872013-01-11 19:35:02400 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]c1dffe82013-06-26 20:59:05401 EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02402 browser()->tab_strip_model()->GetWebContentsAt(2)->
403 GetController().GetLastCommittedEntry()->GetURL().path());
404 EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
405 GetRenderProcessHost(),
406 browser()->tab_strip_model()->GetWebContentsAt(2)->
407 GetRenderProcessHost());
[email protected]faf407b2011-01-05 01:24:32408}
[email protected]d292d8a2011-05-25 03:47:11409
[email protected]aaef4752013-03-02 10:10:51410// Ensure that re-navigating to a URL after installing or uninstalling it as an
411// app correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36412//
[email protected]bc857a62013-05-08 16:44:53413// Fails on Windows. http://crbug.com/238670
[email protected]4c9d02082013-05-15 15:38:36414// Added logging to help diagnose the location of the problem.
415IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]06bdd2b2012-11-30 18:47:13416 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
417 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52418
[email protected]d292d8a2011-05-25 03:47:11419 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05420 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]d292d8a2011-05-25 03:47:11421
422 // The app under test acts on URLs whose host is "localhost",
423 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53424 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11425
426 // Load an app URL before loading the app.
[email protected]4c9d02082013-05-15 15:38:36427 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11428 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36429 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]e0448872013-01-11 19:35:02430 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46431 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52432 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11433
[email protected]aaef4752013-03-02 10:10:51434 // Load app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36435 LOG(INFO) << "Loading extension.";
[email protected]d292d8a2011-05-25 03:47:11436 const Extension* app =
437 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36438 LOG(INFO) << "Loading extension - done.";
[email protected]d292d8a2011-05-25 03:47:11439 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36440 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11441 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36442 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46443 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52444 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11445
[email protected]aaef4752013-03-02 10:10:51446 // Disable app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36447 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11448 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36449 LOG(INFO) << "Disabling extension - done.";
450 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11451 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36452 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46453 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52454 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51455}
456
457// Ensure that reloading a URL after installing or uninstalling it as an app
458// correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36459//
460// Added logging to help diagnose the location of the problem.
461// http://crbug.com/238670
[email protected]aaef4752013-03-02 10:10:51462IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
463 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
464 browser()->profile())->extension_service()->process_map();
465
466 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05467 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]aaef4752013-03-02 10:10:51468
469 // The app under test acts on URLs whose host is "localhost",
470 // so the URLs we navigate to must have host "localhost".
471 GURL base_url = GetTestBaseURL("app_process");
472
473 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36474 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51475 const Extension* app =
476 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36477 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51478 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36479 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51480 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36481 LOG(INFO) << "Disabling extension - done.";
482 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51483 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36484 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51485 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
486 EXPECT_FALSE(process_map->Contains(
487 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11488
[email protected]8d3132f62011-10-12 07:13:42489 // Enable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36490 LOG(INFO) << "Enabling extension.";
[email protected]8d3132f62011-10-12 07:13:42491 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36492 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45493 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42494 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50495 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02496 &browser()->tab_strip_model()->GetActiveWebContents()->
497 GetController()));
[email protected]4c9d02082013-05-15 15:38:36498 LOG(INFO) << "Reloading.";
[email protected]a37d4b02012-06-25 21:56:10499 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42500 reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36501 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46502 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52503 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42504
505 // Disable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36506 LOG(INFO) << "Disabling extension.";
[email protected]8d3132f62011-10-12 07:13:42507 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36508 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45509 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42510 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50511 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02512 &browser()->tab_strip_model()->GetActiveWebContents()->
513 GetController()));
[email protected]4c9d02082013-05-15 15:38:36514 LOG(INFO) << "Reloading.";
[email protected]a37d4b02012-06-25 21:56:10515 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42516 reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36517 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46518 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52519 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51520}
521
522// Ensure that reloading a URL with JavaScript after installing or uninstalling
523// it as an app correctly swaps the process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36524//
525// Crashes on Windows and Mac. http://crbug.com/238670
526// Added logging to help diagnose the location of the problem.
527IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
[email protected]aaef4752013-03-02 10:10:51528 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
529 browser()->profile())->extension_service()->process_map();
530
531 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05532 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]aaef4752013-03-02 10:10:51533
534 // The app under test acts on URLs whose host is "localhost",
535 // so the URLs we navigate to must have host "localhost".
536 GURL base_url = GetTestBaseURL("app_process");
537
538 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36539 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51540 const Extension* app =
541 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36542 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51543 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36544 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51545 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36546 LOG(INFO) << "Disabling extension - done.";
547 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51548 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36549 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51550 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
551 EXPECT_FALSE(process_map->Contains(
552 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42553
[email protected]d292d8a2011-05-25 03:47:11554 // Enable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36555 LOG(INFO) << "Enabling extension.";
[email protected]d292d8a2011-05-25 03:47:11556 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36557 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45558 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42559 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50560 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02561 &browser()->tab_strip_model()->GetActiveWebContents()->
562 GetController()));
[email protected]4c9d02082013-05-15 15:38:36563 LOG(INFO) << "Executing location.reload().";
[email protected]b6987e02013-01-04 18:30:43564 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42565 js_reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36566 LOG(INFO) << "Executing location.reload() - done.";
[email protected]6f371442011-11-09 06:45:46567 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52568 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11569
570 // Disable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36571 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11572 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36573 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45574 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42575 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50576 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02577 &browser()->tab_strip_model()->GetActiveWebContents()->
578 GetController()));
[email protected]4c9d02082013-05-15 15:38:36579 LOG(INFO) << "Executing location = location.";
[email protected]b6987e02013-01-04 18:30:43580 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42581 js_reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36582 LOG(INFO) << "Executing location = location - done.";
[email protected]6f371442011-11-09 06:45:46583 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52584 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11585}
[email protected]118d3122011-08-10 17:09:53586
[email protected]eab29432013-04-09 21:30:47587namespace {
588
589void RenderViewHostCreated(std::vector<content::RenderViewHost*>* rvh_vector,
590 content::RenderViewHost* rvh) {
591 rvh_vector->push_back(rvh);
592}
593
594} // namespace
595
[email protected]118d3122011-08-10 17:09:53596// Tests that if we have a non-app process (path3/container.html) that has an
597// iframe with a URL in the app's extent (path1/iframe.html), then opening a
598// link from that iframe to a new window to a URL in the app's extent (path1/
599// empty.html) results in the new window being in an app process. See
600// http://crbug.com/89272 for more details.
[email protected]1f4495b2012-10-12 05:51:05601IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
[email protected]06bdd2b2012-11-30 18:47:13602 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
603 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52604
[email protected]118d3122011-08-10 17:09:53605 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05606 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]118d3122011-08-10 17:09:53607
608 GURL base_url = GetTestBaseURL("app_process");
609
610 // Load app and start URL (not in the app).
611 const Extension* app =
612 LoadExtension(test_data_dir_.AppendASCII("app_process"));
613 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29614
[email protected]eab29432013-04-09 21:30:47615 std::vector<content::RenderViewHost*> rvh_vector;
616 content::RenderViewHost::CreatedCallback rvh_callback(
617 base::Bind(&RenderViewHostCreated, &rvh_vector));
618 content::RenderViewHost::AddCreatedCallback(rvh_callback);
[email protected]19da16a92012-05-23 17:11:29619 ui_test_utils::NavigateToURL(browser(),
620 base_url.Resolve("path3/container.html"));
[email protected]eab29432013-04-09 21:30:47621 content::RenderViewHost::RemoveCreatedCallback(rvh_callback);
[email protected]6f371442011-11-09 06:45:46622 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02623 browser()->tab_strip_model()->GetWebContentsAt(0)->
624 GetRenderProcessHost()->GetID()));
[email protected]118d3122011-08-10 17:09:53625
626 // Popup window should be in the app's process.
[email protected]eab29432013-04-09 21:30:47627 ASSERT_EQ(3U, rvh_vector.size());
628 RenderViewHost* popup_host = rvh_vector[2];
[email protected]19da16a92012-05-23 17:11:29629 EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
[email protected]118d3122011-08-10 17:09:53630}
[email protected]a09add52011-08-12 03:59:23631
[email protected]079b3cc2012-09-26 19:59:13632// Similar to the previous test, but ensure that popup blocking bypass
633// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05634#if defined(OS_CHROMEOS)
635// http://crbug.com/153513
636#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
637#else
638#define MAYBE_OpenAppFromIframe OpenAppFromIframe
639#endif
640IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13641 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05642 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]079b3cc2012-09-26 19:59:13643
644 // Load app and start URL (not in the app).
645 const Extension* app =
646 LoadExtension(test_data_dir_.AppendASCII("app_process"));
647 ASSERT_TRUE(app);
648
649 content::WindowedNotificationObserver blocker_observer(
650 chrome::NOTIFICATION_CONTENT_BLOCKED_STATE_CHANGED,
651 content::NotificationService::AllSources());
652 ui_test_utils::NavigateToURL(
653 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
654
655 blocker_observer.Wait();
656
[email protected]e0448872013-01-11 19:35:02657 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]079b3cc2012-09-26 19:59:13658 BlockedContentTabHelper* blocked_content_tab_helper =
659 BlockedContentTabHelper::FromWebContents(tab);
660 std::vector<WebContents*> blocked_contents;
661 blocked_content_tab_helper->GetBlockedContents(&blocked_contents);
662 EXPECT_EQ(blocked_contents.size(), 1u);
663}
664
[email protected]88aae972011-12-16 01:14:18665// Tests that if an extension launches an app via chrome.tabs.create with an URL
[email protected]b0a29f22013-05-30 23:00:09666// that's not in the app's extent but that server redirects to it, we still end
667// up with an app process. See http://crbug.com/99349 for more details.
668IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
[email protected]88aae972011-12-16 01:14:18669 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05670 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]88aae972011-12-16 01:14:18671
672 LoadExtension(test_data_dir_.AppendASCII("app_process"));
673 const Extension* launcher =
674 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
675
[email protected]6169a5772013-05-29 17:41:14676 // There should be two navigations by the time the app page is loaded.
[email protected]88aae972011-12-16 01:14:18677 // 1. The extension launcher page.
[email protected]6169a5772013-05-29 17:41:14678 // 2. The app's URL (which includes a server redirect).
679 // Note that the server redirect does not generate a navigation event.
[email protected]5b8ff1c2012-06-02 20:42:20680 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46681 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]6169a5772013-05-29 17:41:14682 2);
[email protected]cbb1ef592013-06-05 19:49:46683 test_navigation_observer.StartWatchingNewWebContents();
[email protected]88aae972011-12-16 01:14:18684
685 // Load the launcher extension, which should launch the app.
686 ui_test_utils::NavigateToURLWithDisposition(
687 browser(),
[email protected]b0a29f22013-05-30 23:00:09688 launcher->GetResourceURL("server_redirect.html"),
689 CURRENT_TAB,
690 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
691
692 // Wait for app tab to be created and loaded.
693 test_navigation_observer.WaitForObservation(
694 base::Bind(&content::RunMessageLoop),
[email protected]bffe0a52013-06-01 11:41:24695 base::Bind(&base::MessageLoop::Quit,
696 base::Unretained(base::MessageLoopForUI::current())));
[email protected]b0a29f22013-05-30 23:00:09697
698 // App has loaded, and chrome.app.isInstalled should be true.
699 bool is_installed = false;
700 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
701 browser()->tab_strip_model()->GetActiveWebContents(),
702 "window.domAutomationController.send(chrome.app.isInstalled)",
703 &is_installed));
704 ASSERT_TRUE(is_installed);
705}
706
707// Tests that if an extension launches an app via chrome.tabs.create with an URL
708// that's not in the app's extent but that client redirects to it, we still end
709// up with an app process.
710IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
711 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05712 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]b0a29f22013-05-30 23:00:09713
714 LoadExtension(test_data_dir_.AppendASCII("app_process"));
715 const Extension* launcher =
716 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
717
718 // There should be three navigations by the time the app page is loaded.
719 // 1. The extension launcher page.
720 // 2. The URL that the extension launches, which client redirects.
721 // 3. The app's URL.
722 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46723 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]b0a29f22013-05-30 23:00:09724 3);
[email protected]cbb1ef592013-06-05 19:49:46725 test_navigation_observer.StartWatchingNewWebContents();
[email protected]b0a29f22013-05-30 23:00:09726
727 // Load the launcher extension, which should launch the app.
728 ui_test_utils::NavigateToURLWithDisposition(
729 browser(),
730 launcher->GetResourceURL("client_redirect.html"),
[email protected]88aae972011-12-16 01:14:18731 CURRENT_TAB,
732 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
733
734 // Wait for app tab to be created and loaded.
735 test_navigation_observer.WaitForObservation(
[email protected]729eb632012-07-26 04:45:26736 base::Bind(&content::RunMessageLoop),
[email protected]b3a25092013-05-28 22:08:16737 base::Bind(&base::MessageLoop::Quit,
738 base::Unretained(base::MessageLoopForUI::current())));
[email protected]88aae972011-12-16 01:14:18739
740 // App has loaded, and chrome.app.isInstalled should be true.
741 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43742 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02743 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13744 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18745 &is_installed));
746 ASSERT_TRUE(is_installed);
747}
748
[email protected]d55c2382011-08-18 23:10:36749// Tests that if we have an app process (path1/container.html) with a non-app
750// iframe (path3/iframe.html), then opening a link from that iframe to a new
751// window to a same-origin non-app URL (path3/empty.html) should keep the window
752// in the app process.
753// This is in contrast to OpenAppFromIframe, since here the popup will not be
754// missing special permissions and should be scriptable from the iframe.
755// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29756IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]06bdd2b2012-11-30 18:47:13757 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
758 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52759
[email protected]d55c2382011-08-18 23:10:36760 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05761 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]d55c2382011-08-18 23:10:36762
763 GURL base_url = GetTestBaseURL("app_process");
764
765 // Load app and start URL (in the app).
766 const Extension* app =
767 LoadExtension(test_data_dir_.AppendASCII("app_process"));
768 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29769
[email protected]eab29432013-04-09 21:30:47770 std::vector<content::RenderViewHost*> rvh_vector;
771 content::RenderViewHost::CreatedCallback rvh_callback(
772 base::Bind(&RenderViewHostCreated, &rvh_vector));
773 content::RenderViewHost::AddCreatedCallback(rvh_callback);
[email protected]19da16a92012-05-23 17:11:29774 ui_test_utils::NavigateToURL(browser(),
775 base_url.Resolve("path1/container.html"));
[email protected]eab29432013-04-09 21:30:47776 content::RenderViewHost::RemoveCreatedCallback(rvh_callback);
[email protected]f3b1a082011-11-18 00:34:30777 content::RenderProcessHost* process =
[email protected]e0448872013-01-11 19:35:02778 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
[email protected]f3b1a082011-11-18 00:34:30779 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36780
[email protected]d55c2382011-08-18 23:10:36781 // Popup window should be in the app's process.
[email protected]eab29432013-04-09 21:30:47782 ASSERT_EQ(2U, rvh_vector.size());
783 RenderViewHost* popup_host = rvh_vector[1];
[email protected]19da16a92012-05-23 17:11:29784 EXPECT_EQ(process, popup_host->GetProcess());
[email protected]d55c2382011-08-18 23:10:36785}
786
[email protected]a344b762012-03-16 18:53:49787// http://crbug.com/118502
788#if defined(OS_MACOSX) || defined(OS_LINUX)
789#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
790#else
791#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
792#endif
793IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]06bdd2b2012-11-30 18:47:13794 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
795 browser()->profile())->extension_service()->process_map();
[email protected]6f371442011-11-09 06:45:46796
[email protected]a09add52011-08-12 03:59:23797 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05798 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
[email protected]a09add52011-08-12 03:59:23799
800 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
801
802 GURL base_url = GetTestBaseURL("app_process");
803
804 // Load the app, chrome.app.isInstalled should be true.
805 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02806 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46807 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52808 contents->GetRenderProcessHost()->GetID()));
[email protected]a09add52011-08-12 03:59:23809 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43810 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
811 contents,
[email protected]06bc5d92013-01-02 22:44:13812 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23813 &is_installed));
814 ASSERT_TRUE(is_installed);
815
816 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02817 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45818 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37819 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50820 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02821 &browser()->tab_strip_model()->GetActiveWebContents()->
822 GetController()));
[email protected]a37d4b02012-06-25 21:56:10823 chrome::Reload(browser(), CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37824 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43825 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
826 contents,
[email protected]06bc5d92013-01-02 22:44:13827 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23828 &is_installed));
829 ASSERT_TRUE(is_installed);
830}