blob: 6579e8e2f44ba145d0f11ff3e91ac9f8d4daf021 [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"
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:3723#include "content/public/browser/render_frame_host.h"
[email protected]c333e792012-01-06 16:57:3924#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3325#include "content/public/browser/render_view_host.h"
[email protected]2aca9a92013-12-03 05:16:0726#include "content/public/browser/site_instance.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]22401dc2014-03-21 01:38:5730#include "extensions/browser/extension_host.h"
[email protected]59b0e602014-01-30 00:41:2431#include "extensions/browser/extension_system.h"
[email protected]4a1d9c0d2014-06-13 12:50:1132#include "extensions/browser/install_flag.h"
[email protected]50de9aa22013-11-14 06:30:3433#include "extensions/browser/process_map.h"
[email protected]e4452d32013-11-15 23:07:4134#include "extensions/common/extension.h"
[email protected]85df9d12014-04-15 17:02:1435#include "extensions/common/file_util.h"
[email protected]558878cc82013-11-09 01:25:5136#include "extensions/common/switches.h"
[email protected]f2cb3cf2013-03-21 01:40:5337#include "net/dns/mock_host_resolver.h"
[email protected]c1dffe82013-06-26 20:59:0538#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]3a8eecb2010-04-22 23:56:3039
[email protected]c5eed492012-01-04 17:07:5040using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1141using content::RenderViewHost;
[email protected]2aca9a92013-12-03 05:16:0742using content::SiteInstance;
[email protected]4ca15302012-01-03 05:53:2043using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3444using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2045
Devlin Croninef3e37e2018-05-14 23:47:2446class AppApiTest : public extensions::ExtensionApiTest {
[email protected]7b54ca02012-03-02 18:06:5347 protected:
48 // Gets the base URL for files for a specific test, making sure that it uses
49 // "localhost" as the hostname, since that is what the extent is declared
50 // as in the test apps manifests.
[email protected]0bb29bd2014-04-30 21:39:1851 GURL GetTestBaseURL(const std::string& test_directory) {
[email protected]7b54ca02012-03-02 18:06:5352 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:1853 replace_host.SetHostStr("localhost");
[email protected]c1dffe82013-06-26 20:59:0554 GURL base_url = embedded_test_server()->GetURL(
55 "/extensions/api_test/" + test_directory + "/");
[email protected]7b54ca02012-03-02 18:06:5356 return base_url.ReplaceComponents(replace_host);
57 }
58
59 // Pass flags to make testing apps easier.
avi3ef9ec9e2014-12-22 22:50:1760 void SetUpCommandLine(base::CommandLine* command_line) override {
Devlin Croninef3e37e2018-05-14 23:47:2461 extensions::ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:1762 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]7b54ca02012-03-02 18:06:5363 switches::kDisablePopupBlocking);
avi3ef9ec9e2014-12-22 22:50:1764 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:5165 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]7b54ca02012-03-02 18:06:5366 }
67
jambb11ed742017-05-01 17:27:5968 void SetUpOnMainThread() override {
Devlin Croninef3e37e2018-05-14 23:47:2469 extensions::ExtensionApiTest::SetUpOnMainThread();
jambb11ed742017-05-01 17:27:5970 host_resolver()->AddRule("*", "127.0.0.1");
71 ASSERT_TRUE(StartEmbeddedTestServer());
72 }
73
[email protected]7b54ca02012-03-02 18:06:5374 // Helper function to test that independent tabs of the named app are loaded
75 // into separate processes.
[email protected]0bb29bd2014-04-30 21:39:1876 void TestAppInstancesHelper(const std::string& app_name) {
[email protected]7b54ca02012-03-02 18:06:5377 LOG(INFO) << "Start of test.";
78
[email protected]fafdc842014-01-17 18:09:0879 extensions::ProcessMap* process_map =
80 extensions::ProcessMap::Get(browser()->profile());
[email protected]7b54ca02012-03-02 18:06:5381
[email protected]7b54ca02012-03-02 18:06:5382 ASSERT_TRUE(LoadExtension(
83 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2784 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5385
86 // Open two tabs in the app, one outside it.
87 GURL base_url = GetTestBaseURL(app_name);
88
89 // Test both opening a URL in a new tab, and opening a tab and then
90 // navigating it. Either way, app tabs should be considered extension
91 // processes, but they have no elevated privileges and thus should not
92 // have WebUI bindings.
93 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:1994 browser(), base_url.Resolve("path1/empty.html"),
95 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]7b54ca02012-03-02 18:06:5396 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
97 LOG(INFO) << "Nav 1.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:3798 EXPECT_TRUE(process_map->Contains(browser()
99 ->tab_strip_model()
100 ->GetWebContentsAt(1)
101 ->GetMainFrame()
102 ->GetProcess()
103 ->GetID()));
[email protected]e0448872013-01-11 19:35:02104 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53105
[email protected]a7fe9112012-07-20 02:34:45106 content::WindowedNotificationObserver tab_added_observer(
[email protected]19506d542013-10-15 23:11:06107 chrome::NOTIFICATION_TAB_ADDED,
[email protected]7b54ca02012-03-02 18:06:53108 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10109 chrome::NewTab(browser());
[email protected]7b54ca02012-03-02 18:06:53110 tab_added_observer.Wait();
111 LOG(INFO) << "New tab.";
112 ui_test_utils::NavigateToURL(browser(),
113 base_url.Resolve("path2/empty.html"));
114 LOG(INFO) << "Nav 2.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37115 EXPECT_TRUE(process_map->Contains(browser()
116 ->tab_strip_model()
117 ->GetWebContentsAt(2)
118 ->GetMainFrame()
119 ->GetProcess()
120 ->GetID()));
[email protected]e0448872013-01-11 19:35:02121 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53122
123 // We should have opened 2 new extension tabs. Including the original blank
124 // tab, we now have 3 tabs. The two app tabs should not be in the same
125 // process, since they do not have the background permission. (Thus, we
126 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02127 ASSERT_EQ(3, browser()->tab_strip_model()->count());
128 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
129 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37130 EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
131 tab2->GetMainFrame()->GetProcess());
[email protected]7b54ca02012-03-02 18:06:53132
133 // Opening tabs with window.open should keep the page in the opener's
134 // process.
scottmg34c5dd882016-02-03 05:21:54135 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
Devlin Croninf1afce252017-08-19 01:21:48136 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, true, NULL);
[email protected]7b54ca02012-03-02 18:06:53137 LOG(INFO) << "WindowOpenHelper 1.";
Devlin Croninf1afce252017-08-19 01:21:48138 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, true, NULL);
[email protected]7b54ca02012-03-02 18:06:53139 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27140 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53141 }
142};
143
[email protected]079b3cc2012-09-26 19:59:13144// Omits the disable-popup-blocking flag so we can cover that case.
145class BlockedAppApiTest : public AppApiTest {
146 protected:
avi3ef9ec9e2014-12-22 22:50:17147 void SetUpCommandLine(base::CommandLine* command_line) override {
Devlin Croninef3e37e2018-05-14 23:47:24148 extensions::ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:17149 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:51150 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]079b3cc2012-09-26 19:59:13151 }
152};
153
[email protected]7b54ca02012-03-02 18:06:53154// Tests that hosted apps with the background permission get a process-per-app
155// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56156// http://crbug.com/172750
[email protected]2340a3c2013-06-17 20:54:36157IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41158 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59159
[email protected]fafdc842014-01-17 18:09:08160 extensions::ProcessMap* process_map =
161 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52162
[email protected]cbf4d1912010-08-12 18:24:57163 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30164
[email protected]87c7c292011-10-27 16:16:41165 LOG(INFO) << "Loaded extension.";
166
[email protected]cbf4d1912010-08-12 18:24:57167 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53168 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59169
[email protected]f0e13332011-05-20 22:41:14170 // Test both opening a URL in a new tab, and opening a tab and then navigating
171 // it. Either way, app tabs should be considered extension processes, but
172 // they have no elevated privileges and thus should not have WebUI bindings.
173 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19174 browser(), base_url.Resolve("path1/empty.html"),
175 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]f0e13332011-05-20 22:41:14176 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37177 EXPECT_TRUE(process_map->Contains(browser()
178 ->tab_strip_model()
179 ->GetWebContentsAt(1)
180 ->GetMainFrame()
181 ->GetProcess()
182 ->GetID()));
[email protected]e0448872013-01-11 19:35:02183 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41184 LOG(INFO) << "Nav 1.";
185
186 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19187 browser(), base_url.Resolve("path2/empty.html"),
188 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]87c7c292011-10-27 16:16:41189 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37190 EXPECT_TRUE(process_map->Contains(browser()
191 ->tab_strip_model()
192 ->GetWebContentsAt(2)
193 ->GetMainFrame()
194 ->GetProcess()
195 ->GetID()));
[email protected]e0448872013-01-11 19:35:02196 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41197 LOG(INFO) << "Nav 2.";
198
[email protected]a7fe9112012-07-20 02:34:45199 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42200 chrome::NOTIFICATION_TAB_ADDED,
[email protected]87c7c292011-10-27 16:16:41201 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10202 chrome::NewTab(browser());
[email protected]87c7c292011-10-27 16:16:41203 tab_added_observer.Wait();
204 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57205 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41206 LOG(INFO) << "Nav 3.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37207 EXPECT_FALSE(process_map->Contains(browser()
208 ->tab_strip_model()
209 ->GetWebContentsAt(3)
210 ->GetMainFrame()
211 ->GetProcess()
212 ->GetID()));
[email protected]e0448872013-01-11 19:35:02213 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30214
[email protected]056ad2a2011-07-12 02:13:55215 // We should have opened 3 new extension tabs. Including the original blank
216 // tab, we now have 4 tabs. Because the app_process app has the background
217 // permission, all of its instances are in the same process. Thus two tabs
218 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02219 ASSERT_EQ(4, browser()->tab_strip_model()->count());
220 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57221
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37222 EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
223 ->tab_strip_model()
224 ->GetWebContentsAt(2)
225 ->GetMainFrame()
226 ->GetProcess());
227 EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
228 ->tab_strip_model()
229 ->GetWebContentsAt(3)
230 ->GetMainFrame()
231 ->GetProcess());
[email protected]3a8eecb2010-04-22 23:56:30232
233 // Now let's do the same using window.open. The same should happen.
scottmg34c5dd882016-02-03 05:21:54234 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
Devlin Croninf1afce252017-08-19 01:21:48235 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, true, NULL);
[email protected]87c7c292011-10-27 16:16:41236 LOG(INFO) << "WindowOpenHelper 1.";
Devlin Croninf1afce252017-08-19 01:21:48237 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, true, NULL);
[email protected]87c7c292011-10-27 16:16:41238 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15239 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17240 // argument), but we temporarily avoid swapping processes away from a hosted
241 // app if it has an opener, because some OAuth providers make script calls
242 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15243 // See crbug.com/59285.
Devlin Croninf1afce252017-08-19 01:21:48244 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, true, NULL);
[email protected]87c7c292011-10-27 16:16:41245 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30246
247 // Now let's have these pages navigate, into or out of the extension web
248 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36249 const GURL& app_url(base_url.Resolve("path1/empty.html"));
250 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02251 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
252 non_app_url);
[email protected]87c7c292011-10-27 16:16:41253 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02254 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
255 app_url);
[email protected]87c7c292011-10-27 16:16:41256 LOG(INFO) << "NavigateTabHelper 2.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37257 EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
258 ->tab_strip_model()
259 ->GetWebContentsAt(2)
260 ->GetMainFrame()
261 ->GetProcess());
262 EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
263 ->tab_strip_model()
264 ->GetWebContentsAt(3)
265 ->GetMainFrame()
266 ->GetProcess());
[email protected]08e94b82010-12-15 22:51:04267
268 // If one of the popup tabs navigates back to the app, window.opener should
269 // be valid.
[email protected]e0448872013-01-11 19:35:02270 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
271 app_url);
[email protected]87c7c292011-10-27 16:16:41272 LOG(INFO) << "NavigateTabHelper 3.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37273 EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
274 ->tab_strip_model()
275 ->GetWebContentsAt(6)
276 ->GetMainFrame()
277 ->GetProcess());
[email protected]08e94b82010-12-15 22:51:04278 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43279 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02280 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13281 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04282 &windowOpenerValid));
283 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41284
285 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30286}
[email protected]faf407b2011-01-05 01:24:32287
[email protected]056ad2a2011-07-12 02:13:55288// Test that hosted apps without the background permission use a process per app
289// instance model, such that separate instances are in separate processes.
[email protected]4ef849e2013-06-10 08:36:59290// Flaky on Windows. http://crbug.com/248047
291#if defined(OS_WIN)
292#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
293#else
294#define MAYBE_AppProcessInstances AppProcessInstances
295#endif
296IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53297 TestAppInstancesHelper("app_process_instances");
298}
[email protected]87c7c292011-10-27 16:16:41299
[email protected]7b54ca02012-03-02 18:06:53300// Test that hosted apps with the background permission but that set
301// allow_js_access to false also use a process per app instance model.
302// Separate instances should be in separate processes.
Devlin Cronin32182162017-09-13 01:36:27303IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53304 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55305}
306
[email protected]15877ca2011-11-18 22:40:52307// Tests that bookmark apps do not use the app process model and are treated
308// like normal web pages instead. http://crbug.com/104636.
[email protected]19506d542013-10-15 23:11:06309// Timing out on Windows. http://crbug.com/238777
310#if defined(OS_WIN)
311#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
312#else
313#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
314#endif
315IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
Devlin Cronin251bd412018-05-30 00:55:42316 extensions::ExtensionService* service =
317 extensions::ExtensionSystem::Get(browser()->profile())
318 ->extension_service();
[email protected]fafdc842014-01-17 18:09:08319 extensions::ProcessMap* process_map =
320 extensions::ProcessMap::Get(browser()->profile());
[email protected]15877ca2011-11-18 22:40:52321
[email protected]15877ca2011-11-18 22:40:52322 GURL base_url = GetTestBaseURL("app_process");
323
[email protected]c2f36e3a2011-12-14 01:27:19324 // Load an app as a bookmark app.
325 std::string error;
jam3f2d3932017-04-26 20:28:51326 scoped_refptr<const Extension> extension;
327 {
Francois Doraye6fb2d02017-10-18 21:29:13328 base::ScopedAllowBlockingForTesting allow_blocking;
jam3f2d3932017-04-26 20:28:51329 extension = extensions::file_util::LoadExtension(
330 test_data_dir_.AppendASCII("app_process"),
331 extensions::Manifest::UNPACKED, Extension::FROM_BOOKMARK, &error);
332 }
[email protected]dc24976f2013-06-02 21:15:09333 service->OnExtensionInstalled(extension.get(),
[email protected]98270432012-09-11 20:51:24334 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]4a1d9c0d2014-06-13 12:50:11335 extensions::kInstallFlagInstallImmediately);
[email protected]c2f36e3a2011-12-14 01:27:19336 ASSERT_TRUE(extension.get());
337 ASSERT_TRUE(extension->from_bookmark());
338
[email protected]15877ca2011-11-18 22:40:52339 // Test both opening a URL in a new tab, and opening a tab and then navigating
340 // it. Either way, bookmark app tabs should be considered normal processes
341 // with no elevated privileges and no WebUI bindings.
342 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19343 browser(), base_url.Resolve("path1/empty.html"),
344 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]15877ca2011-11-18 22:40:52345 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37346 EXPECT_FALSE(process_map->Contains(browser()
347 ->tab_strip_model()
348 ->GetWebContentsAt(1)
349 ->GetMainFrame()
350 ->GetProcess()
351 ->GetID()));
[email protected]e0448872013-01-11 19:35:02352 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52353
[email protected]a7fe9112012-07-20 02:34:45354 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42355 chrome::NOTIFICATION_TAB_ADDED,
[email protected]15877ca2011-11-18 22:40:52356 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10357 chrome::NewTab(browser());
[email protected]15877ca2011-11-18 22:40:52358 tab_added_observer.Wait();
359 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37360 EXPECT_FALSE(process_map->Contains(browser()
361 ->tab_strip_model()
362 ->GetWebContentsAt(2)
363 ->GetMainFrame()
364 ->GetProcess()
365 ->GetID()));
[email protected]e0448872013-01-11 19:35:02366 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52367
368 // We should have opened 2 new bookmark app tabs. Including the original blank
369 // tab, we now have 3 tabs. Because normal pages use the
370 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02371 ASSERT_EQ(3, browser()->tab_strip_model()->count());
372 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37373 EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
374 ->tab_strip_model()
375 ->GetWebContentsAt(2)
376 ->GetMainFrame()
377 ->GetProcess());
[email protected]15877ca2011-11-18 22:40:52378
379 // Now let's do the same using window.open. The same should happen.
scottmg34c5dd882016-02-03 05:21:54380 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
Devlin Croninf1afce252017-08-19 01:21:48381 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, true, NULL);
382 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, true, NULL);
[email protected]15877ca2011-11-18 22:40:52383
384 // Now let's have a tab navigate out of and back into the app's web
385 // extent. Neither navigation should switch processes.
386 const GURL& app_url(base_url.Resolve("path1/empty.html"));
387 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03388 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02389 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
390 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
391 non_app_url);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37392 EXPECT_EQ(host2->GetProcess(), browser()
393 ->tab_strip_model()
394 ->GetWebContentsAt(2)
395 ->GetMainFrame()
396 ->GetProcess());
[email protected]e0448872013-01-11 19:35:02397 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
398 app_url);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37399 EXPECT_EQ(host2->GetProcess(), browser()
400 ->tab_strip_model()
401 ->GetWebContentsAt(2)
402 ->GetMainFrame()
403 ->GetProcess());
[email protected]15877ca2011-11-18 22:40:52404}
405
[email protected]faf407b2011-01-05 01:24:32406// Tests that app process switching works properly in the following scenario:
407// 1. navigate to a page1 in the app
408// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
409// 3. page2 redirects back to a page in the app
410// The final navigation should end up in the app process.
411// See http://crbug.com/61757
John Abd-El-Malek3f7aec312014-08-27 03:18:10412// Flaky. http://crbug.com/341898
413IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32414 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
415
416 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53417 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32418
[email protected]a37d4b02012-06-25 21:56:10419 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32420 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10421 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17422 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48423 // 1. We navigate to redirect.html
424 // 2. Renderer navigates and finishes, counting as a load stop.
425 // 3. Renderer issues the meta refresh to navigate to server-redirect.
426 // 4. Renderer is now in a "provisional load", waiting for navigation to
427 // complete.
428 // 5. Browser sees a redirect response from server-redirect to empty.html, and
429 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17430 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
431 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48432 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17433 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32434
435 // 3 tabs, including the initial about:blank. The last 2 should be the same
436 // process.
[email protected]e0448872013-01-11 19:35:02437 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]c1dffe82013-06-26 20:59:05438 EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02439 browser()->tab_strip_model()->GetWebContentsAt(2)->
440 GetController().GetLastCommittedEntry()->GetURL().path());
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37441 EXPECT_EQ(browser()
442 ->tab_strip_model()
443 ->GetWebContentsAt(1)
444 ->GetMainFrame()
445 ->GetProcess(),
446 browser()
447 ->tab_strip_model()
448 ->GetWebContentsAt(2)
449 ->GetMainFrame()
450 ->GetProcess());
[email protected]faf407b2011-01-05 01:24:32451}
[email protected]d292d8a2011-05-25 03:47:11452
[email protected]aaef4752013-03-02 10:10:51453// Ensure that re-navigating to a URL after installing or uninstalling it as an
454// app correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36455//
[email protected]bc857a62013-05-08 16:44:53456// Fails on Windows. http://crbug.com/238670
[email protected]4c9d02082013-05-15 15:38:36457// Added logging to help diagnose the location of the problem.
[email protected]11170a772013-12-13 11:38:32458IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08459 extensions::ProcessMap* process_map =
460 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52461
[email protected]d292d8a2011-05-25 03:47:11462 // The app under test acts on URLs whose host is "localhost",
463 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53464 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11465
466 // Load an app URL before loading the app.
[email protected]4c9d02082013-05-15 15:38:36467 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11468 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36469 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]e0448872013-01-11 19:35:02470 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37471 EXPECT_FALSE(
472 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11473
[email protected]aaef4752013-03-02 10:10:51474 // Load app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36475 LOG(INFO) << "Loading extension.";
[email protected]d292d8a2011-05-25 03:47:11476 const Extension* app =
477 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36478 LOG(INFO) << "Loading extension - done.";
[email protected]d292d8a2011-05-25 03:47:11479 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36480 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11481 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36482 LOG(INFO) << "Loading path1/empty.html - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37483 EXPECT_TRUE(
484 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11485
[email protected]aaef4752013-03-02 10:10:51486 // Disable app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36487 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11488 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36489 LOG(INFO) << "Disabling extension - done.";
490 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11491 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36492 LOG(INFO) << "Loading path1/empty.html - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37493 EXPECT_FALSE(
494 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]aaef4752013-03-02 10:10:51495}
496
497// Ensure that reloading a URL after installing or uninstalling it as an app
498// correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36499//
500// Added logging to help diagnose the location of the problem.
501// http://crbug.com/238670
[email protected]aaef4752013-03-02 10:10:51502IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08503 extensions::ProcessMap* process_map =
504 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51505
[email protected]aaef4752013-03-02 10:10:51506 // The app under test acts on URLs whose host is "localhost",
507 // so the URLs we navigate to must have host "localhost".
508 GURL base_url = GetTestBaseURL("app_process");
509
510 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36511 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51512 const Extension* app =
513 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36514 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51515 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36516 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51517 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36518 LOG(INFO) << "Disabling extension - done.";
519 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51520 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36521 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51522 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lucas Furukawa Gadani5553a1582019-01-08 18:55:57523 content::NavigationController& controller = contents->GetController();
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37524 EXPECT_FALSE(
525 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
Nasko Oskovaee2f862018-06-15 00:05:52526 // The test starts with about:blank, then navigates to path1/empty.html,
527 // so there should be two entries.
528 EXPECT_EQ(2, controller.GetEntryCount());
[email protected]d292d8a2011-05-25 03:47:11529
[email protected]8d3132f62011-10-12 07:13:42530 // Enable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36531 LOG(INFO) << "Enabling extension.";
[email protected]8d3132f62011-10-12 07:13:42532 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36533 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45534 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42535 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50536 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02537 &browser()->tab_strip_model()->GetActiveWebContents()->
538 GetController()));
[email protected]4c9d02082013-05-15 15:38:36539 LOG(INFO) << "Reloading.";
nick3b04f322016-08-31 19:29:19540 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42541 reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36542 LOG(INFO) << "Reloading - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37543 EXPECT_TRUE(
544 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
Nasko Oskovaee2f862018-06-15 00:05:52545 // Reloading, even with changing SiteInstance/process should not add any
546 // more entries.
547 EXPECT_EQ(2, controller.GetEntryCount());
[email protected]8d3132f62011-10-12 07:13:42548
549 // Disable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36550 LOG(INFO) << "Disabling extension.";
[email protected]8d3132f62011-10-12 07:13:42551 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36552 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45553 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42554 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50555 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02556 &browser()->tab_strip_model()->GetActiveWebContents()->
557 GetController()));
[email protected]4c9d02082013-05-15 15:38:36558 LOG(INFO) << "Reloading.";
nick3b04f322016-08-31 19:29:19559 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42560 reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36561 LOG(INFO) << "Reloading - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37562 EXPECT_FALSE(
563 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
Nasko Oskovaee2f862018-06-15 00:05:52564 EXPECT_EQ(2, controller.GetEntryCount());
[email protected]aaef4752013-03-02 10:10:51565}
566
567// Ensure that reloading a URL with JavaScript after installing or uninstalling
568// it as an app correctly swaps the process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36569//
570// Crashes on Windows and Mac. http://crbug.com/238670
571// Added logging to help diagnose the location of the problem.
572IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
[email protected]fafdc842014-01-17 18:09:08573 extensions::ProcessMap* process_map =
574 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51575
[email protected]aaef4752013-03-02 10:10:51576 // The app under test acts on URLs whose host is "localhost",
577 // so the URLs we navigate to must have host "localhost".
578 GURL base_url = GetTestBaseURL("app_process");
579
580 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36581 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51582 const Extension* app =
583 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36584 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51585 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36586 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51587 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36588 LOG(INFO) << "Disabling extension - done.";
589 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51590 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36591 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51592 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37593 EXPECT_FALSE(
594 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42595
[email protected]d292d8a2011-05-25 03:47:11596 // Enable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36597 LOG(INFO) << "Enabling extension.";
[email protected]d292d8a2011-05-25 03:47:11598 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36599 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45600 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42601 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50602 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02603 &browser()->tab_strip_model()->GetActiveWebContents()->
604 GetController()));
[email protected]4c9d02082013-05-15 15:38:36605 LOG(INFO) << "Executing location.reload().";
[email protected]b6987e02013-01-04 18:30:43606 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42607 js_reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36608 LOG(INFO) << "Executing location.reload() - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37609 EXPECT_TRUE(
610 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11611
612 // Disable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36613 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11614 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36615 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45616 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42617 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50618 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02619 &browser()->tab_strip_model()->GetActiveWebContents()->
620 GetController()));
[email protected]4c9d02082013-05-15 15:38:36621 LOG(INFO) << "Executing location = location.";
[email protected]b6987e02013-01-04 18:30:43622 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42623 js_reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36624 LOG(INFO) << "Executing location = location - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37625 EXPECT_FALSE(
626 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11627}
[email protected]118d3122011-08-10 17:09:53628
[email protected]079b3cc2012-09-26 19:59:13629// Similar to the previous test, but ensure that popup blocking bypass
630// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05631#if defined(OS_CHROMEOS)
632// http://crbug.com/153513
633#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
634#else
635#define MAYBE_OpenAppFromIframe OpenAppFromIframe
636#endif
637IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13638 // Load app and start URL (not in the app).
639 const Extension* app =
640 LoadExtension(test_data_dir_.AppendASCII("app_process"));
641 ASSERT_TRUE(app);
642
[email protected]079b3cc2012-09-26 19:59:13643 ui_test_utils::NavigateToURL(
644 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
645
[email protected]e0448872013-01-11 19:35:02646 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]e0731d72013-07-25 12:39:46647 PopupBlockerTabHelper* popup_blocker_tab_helper =
648 PopupBlockerTabHelper::FromWebContents(tab);
[email protected]992e2912013-08-19 15:05:24649 if (!popup_blocker_tab_helper->GetBlockedPopupsCount()) {
[email protected]e0731d72013-07-25 12:39:46650 content::WindowedNotificationObserver observer(
651 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
652 content::NotificationService::AllSources());
653 observer.Wait();
654 }
655
[email protected]992e2912013-08-19 15:05:24656 EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
[email protected]079b3cc2012-09-26 19:59:13657}
658
[email protected]88aae972011-12-16 01:14:18659// Tests that if an extension launches an app via chrome.tabs.create with an URL
[email protected]b0a29f22013-05-30 23:00:09660// that's not in the app's extent but that server redirects to it, we still end
661// up with an app process. See http://crbug.com/99349 for more details.
662IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
[email protected]88aae972011-12-16 01:14:18663 LoadExtension(test_data_dir_.AppendASCII("app_process"));
664 const Extension* launcher =
665 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
666
[email protected]6169a5772013-05-29 17:41:14667 // There should be two navigations by the time the app page is loaded.
[email protected]88aae972011-12-16 01:14:18668 // 1. The extension launcher page.
[email protected]6169a5772013-05-29 17:41:14669 // 2. The app's URL (which includes a server redirect).
670 // Note that the server redirect does not generate a navigation event.
[email protected]5b8ff1c2012-06-02 20:42:20671 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46672 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]6169a5772013-05-29 17:41:14673 2);
[email protected]cbb1ef592013-06-05 19:49:46674 test_navigation_observer.StartWatchingNewWebContents();
[email protected]88aae972011-12-16 01:14:18675
676 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18677 ui_test_utils::NavigateToURL(
678 browser(), launcher->GetResourceURL("server_redirect.html"));
[email protected]b0a29f22013-05-30 23:00:09679
680 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59681 test_navigation_observer.Wait();
[email protected]b0a29f22013-05-30 23:00:09682
683 // App has loaded, and chrome.app.isInstalled should be true.
684 bool is_installed = false;
685 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
686 browser()->tab_strip_model()->GetActiveWebContents(),
687 "window.domAutomationController.send(chrome.app.isInstalled)",
688 &is_installed));
689 ASSERT_TRUE(is_installed);
690}
691
692// Tests that if an extension launches an app via chrome.tabs.create with an URL
693// that's not in the app's extent but that client redirects to it, we still end
694// up with an app process.
695IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
[email protected]b0a29f22013-05-30 23:00:09696 LoadExtension(test_data_dir_.AppendASCII("app_process"));
697 const Extension* launcher =
698 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
699
700 // There should be three navigations by the time the app page is loaded.
701 // 1. The extension launcher page.
702 // 2. The URL that the extension launches, which client redirects.
703 // 3. The app's URL.
704 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46705 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]b0a29f22013-05-30 23:00:09706 3);
[email protected]cbb1ef592013-06-05 19:49:46707 test_navigation_observer.StartWatchingNewWebContents();
[email protected]b0a29f22013-05-30 23:00:09708
709 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18710 ui_test_utils::NavigateToURL(
711 browser(), launcher->GetResourceURL("client_redirect.html"));
[email protected]88aae972011-12-16 01:14:18712
713 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59714 test_navigation_observer.Wait();
[email protected]88aae972011-12-16 01:14:18715
716 // App has loaded, and chrome.app.isInstalled should be true.
717 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43718 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02719 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13720 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18721 &is_installed));
722 ASSERT_TRUE(is_installed);
723}
724
[email protected]d55c2382011-08-18 23:10:36725// Tests that if we have an app process (path1/container.html) with a non-app
726// iframe (path3/iframe.html), then opening a link from that iframe to a new
727// window to a same-origin non-app URL (path3/empty.html) should keep the window
728// in the app process.
729// This is in contrast to OpenAppFromIframe, since here the popup will not be
730// missing special permissions and should be scriptable from the iframe.
731// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29732IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]fafdc842014-01-17 18:09:08733 extensions::ProcessMap* process_map =
734 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52735
[email protected]d55c2382011-08-18 23:10:36736 GURL base_url = GetTestBaseURL("app_process");
737
738 // Load app and start URL (in the app).
739 const Extension* app =
740 LoadExtension(test_data_dir_.AppendASCII("app_process"));
741 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29742
[email protected]19da16a92012-05-23 17:11:29743 ui_test_utils::NavigateToURL(browser(),
744 base_url.Resolve("path1/container.html"));
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37745 content::RenderProcessHost* process = browser()
746 ->tab_strip_model()
747 ->GetWebContentsAt(0)
748 ->GetMainFrame()
749 ->GetProcess();
[email protected]f3b1a082011-11-18 00:34:30750 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36751
Alex Moshchuka854a5e2018-04-09 23:37:14752 // Popup window should be in the app's process.
scottmg0d8e4ab2016-01-28 00:34:55753 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]415dc61612013-10-29 04:35:27754 EXPECT_EQ(2U, active_browser_list->size());
755 content::WebContents* popup_contents =
756 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
757 content::WaitForLoadStop(popup_contents);
758
rdevlin.cronine29bde72015-07-17 15:11:35759 content::RenderProcessHost* popup_process =
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37760 popup_contents->GetMainFrame()->GetProcess();
Alex Moshchuka854a5e2018-04-09 23:37:14761 EXPECT_EQ(process, popup_process);
762 EXPECT_TRUE(process_map->Contains(popup_process->GetID()));
[email protected]d55c2382011-08-18 23:10:36763}
764
[email protected]a344b762012-03-16 18:53:49765// http://crbug.com/118502
766#if defined(OS_MACOSX) || defined(OS_LINUX)
767#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
768#else
769#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
770#endif
771IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]fafdc842014-01-17 18:09:08772 extensions::ProcessMap* process_map =
773 extensions::ProcessMap::Get(browser()->profile());
[email protected]6f371442011-11-09 06:45:46774
[email protected]a09add52011-08-12 03:59:23775 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
776
777 GURL base_url = GetTestBaseURL("app_process");
778
779 // Load the app, chrome.app.isInstalled should be true.
780 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02781 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37782 EXPECT_TRUE(
783 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]a09add52011-08-12 03:59:23784 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43785 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
786 contents,
[email protected]06bc5d92013-01-02 22:44:13787 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23788 &is_installed));
789 ASSERT_TRUE(is_installed);
790
791 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02792 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45793 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37794 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50795 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02796 &browser()->tab_strip_model()->GetActiveWebContents()->
797 GetController()));
nick3b04f322016-08-31 19:29:19798 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37799 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43800 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
801 contents,
[email protected]06bc5d92013-01-02 22:44:13802 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23803 &is_installed));
804 ASSERT_TRUE(is_installed);
805}
[email protected]2aca9a92013-12-03 05:16:07806
Alex Moshchuk7e26eca2018-03-03 01:34:29807// Test that a cross-site renderer-initiated navigation away from a hosted app
808// stays in the same BrowsingInstance, so that postMessage calls to the app's
809// other windows still work, and a cross-site browser-initiated navigation away
810// from a hosted app switches BrowsingInstances.
811IN_PROC_BROWSER_TEST_F(AppApiTest, NavigatePopupFromAppToOutsideApp) {
[email protected]fafdc842014-01-17 18:09:08812 extensions::ProcessMap* process_map =
813 extensions::ProcessMap::Get(browser()->profile());
[email protected]2aca9a92013-12-03 05:16:07814
[email protected]2aca9a92013-12-03 05:16:07815 GURL base_url = GetTestBaseURL("app_process");
816
817 // Load app and start URL (in the app).
818 const Extension* app =
819 LoadExtension(test_data_dir_.AppendASCII("app_process"));
820 ASSERT_TRUE(app);
821
822 ui_test_utils::NavigateToURL(browser(),
823 base_url.Resolve("path1/iframe.html"));
824 content::SiteInstance* app_instance =
825 browser()->tab_strip_model()->GetWebContentsAt(0)->GetSiteInstance();
826 EXPECT_TRUE(process_map->Contains(app_instance->GetProcess()->GetID()));
827
828 // Popup window should be in the app's process.
scottmg0d8e4ab2016-01-28 00:34:55829 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]2aca9a92013-12-03 05:16:07830 EXPECT_EQ(2U, active_browser_list->size());
831 content::WebContents* popup_contents =
832 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
833 content::WaitForLoadStop(popup_contents);
834
835 SiteInstance* popup_instance = popup_contents->GetSiteInstance();
836 EXPECT_EQ(app_instance, popup_instance);
837
Alex Moshchuk7e26eca2018-03-03 01:34:29838 // Do a renderer-initiated navigation in the popup to a URL outside the app.
[email protected]2aca9a92013-12-03 05:16:07839 GURL non_app_url(base_url.Resolve("path3/empty.html"));
Alex Moshchuk7e26eca2018-03-03 01:34:29840 content::TestNavigationObserver observer(popup_contents);
841 EXPECT_TRUE(ExecuteScript(
842 popup_contents,
843 base::StringPrintf("location = '%s';", non_app_url.spec().c_str())));
844 observer.Wait();
[email protected]2aca9a92013-12-03 05:16:07845
Alex Moshchuka854a5e2018-04-09 23:37:14846 // The popup will stay in the same SiteInstance, even in
847 // --site-per-process mode, because the popup is still same-site with its
848 // opener. Staying in same SiteInstance implies that postMessage will still
849 // work.
Alex Moshchuk7e26eca2018-03-03 01:34:29850 EXPECT_TRUE(
851 app_instance->IsRelatedSiteInstance(popup_contents->GetSiteInstance()));
Alex Moshchuka854a5e2018-04-09 23:37:14852 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
Alex Moshchuk7e26eca2018-03-03 01:34:29853
Alex Moshchuka854a5e2018-04-09 23:37:14854 // Go back in the popup.
Alex Moshchuk7e26eca2018-03-03 01:34:29855 {
856 content::TestNavigationObserver observer(popup_contents);
857 popup_contents->GetController().GoBack();
858 observer.Wait();
859 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
860 }
861
Alex Moshchuka854a5e2018-04-09 23:37:14862 // Do a browser-initiated navigation in the popup to a same-site URL outside
863 // the app.
864 // TODO(alexmos): This could swap BrowsingInstances, since a
865 // browser-initiated navigation breaks the scripting relationship between the
866 // popup and the app, but it currently does not, since we keep the scripting
867 // relationship regardless of whether the navigation is browser or
868 // renderer-initiated (see https://crbug.com/828720). Consider changing
869 // this in the future as part of https://crbug.com/718516.
Alex Moshchuk7e26eca2018-03-03 01:34:29870 {
871 content::TestNavigationObserver observer(popup_contents);
872 ui_test_utils::NavigateToURL(active_browser_list->get(1), non_app_url);
873 observer.Wait();
Alex Moshchuka854a5e2018-04-09 23:37:14874 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
875 EXPECT_TRUE(
876 app_instance->IsRelatedSiteInstance(popup_contents->GetSiteInstance()));
877 }
878
879 // Go back in the popup.
880 {
881 content::TestNavigationObserver observer(popup_contents);
882 popup_contents->GetController().GoBack();
883 observer.Wait();
884 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
885 }
886
887 // Do a browser-initiated navigation in the popup to a cross-site URL outside
888 // the app. This should swap BrowsingInstances.
889 {
890 content::TestNavigationObserver observer(popup_contents);
891 GURL cross_site_url(
892 embedded_test_server()->GetURL("foo.com", "/title1.html"));
893 ui_test_utils::NavigateToURL(active_browser_list->get(1), cross_site_url);
894 observer.Wait();
Alex Moshchuk7e26eca2018-03-03 01:34:29895 EXPECT_NE(app_instance, popup_contents->GetSiteInstance());
896 EXPECT_FALSE(
897 app_instance->IsRelatedSiteInstance(popup_contents->GetSiteInstance()));
898 }
[email protected]2aca9a92013-12-03 05:16:07899}