blob: 6abc403f83d0bef32c4fe08657c7d1015ef5c289 [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"
avia2f4804a2015-12-24 23:11:136#include "build/build_config.h"
[email protected]fdf40f3e2013-07-11 23:55:467#include "chrome/browser/chrome_notification_types.h"
[email protected]3a8eecb2010-04-22 23:56:308#include "chrome/browser/extensions/extension_apitest.h"
[email protected]6f371442011-11-09 06:45:469#include "chrome/browser/extensions/extension_service.h"
[email protected]8ecad5e2010-12-02 21:18:3310#include "chrome/browser/profiles/profile.h"
[email protected]e0731d72013-07-25 12:39:4611#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
[email protected]7b5dc002010-11-16 23:08:1012#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1013#include "chrome/browser/ui/browser_commands.h"
[email protected]d8748142012-05-16 21:13:4314#include "chrome/browser/ui/browser_finder.h"
[email protected]71b73f02011-04-06 15:57:2915#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3616#include "chrome/browser/ui/browser_window.h"
[email protected]e0448872013-01-11 19:35:0217#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]3a8eecb2010-04-22 23:56:3018#include "chrome/common/chrome_switches.h"
[email protected]af44e7fb2011-07-29 18:32:3219#include "chrome/test/base/ui_test_utils.h"
skym71603842016-10-10 18:17:3120#include "components/sync/model/string_ordinal.h"
[email protected]ad23a092011-12-28 07:02:0421#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0722#include "content/public/browser/notification_service.h"
[email protected]c333e792012-01-06 16:57:3923#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3324#include "content/public/browser/render_view_host.h"
[email protected]2aca9a92013-12-03 05:16:0725#include "content/public/browser/site_instance.h"
[email protected]6acde6352012-01-04 16:52:2026#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4227#include "content/public/test/browser_test_utils.h"
[email protected]5b8ff1c2012-06-02 20:42:2028#include "content/public/test/test_navigation_observer.h"
[email protected]22401dc2014-03-21 01:38:5729#include "extensions/browser/extension_host.h"
[email protected]59b0e602014-01-30 00:41:2430#include "extensions/browser/extension_system.h"
[email protected]4a1d9c0d2014-06-13 12:50:1131#include "extensions/browser/install_flag.h"
[email protected]50de9aa22013-11-14 06:30:3432#include "extensions/browser/process_map.h"
[email protected]e4452d32013-11-15 23:07:4133#include "extensions/common/extension.h"
[email protected]85df9d12014-04-15 17:02:1434#include "extensions/common/file_util.h"
[email protected]558878cc82013-11-09 01:25:5135#include "extensions/common/switches.h"
[email protected]f2cb3cf2013-03-21 01:40:5336#include "net/dns/mock_host_resolver.h"
[email protected]c1dffe82013-06-26 20:59:0537#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]3a8eecb2010-04-22 23:56:3038
[email protected]c5eed492012-01-04 17:07:5039using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1140using content::RenderViewHost;
[email protected]2aca9a92013-12-03 05:16:0741using content::SiteInstance;
[email protected]4ca15302012-01-03 05:53:2042using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3443using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2044
[email protected]7b54ca02012-03-02 18:06:5345class AppApiTest : public ExtensionApiTest {
46 protected:
47 // Gets the base URL for files for a specific test, making sure that it uses
48 // "localhost" as the hostname, since that is what the extent is declared
49 // as in the test apps manifests.
[email protected]0bb29bd2014-04-30 21:39:1850 GURL GetTestBaseURL(const std::string& test_directory) {
[email protected]7b54ca02012-03-02 18:06:5351 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:1852 replace_host.SetHostStr("localhost");
[email protected]c1dffe82013-06-26 20:59:0553 GURL base_url = embedded_test_server()->GetURL(
54 "/extensions/api_test/" + test_directory + "/");
[email protected]7b54ca02012-03-02 18:06:5355 return base_url.ReplaceComponents(replace_host);
56 }
57
58 // Pass flags to make testing apps easier.
avi3ef9ec9e2014-12-22 22:50:1759 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]7b54ca02012-03-02 18:06:5360 ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:1761 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]7b54ca02012-03-02 18:06:5362 switches::kDisablePopupBlocking);
avi3ef9ec9e2014-12-22 22:50:1763 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:5164 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]7b54ca02012-03-02 18:06:5365 }
66
67 // Helper function to test that independent tabs of the named app are loaded
68 // into separate processes.
[email protected]0bb29bd2014-04-30 21:39:1869 void TestAppInstancesHelper(const std::string& app_name) {
[email protected]7b54ca02012-03-02 18:06:5370 LOG(INFO) << "Start of test.";
71
[email protected]fafdc842014-01-17 18:09:0872 extensions::ProcessMap* process_map =
73 extensions::ProcessMap::Get(browser()->profile());
[email protected]7b54ca02012-03-02 18:06:5374
75 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:5676 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]7b54ca02012-03-02 18:06:5377
78 ASSERT_TRUE(LoadExtension(
79 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2780 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5381
82 // Open two tabs in the app, one outside it.
83 GURL base_url = GetTestBaseURL(app_name);
84
85 // Test both opening a URL in a new tab, and opening a tab and then
86 // navigating it. Either way, app tabs should be considered extension
87 // processes, but they have no elevated privileges and thus should not
88 // have WebUI bindings.
89 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:1990 browser(), base_url.Resolve("path1/empty.html"),
91 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]7b54ca02012-03-02 18:06:5392 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
93 LOG(INFO) << "Nav 1.";
94 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:0295 browser()->tab_strip_model()->GetWebContentsAt(1)->
96 GetRenderProcessHost()->GetID()));
97 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:5398
[email protected]a7fe9112012-07-20 02:34:4599 content::WindowedNotificationObserver tab_added_observer(
[email protected]19506d542013-10-15 23:11:06100 chrome::NOTIFICATION_TAB_ADDED,
[email protected]7b54ca02012-03-02 18:06:53101 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10102 chrome::NewTab(browser());
[email protected]7b54ca02012-03-02 18:06:53103 tab_added_observer.Wait();
104 LOG(INFO) << "New tab.";
105 ui_test_utils::NavigateToURL(browser(),
106 base_url.Resolve("path2/empty.html"));
107 LOG(INFO) << "Nav 2.";
108 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02109 browser()->tab_strip_model()->GetWebContentsAt(2)->
110 GetRenderProcessHost()->GetID()));
111 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53112
113 // We should have opened 2 new extension tabs. Including the original blank
114 // tab, we now have 3 tabs. The two app tabs should not be in the same
115 // process, since they do not have the background permission. (Thus, we
116 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02117 ASSERT_EQ(3, browser()->tab_strip_model()->count());
118 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
119 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
[email protected]19da16a92012-05-23 17:11:29120 EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
[email protected]7b54ca02012-03-02 18:06:53121
122 // Opening tabs with window.open should keep the page in the opener's
123 // process.
scottmg34c5dd882016-02-03 05:21:54124 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
[email protected]19da16a92012-05-23 17:11:29125 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53126 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29127 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53128 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27129 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53130 }
131};
132
[email protected]079b3cc2012-09-26 19:59:13133// Omits the disable-popup-blocking flag so we can cover that case.
134class BlockedAppApiTest : public AppApiTest {
135 protected:
avi3ef9ec9e2014-12-22 22:50:17136 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]079b3cc2012-09-26 19:59:13137 ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:17138 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:51139 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]079b3cc2012-09-26 19:59:13140 }
141};
142
[email protected]7b54ca02012-03-02 18:06:53143// Tests that hosted apps with the background permission get a process-per-app
144// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56145// http://crbug.com/172750
[email protected]2340a3c2013-06-17 20:54:36146IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41147 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59148
[email protected]fafdc842014-01-17 18:09:08149 extensions::ProcessMap* process_map =
150 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52151
[email protected]3a8eecb2010-04-22 23:56:30152 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56153 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]3a8eecb2010-04-22 23:56:30154
[email protected]cbf4d1912010-08-12 18:24:57155 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30156
[email protected]87c7c292011-10-27 16:16:41157 LOG(INFO) << "Loaded extension.";
158
[email protected]cbf4d1912010-08-12 18:24:57159 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53160 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59161
[email protected]f0e13332011-05-20 22:41:14162 // Test both opening a URL in a new tab, and opening a tab and then navigating
163 // it. Either way, app tabs should be considered extension processes, but
164 // they have no elevated privileges and thus should not have WebUI bindings.
165 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19166 browser(), base_url.Resolve("path1/empty.html"),
167 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]f0e13332011-05-20 22:41:14168 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46169 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02170 browser()->tab_strip_model()->GetWebContentsAt(1)->
171 GetRenderProcessHost()->GetID()));
172 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41173 LOG(INFO) << "Nav 1.";
174
175 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19176 browser(), base_url.Resolve("path2/empty.html"),
177 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]87c7c292011-10-27 16:16:41178 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46179 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02180 browser()->tab_strip_model()->GetWebContentsAt(2)->
181 GetRenderProcessHost()->GetID()));
182 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41183 LOG(INFO) << "Nav 2.";
184
[email protected]a7fe9112012-07-20 02:34:45185 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42186 chrome::NOTIFICATION_TAB_ADDED,
[email protected]87c7c292011-10-27 16:16:41187 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10188 chrome::NewTab(browser());
[email protected]87c7c292011-10-27 16:16:41189 tab_added_observer.Wait();
190 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57191 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41192 LOG(INFO) << "Nav 3.";
[email protected]6f371442011-11-09 06:45:46193 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02194 browser()->tab_strip_model()->GetWebContentsAt(3)->
195 GetRenderProcessHost()->GetID()));
196 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30197
[email protected]056ad2a2011-07-12 02:13:55198 // We should have opened 3 new extension tabs. Including the original blank
199 // tab, we now have 4 tabs. Because the app_process app has the background
200 // permission, all of its instances are in the same process. Thus two tabs
201 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02202 ASSERT_EQ(4, browser()->tab_strip_model()->count());
203 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57204
[email protected]19da16a92012-05-23 17:11:29205 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02206 browser()->tab_strip_model()->GetWebContentsAt(2)->
207 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29208 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02209 browser()->tab_strip_model()->GetWebContentsAt(3)->
210 GetRenderProcessHost());
[email protected]3a8eecb2010-04-22 23:56:30211
212 // Now let's do the same using window.open. The same should happen.
scottmg34c5dd882016-02-03 05:21:54213 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
[email protected]19da16a92012-05-23 17:11:29214 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41215 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29216 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41217 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15218 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17219 // argument), but we temporarily avoid swapping processes away from a hosted
220 // app if it has an opener, because some OAuth providers make script calls
221 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15222 // See crbug.com/59285.
[email protected]19da16a92012-05-23 17:11:29223 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41224 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30225
226 // Now let's have these pages navigate, into or out of the extension web
227 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36228 const GURL& app_url(base_url.Resolve("path1/empty.html"));
229 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02230 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
231 non_app_url);
[email protected]87c7c292011-10-27 16:16:41232 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02233 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
234 app_url);
[email protected]87c7c292011-10-27 16:16:41235 LOG(INFO) << "NavigateTabHelper 2.";
[email protected]ea7b7d82012-05-25 17:29:17236 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02237 browser()->tab_strip_model()->GetWebContentsAt(2)->
238 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29239 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02240 browser()->tab_strip_model()->GetWebContentsAt(3)->
241 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04242
243 // If one of the popup tabs navigates back to the app, window.opener should
244 // be valid.
[email protected]e0448872013-01-11 19:35:02245 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
246 app_url);
[email protected]87c7c292011-10-27 16:16:41247 LOG(INFO) << "NavigateTabHelper 3.";
[email protected]19da16a92012-05-23 17:11:29248 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02249 browser()->tab_strip_model()->GetWebContentsAt(6)->
250 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04251 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43252 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02253 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13254 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04255 &windowOpenerValid));
256 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41257
258 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30259}
[email protected]faf407b2011-01-05 01:24:32260
[email protected]056ad2a2011-07-12 02:13:55261// Test that hosted apps without the background permission use a process per app
262// instance model, such that separate instances are in separate processes.
[email protected]4ef849e2013-06-10 08:36:59263// Flaky on Windows. http://crbug.com/248047
264#if defined(OS_WIN)
265#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
266#else
267#define MAYBE_AppProcessInstances AppProcessInstances
268#endif
269IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53270 TestAppInstancesHelper("app_process_instances");
271}
[email protected]87c7c292011-10-27 16:16:41272
[email protected]7b54ca02012-03-02 18:06:53273// Test that hosted apps with the background permission but that set
274// allow_js_access to false also use a process per app instance model.
275// Separate instances should be in separate processes.
[email protected]0d70b7d42012-12-13 01:14:20276// Flaky on XP: http://crbug.com/165834
[email protected]0cfb748b2012-12-13 01:10:11277#if defined(OS_WIN)
278#define MAYBE_AppProcessBackgroundInstances \
279 DISABLED_AppProcessBackgroundInstances
280#else
281#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
282#endif
283IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53284 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55285}
286
[email protected]15877ca2011-11-18 22:40:52287// Tests that bookmark apps do not use the app process model and are treated
288// like normal web pages instead. http://crbug.com/104636.
[email protected]19506d542013-10-15 23:11:06289// Timing out on Windows. http://crbug.com/238777
290#if defined(OS_WIN)
291#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
292#else
293#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
294#endif
295IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
[email protected]06bdd2b2012-11-30 18:47:13296 ExtensionService* service = extensions::ExtensionSystem::Get(
297 browser()->profile())->extension_service();
[email protected]fafdc842014-01-17 18:09:08298 extensions::ProcessMap* process_map =
299 extensions::ProcessMap::Get(browser()->profile());
[email protected]15877ca2011-11-18 22:40:52300
301 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56302 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]15877ca2011-11-18 22:40:52303 GURL base_url = GetTestBaseURL("app_process");
304
[email protected]c2f36e3a2011-12-14 01:27:19305 // Load an app as a bookmark app.
306 std::string error;
[email protected]85df9d12014-04-15 17:02:14307 scoped_refptr<const Extension> extension(extensions::file_util::LoadExtension(
[email protected]c2f36e3a2011-12-14 01:27:19308 test_data_dir_.AppendASCII("app_process"),
[email protected]12075d12013-02-27 05:38:05309 extensions::Manifest::UNPACKED,
[email protected]c2f36e3a2011-12-14 01:27:19310 Extension::FROM_BOOKMARK,
311 &error));
[email protected]dc24976f2013-06-02 21:15:09312 service->OnExtensionInstalled(extension.get(),
[email protected]98270432012-09-11 20:51:24313 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]4a1d9c0d2014-06-13 12:50:11314 extensions::kInstallFlagInstallImmediately);
[email protected]c2f36e3a2011-12-14 01:27:19315 ASSERT_TRUE(extension.get());
316 ASSERT_TRUE(extension->from_bookmark());
317
[email protected]15877ca2011-11-18 22:40:52318 // Test both opening a URL in a new tab, and opening a tab and then navigating
319 // it. Either way, bookmark app tabs should be considered normal processes
320 // with no elevated privileges and no WebUI bindings.
321 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19322 browser(), base_url.Resolve("path1/empty.html"),
323 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]15877ca2011-11-18 22:40:52324 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
325 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02326 browser()->tab_strip_model()->GetWebContentsAt(1)->
327 GetRenderProcessHost()->GetID()));
328 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52329
[email protected]a7fe9112012-07-20 02:34:45330 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42331 chrome::NOTIFICATION_TAB_ADDED,
[email protected]15877ca2011-11-18 22:40:52332 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10333 chrome::NewTab(browser());
[email protected]15877ca2011-11-18 22:40:52334 tab_added_observer.Wait();
335 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
336 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02337 browser()->tab_strip_model()->GetWebContentsAt(2)->
338 GetRenderProcessHost()->GetID()));
339 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52340
341 // We should have opened 2 new bookmark app tabs. Including the original blank
342 // tab, we now have 3 tabs. Because normal pages use the
343 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02344 ASSERT_EQ(3, browser()->tab_strip_model()->count());
345 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]19da16a92012-05-23 17:11:29346 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02347 browser()->tab_strip_model()->GetWebContentsAt(2)->
348 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52349
350 // Now let's do the same using window.open. The same should happen.
scottmg34c5dd882016-02-03 05:21:54351 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
[email protected]19da16a92012-05-23 17:11:29352 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
353 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]15877ca2011-11-18 22:40:52354
355 // Now let's have a tab navigate out of and back into the app's web
356 // extent. Neither navigation should switch processes.
357 const GURL& app_url(base_url.Resolve("path1/empty.html"));
358 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03359 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02360 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
361 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
362 non_app_url);
[email protected]9f76c1e2012-03-05 15:15:58363 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02364 browser()->tab_strip_model()->GetWebContentsAt(2)->
365 GetRenderProcessHost());
366 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
367 app_url);
[email protected]9f76c1e2012-03-05 15:15:58368 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02369 browser()->tab_strip_model()->GetWebContentsAt(2)->
370 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52371}
372
[email protected]faf407b2011-01-05 01:24:32373// Tests that app process switching works properly in the following scenario:
374// 1. navigate to a page1 in the app
375// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
376// 3. page2 redirects back to a page in the app
377// The final navigation should end up in the app process.
378// See http://crbug.com/61757
John Abd-El-Malek3f7aec312014-08-27 03:18:10379// Flaky. http://crbug.com/341898
380IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32381 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56382 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]faf407b2011-01-05 01:24:32383
384 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
385
386 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53387 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32388
[email protected]a37d4b02012-06-25 21:56:10389 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32390 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10391 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17392 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48393 // 1. We navigate to redirect.html
394 // 2. Renderer navigates and finishes, counting as a load stop.
395 // 3. Renderer issues the meta refresh to navigate to server-redirect.
396 // 4. Renderer is now in a "provisional load", waiting for navigation to
397 // complete.
398 // 5. Browser sees a redirect response from server-redirect to empty.html, and
399 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17400 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
401 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48402 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17403 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32404
405 // 3 tabs, including the initial about:blank. The last 2 should be the same
406 // process.
[email protected]e0448872013-01-11 19:35:02407 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]c1dffe82013-06-26 20:59:05408 EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02409 browser()->tab_strip_model()->GetWebContentsAt(2)->
410 GetController().GetLastCommittedEntry()->GetURL().path());
411 EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
412 GetRenderProcessHost(),
413 browser()->tab_strip_model()->GetWebContentsAt(2)->
414 GetRenderProcessHost());
[email protected]faf407b2011-01-05 01:24:32415}
[email protected]d292d8a2011-05-25 03:47:11416
[email protected]aaef4752013-03-02 10:10:51417// Ensure that re-navigating to a URL after installing or uninstalling it as an
418// app correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36419//
[email protected]bc857a62013-05-08 16:44:53420// Fails on Windows. http://crbug.com/238670
[email protected]4c9d02082013-05-15 15:38:36421// Added logging to help diagnose the location of the problem.
[email protected]11170a772013-12-13 11:38:32422IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08423 extensions::ProcessMap* process_map =
424 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52425
[email protected]d292d8a2011-05-25 03:47:11426 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56427 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]d292d8a2011-05-25 03:47:11428
429 // The app under test acts on URLs whose host is "localhost",
430 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53431 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11432
433 // Load an app URL before loading the app.
[email protected]4c9d02082013-05-15 15:38:36434 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11435 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36436 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]e0448872013-01-11 19:35:02437 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46438 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52439 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11440
[email protected]aaef4752013-03-02 10:10:51441 // Load app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36442 LOG(INFO) << "Loading extension.";
[email protected]d292d8a2011-05-25 03:47:11443 const Extension* app =
444 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36445 LOG(INFO) << "Loading extension - done.";
[email protected]d292d8a2011-05-25 03:47:11446 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36447 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11448 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36449 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46450 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52451 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11452
[email protected]aaef4752013-03-02 10:10:51453 // Disable app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36454 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11455 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36456 LOG(INFO) << "Disabling extension - done.";
457 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11458 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36459 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]6f371442011-11-09 06:45:46460 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52461 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51462}
463
464// Ensure that reloading a URL after installing or uninstalling it as an app
465// correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36466//
467// Added logging to help diagnose the location of the problem.
468// http://crbug.com/238670
[email protected]aaef4752013-03-02 10:10:51469IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08470 extensions::ProcessMap* process_map =
471 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51472
473 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56474 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]aaef4752013-03-02 10:10:51475
476 // The app under test acts on URLs whose host is "localhost",
477 // so the URLs we navigate to must have host "localhost".
478 GURL base_url = GetTestBaseURL("app_process");
479
480 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36481 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51482 const Extension* app =
483 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36484 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51485 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36486 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51487 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36488 LOG(INFO) << "Disabling extension - done.";
489 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51490 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36491 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51492 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
493 EXPECT_FALSE(process_map->Contains(
494 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11495
[email protected]8d3132f62011-10-12 07:13:42496 // Enable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36497 LOG(INFO) << "Enabling extension.";
[email protected]8d3132f62011-10-12 07:13:42498 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36499 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45500 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42501 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50502 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02503 &browser()->tab_strip_model()->GetActiveWebContents()->
504 GetController()));
[email protected]4c9d02082013-05-15 15:38:36505 LOG(INFO) << "Reloading.";
nick3b04f322016-08-31 19:29:19506 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42507 reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36508 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46509 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52510 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42511
512 // Disable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36513 LOG(INFO) << "Disabling extension.";
[email protected]8d3132f62011-10-12 07:13:42514 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36515 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45516 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42517 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50518 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02519 &browser()->tab_strip_model()->GetActiveWebContents()->
520 GetController()));
[email protected]4c9d02082013-05-15 15:38:36521 LOG(INFO) << "Reloading.";
nick3b04f322016-08-31 19:29:19522 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42523 reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36524 LOG(INFO) << "Reloading - done.";
[email protected]6f371442011-11-09 06:45:46525 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52526 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51527}
528
529// Ensure that reloading a URL with JavaScript after installing or uninstalling
530// it as an app correctly swaps the process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36531//
532// Crashes on Windows and Mac. http://crbug.com/238670
533// Added logging to help diagnose the location of the problem.
534IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
[email protected]fafdc842014-01-17 18:09:08535 extensions::ProcessMap* process_map =
536 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51537
538 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56539 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]aaef4752013-03-02 10:10:51540
541 // The app under test acts on URLs whose host is "localhost",
542 // so the URLs we navigate to must have host "localhost".
543 GURL base_url = GetTestBaseURL("app_process");
544
545 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36546 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51547 const Extension* app =
548 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36549 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51550 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36551 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51552 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36553 LOG(INFO) << "Disabling extension - done.";
554 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51555 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36556 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51557 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
558 EXPECT_FALSE(process_map->Contains(
559 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42560
[email protected]d292d8a2011-05-25 03:47:11561 // Enable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36562 LOG(INFO) << "Enabling extension.";
[email protected]d292d8a2011-05-25 03:47:11563 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36564 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45565 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42566 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50567 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02568 &browser()->tab_strip_model()->GetActiveWebContents()->
569 GetController()));
[email protected]4c9d02082013-05-15 15:38:36570 LOG(INFO) << "Executing location.reload().";
[email protected]b6987e02013-01-04 18:30:43571 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42572 js_reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36573 LOG(INFO) << "Executing location.reload() - done.";
[email protected]6f371442011-11-09 06:45:46574 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52575 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11576
577 // Disable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36578 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11579 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36580 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45581 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42582 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50583 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02584 &browser()->tab_strip_model()->GetActiveWebContents()->
585 GetController()));
[email protected]4c9d02082013-05-15 15:38:36586 LOG(INFO) << "Executing location = location.";
[email protected]b6987e02013-01-04 18:30:43587 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42588 js_reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36589 LOG(INFO) << "Executing location = location - done.";
[email protected]6f371442011-11-09 06:45:46590 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52591 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11592}
[email protected]118d3122011-08-10 17:09:53593
[email protected]118d3122011-08-10 17:09:53594// Tests that if we have a non-app process (path3/container.html) that has an
595// iframe with a URL in the app's extent (path1/iframe.html), then opening a
596// link from that iframe to a new window to a URL in the app's extent (path1/
597// empty.html) results in the new window being in an app process. See
598// http://crbug.com/89272 for more details.
[email protected]1f4495b2012-10-12 05:51:05599IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
[email protected]fafdc842014-01-17 18:09:08600 extensions::ProcessMap* process_map =
601 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52602
[email protected]118d3122011-08-10 17:09:53603 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56604 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]118d3122011-08-10 17:09:53605
606 GURL base_url = GetTestBaseURL("app_process");
607
608 // Load app and start URL (not in the app).
609 const Extension* app =
610 LoadExtension(test_data_dir_.AppendASCII("app_process"));
611 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29612
[email protected]19da16a92012-05-23 17:11:29613 ui_test_utils::NavigateToURL(browser(),
614 base_url.Resolve("path3/container.html"));
[email protected]6f371442011-11-09 06:45:46615 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02616 browser()->tab_strip_model()->GetWebContentsAt(0)->
617 GetRenderProcessHost()->GetID()));
[email protected]118d3122011-08-10 17:09:53618
scottmg0d8e4ab2016-01-28 00:34:55619 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]415dc61612013-10-29 04:35:27620 EXPECT_EQ(2U, active_browser_list->size());
621 content::WebContents* popup_contents =
622 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
623 content::WaitForLoadStop(popup_contents);
624
[email protected]118d3122011-08-10 17:09:53625 // Popup window should be in the app's process.
[email protected]415dc61612013-10-29 04:35:27626 RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
[email protected]19da16a92012-05-23 17:11:29627 EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
[email protected]118d3122011-08-10 17:09:53628}
[email protected]a09add52011-08-12 03:59:23629
[email protected]079b3cc2012-09-26 19:59:13630// Similar to the previous test, but ensure that popup blocking bypass
631// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05632#if defined(OS_CHROMEOS)
633// http://crbug.com/153513
634#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
635#else
636#define MAYBE_OpenAppFromIframe OpenAppFromIframe
637#endif
638IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13639 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56640 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]079b3cc2012-09-26 19:59:13641
642 // Load app and start URL (not in the app).
643 const Extension* app =
644 LoadExtension(test_data_dir_.AppendASCII("app_process"));
645 ASSERT_TRUE(app);
646
[email protected]079b3cc2012-09-26 19:59:13647 ui_test_utils::NavigateToURL(
648 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
649
[email protected]e0448872013-01-11 19:35:02650 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]e0731d72013-07-25 12:39:46651 PopupBlockerTabHelper* popup_blocker_tab_helper =
652 PopupBlockerTabHelper::FromWebContents(tab);
[email protected]992e2912013-08-19 15:05:24653 if (!popup_blocker_tab_helper->GetBlockedPopupsCount()) {
[email protected]e0731d72013-07-25 12:39:46654 content::WindowedNotificationObserver observer(
655 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
656 content::NotificationService::AllSources());
657 observer.Wait();
658 }
659
[email protected]992e2912013-08-19 15:05:24660 EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
[email protected]079b3cc2012-09-26 19:59:13661}
662
[email protected]88aae972011-12-16 01:14:18663// Tests that if an extension launches an app via chrome.tabs.create with an URL
[email protected]b0a29f22013-05-30 23:00:09664// that's not in the app's extent but that server redirects to it, we still end
665// up with an app process. See http://crbug.com/99349 for more details.
666IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
[email protected]88aae972011-12-16 01:14:18667 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05668 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]88aae972011-12-16 01:14:18669
670 LoadExtension(test_data_dir_.AppendASCII("app_process"));
671 const Extension* launcher =
672 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
673
[email protected]6169a5772013-05-29 17:41:14674 // There should be two navigations by the time the app page is loaded.
[email protected]88aae972011-12-16 01:14:18675 // 1. The extension launcher page.
[email protected]6169a5772013-05-29 17:41:14676 // 2. The app's URL (which includes a server redirect).
677 // Note that the server redirect does not generate a navigation event.
[email protected]5b8ff1c2012-06-02 20:42:20678 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46679 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]6169a5772013-05-29 17:41:14680 2);
[email protected]cbb1ef592013-06-05 19:49:46681 test_navigation_observer.StartWatchingNewWebContents();
[email protected]88aae972011-12-16 01:14:18682
683 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18684 ui_test_utils::NavigateToURL(
685 browser(), launcher->GetResourceURL("server_redirect.html"));
[email protected]b0a29f22013-05-30 23:00:09686
687 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59688 test_navigation_observer.Wait();
[email protected]b0a29f22013-05-30 23:00:09689
690 // App has loaded, and chrome.app.isInstalled should be true.
691 bool is_installed = false;
692 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
693 browser()->tab_strip_model()->GetActiveWebContents(),
694 "window.domAutomationController.send(chrome.app.isInstalled)",
695 &is_installed));
696 ASSERT_TRUE(is_installed);
697}
698
699// Tests that if an extension launches an app via chrome.tabs.create with an URL
700// that's not in the app's extent but that client redirects to it, we still end
701// up with an app process.
702IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
703 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]c1dffe82013-06-26 20:59:05704 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]b0a29f22013-05-30 23:00:09705
706 LoadExtension(test_data_dir_.AppendASCII("app_process"));
707 const Extension* launcher =
708 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
709
710 // There should be three navigations by the time the app page is loaded.
711 // 1. The extension launcher page.
712 // 2. The URL that the extension launches, which client redirects.
713 // 3. The app's URL.
714 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46715 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]b0a29f22013-05-30 23:00:09716 3);
[email protected]cbb1ef592013-06-05 19:49:46717 test_navigation_observer.StartWatchingNewWebContents();
[email protected]b0a29f22013-05-30 23:00:09718
719 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18720 ui_test_utils::NavigateToURL(
721 browser(), launcher->GetResourceURL("client_redirect.html"));
[email protected]88aae972011-12-16 01:14:18722
723 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59724 test_navigation_observer.Wait();
[email protected]88aae972011-12-16 01:14:18725
726 // App has loaded, and chrome.app.isInstalled should be true.
727 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43728 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02729 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13730 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18731 &is_installed));
732 ASSERT_TRUE(is_installed);
733}
734
[email protected]d55c2382011-08-18 23:10:36735// Tests that if we have an app process (path1/container.html) with a non-app
736// iframe (path3/iframe.html), then opening a link from that iframe to a new
737// window to a same-origin non-app URL (path3/empty.html) should keep the window
738// in the app process.
739// This is in contrast to OpenAppFromIframe, since here the popup will not be
740// missing special permissions and should be scriptable from the iframe.
741// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29742IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]fafdc842014-01-17 18:09:08743 extensions::ProcessMap* process_map =
744 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52745
[email protected]d55c2382011-08-18 23:10:36746 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56747 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]d55c2382011-08-18 23:10:36748
749 GURL base_url = GetTestBaseURL("app_process");
750
751 // Load app and start URL (in the app).
752 const Extension* app =
753 LoadExtension(test_data_dir_.AppendASCII("app_process"));
754 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29755
[email protected]19da16a92012-05-23 17:11:29756 ui_test_utils::NavigateToURL(browser(),
757 base_url.Resolve("path1/container.html"));
[email protected]f3b1a082011-11-18 00:34:30758 content::RenderProcessHost* process =
[email protected]e0448872013-01-11 19:35:02759 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
[email protected]f3b1a082011-11-18 00:34:30760 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36761
rdevlin.cronine29bde72015-07-17 15:11:35762 // Popup window should be in the app's process if site isolation is off;
763 // otherwise they should be in different processes.
scottmg0d8e4ab2016-01-28 00:34:55764 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]415dc61612013-10-29 04:35:27765 EXPECT_EQ(2U, active_browser_list->size());
766 content::WebContents* popup_contents =
767 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
768 content::WaitForLoadStop(popup_contents);
769
nickd30fd962015-07-27 21:51:08770 bool should_be_in_same_process = !content::AreAllSitesIsolatedForTesting();
rdevlin.cronine29bde72015-07-17 15:11:35771 content::RenderProcessHost* popup_process =
772 popup_contents->GetRenderProcessHost();
773 EXPECT_EQ(should_be_in_same_process, process == popup_process);
774 EXPECT_EQ(should_be_in_same_process,
775 process_map->Contains(popup_process->GetID()));
[email protected]d55c2382011-08-18 23:10:36776}
777
[email protected]a344b762012-03-16 18:53:49778// http://crbug.com/118502
779#if defined(OS_MACOSX) || defined(OS_LINUX)
780#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
781#else
782#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
783#endif
784IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]fafdc842014-01-17 18:09:08785 extensions::ProcessMap* process_map =
786 extensions::ProcessMap::Get(browser()->profile());
[email protected]6f371442011-11-09 06:45:46787
[email protected]a09add52011-08-12 03:59:23788 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56789 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]a09add52011-08-12 03:59:23790
791 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
792
793 GURL base_url = GetTestBaseURL("app_process");
794
795 // Load the app, chrome.app.isInstalled should be true.
796 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02797 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46798 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52799 contents->GetRenderProcessHost()->GetID()));
[email protected]a09add52011-08-12 03:59:23800 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43801 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
802 contents,
[email protected]06bc5d92013-01-02 22:44:13803 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23804 &is_installed));
805 ASSERT_TRUE(is_installed);
806
807 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02808 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45809 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37810 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50811 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02812 &browser()->tab_strip_model()->GetActiveWebContents()->
813 GetController()));
nick3b04f322016-08-31 19:29:19814 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37815 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43816 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
817 contents,
[email protected]06bc5d92013-01-02 22:44:13818 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23819 &is_installed));
820 ASSERT_TRUE(is_installed);
821}
[email protected]2aca9a92013-12-03 05:16:07822
823// Test that a cross-process navigation away from a hosted app stays in the same
824// BrowsingInstance, so that postMessage calls to the app's other windows still
825// work.
826IN_PROC_BROWSER_TEST_F(AppApiTest, SameBrowsingInstanceAfterSwap) {
[email protected]fafdc842014-01-17 18:09:08827 extensions::ProcessMap* process_map =
828 extensions::ProcessMap::Get(browser()->profile());
[email protected]2aca9a92013-12-03 05:16:07829
830 host_resolver()->AddRule("*", "127.0.0.1");
svaldeza01f7d92015-11-18 17:47:56831 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]2aca9a92013-12-03 05:16:07832
833 GURL base_url = GetTestBaseURL("app_process");
834
835 // Load app and start URL (in the app).
836 const Extension* app =
837 LoadExtension(test_data_dir_.AppendASCII("app_process"));
838 ASSERT_TRUE(app);
839
840 ui_test_utils::NavigateToURL(browser(),
841 base_url.Resolve("path1/iframe.html"));
842 content::SiteInstance* app_instance =
843 browser()->tab_strip_model()->GetWebContentsAt(0)->GetSiteInstance();
844 EXPECT_TRUE(process_map->Contains(app_instance->GetProcess()->GetID()));
845
846 // Popup window should be in the app's process.
scottmg0d8e4ab2016-01-28 00:34:55847 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]2aca9a92013-12-03 05:16:07848 EXPECT_EQ(2U, active_browser_list->size());
849 content::WebContents* popup_contents =
850 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
851 content::WaitForLoadStop(popup_contents);
852
853 SiteInstance* popup_instance = popup_contents->GetSiteInstance();
854 EXPECT_EQ(app_instance, popup_instance);
855
856 // Navigate the popup to another process outside the app.
857 GURL non_app_url(base_url.Resolve("path3/empty.html"));
858 ui_test_utils::NavigateToURL(active_browser_list->get(1), non_app_url);
859 SiteInstance* new_instance = popup_contents->GetSiteInstance();
860 EXPECT_NE(app_instance, new_instance);
861
862 // It should still be in the same BrowsingInstance, allowing postMessage to
863 // work.
864 EXPECT_TRUE(app_instance->IsRelatedSiteInstance(new_instance));
865}