blob: b0a3ee7c5d3c7138aa5a5adfd15ce10462859a31 [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"
Lei Zhangfe5b86932019-02-01 17:26:596#include "base/strings/stringprintf.h"
avia2f4804a2015-12-24 23:11:137#include "build/build_config.h"
[email protected]fdf40f3e2013-07-11 23:55:468#include "chrome/browser/chrome_notification_types.h"
[email protected]3a8eecb2010-04-22 23:56:309#include "chrome/browser/extensions/extension_apitest.h"
[email protected]6f371442011-11-09 06:45:4610#include "chrome/browser/extensions/extension_service.h"
[email protected]8ecad5e2010-12-02 21:18:3311#include "chrome/browser/profiles/profile.h"
[email protected]e0731d72013-07-25 12:39:4612#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
[email protected]7b5dc002010-11-16 23:08:1013#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1014#include "chrome/browser/ui/browser_commands.h"
[email protected]d8748142012-05-16 21:13:4315#include "chrome/browser/ui/browser_finder.h"
[email protected]71b73f02011-04-06 15:57:2916#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3617#include "chrome/browser/ui/browser_window.h"
[email protected]e0448872013-01-11 19:35:0218#include "chrome/browser/ui/tabs/tab_strip_model.h"
Evan Stade2e327592019-07-08 17:55:5719#include "chrome/browser/ui/view_ids.h"
[email protected]3a8eecb2010-04-22 23:56:3020#include "chrome/common/chrome_switches.h"
Evan Stade2e327592019-07-08 17:55:5721#include "chrome/test/base/interactive_test_utils.h"
[email protected]af44e7fb2011-07-29 18:32:3222#include "chrome/test/base/ui_test_utils.h"
skym71603842016-10-10 18:17:3123#include "components/sync/model/string_ordinal.h"
[email protected]ad23a092011-12-28 07:02:0424#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0725#include "content/public/browser/notification_service.h"
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:3726#include "content/public/browser/render_frame_host.h"
[email protected]c333e792012-01-06 16:57:3927#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3328#include "content/public/browser/render_view_host.h"
[email protected]2aca9a92013-12-03 05:16:0729#include "content/public/browser/site_instance.h"
[email protected]6acde6352012-01-04 16:52:2030#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4231#include "content/public/test/browser_test_utils.h"
[email protected]5b8ff1c2012-06-02 20:42:2032#include "content/public/test/test_navigation_observer.h"
[email protected]22401dc2014-03-21 01:38:5733#include "extensions/browser/extension_host.h"
[email protected]59b0e602014-01-30 00:41:2434#include "extensions/browser/extension_system.h"
[email protected]4a1d9c0d2014-06-13 12:50:1135#include "extensions/browser/install_flag.h"
[email protected]50de9aa22013-11-14 06:30:3436#include "extensions/browser/process_map.h"
[email protected]e4452d32013-11-15 23:07:4137#include "extensions/common/extension.h"
[email protected]85df9d12014-04-15 17:02:1438#include "extensions/common/file_util.h"
[email protected]558878cc82013-11-09 01:25:5139#include "extensions/common/switches.h"
[email protected]f2cb3cf2013-03-21 01:40:5340#include "net/dns/mock_host_resolver.h"
[email protected]c1dffe82013-06-26 20:59:0541#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]3a8eecb2010-04-22 23:56:3042
[email protected]c5eed492012-01-04 17:07:5043using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1144using content::RenderViewHost;
[email protected]2aca9a92013-12-03 05:16:0745using content::SiteInstance;
[email protected]4ca15302012-01-03 05:53:2046using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3447using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2048
Devlin Croninef3e37e2018-05-14 23:47:2449class AppApiTest : public extensions::ExtensionApiTest {
[email protected]7b54ca02012-03-02 18:06:5350 protected:
51 // Gets the base URL for files for a specific test, making sure that it uses
52 // "localhost" as the hostname, since that is what the extent is declared
53 // as in the test apps manifests.
[email protected]0bb29bd2014-04-30 21:39:1854 GURL GetTestBaseURL(const std::string& test_directory) {
[email protected]7b54ca02012-03-02 18:06:5355 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:1856 replace_host.SetHostStr("localhost");
[email protected]c1dffe82013-06-26 20:59:0557 GURL base_url = embedded_test_server()->GetURL(
58 "/extensions/api_test/" + test_directory + "/");
[email protected]7b54ca02012-03-02 18:06:5359 return base_url.ReplaceComponents(replace_host);
60 }
61
62 // Pass flags to make testing apps easier.
avi3ef9ec9e2014-12-22 22:50:1763 void SetUpCommandLine(base::CommandLine* command_line) override {
Devlin Croninef3e37e2018-05-14 23:47:2464 extensions::ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:1765 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]7b54ca02012-03-02 18:06:5366 switches::kDisablePopupBlocking);
avi3ef9ec9e2014-12-22 22:50:1767 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:5168 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]7b54ca02012-03-02 18:06:5369 }
70
jambb11ed742017-05-01 17:27:5971 void SetUpOnMainThread() override {
Devlin Croninef3e37e2018-05-14 23:47:2472 extensions::ExtensionApiTest::SetUpOnMainThread();
jambb11ed742017-05-01 17:27:5973 host_resolver()->AddRule("*", "127.0.0.1");
74 ASSERT_TRUE(StartEmbeddedTestServer());
75 }
76
[email protected]7b54ca02012-03-02 18:06:5377 // Helper function to test that independent tabs of the named app are loaded
78 // into separate processes.
[email protected]0bb29bd2014-04-30 21:39:1879 void TestAppInstancesHelper(const std::string& app_name) {
[email protected]7b54ca02012-03-02 18:06:5380 LOG(INFO) << "Start of test.";
81
[email protected]fafdc842014-01-17 18:09:0882 extensions::ProcessMap* process_map =
83 extensions::ProcessMap::Get(browser()->profile());
[email protected]7b54ca02012-03-02 18:06:5384
[email protected]7b54ca02012-03-02 18:06:5385 ASSERT_TRUE(LoadExtension(
86 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2787 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5388
89 // Open two tabs in the app, one outside it.
90 GURL base_url = GetTestBaseURL(app_name);
91
92 // Test both opening a URL in a new tab, and opening a tab and then
93 // navigating it. Either way, app tabs should be considered extension
94 // processes, but they have no elevated privileges and thus should not
95 // have WebUI bindings.
96 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:1997 browser(), base_url.Resolve("path1/empty.html"),
98 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]7b54ca02012-03-02 18:06:5399 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
100 LOG(INFO) << "Nav 1.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37101 EXPECT_TRUE(process_map->Contains(browser()
102 ->tab_strip_model()
103 ->GetWebContentsAt(1)
104 ->GetMainFrame()
105 ->GetProcess()
106 ->GetID()));
[email protected]e0448872013-01-11 19:35:02107 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53108
Evan Stadeacbfc3de2019-07-18 19:44:17109 ui_test_utils::TabAddedWaiter tab_add(browser());
[email protected]a37d4b02012-06-25 21:56:10110 chrome::NewTab(browser());
Evan Stadeacbfc3de2019-07-18 19:44:17111 tab_add.Wait();
[email protected]7b54ca02012-03-02 18:06:53112 LOG(INFO) << "New tab.";
113 ui_test_utils::NavigateToURL(browser(),
114 base_url.Resolve("path2/empty.html"));
115 LOG(INFO) << "Nav 2.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37116 EXPECT_TRUE(process_map->Contains(browser()
117 ->tab_strip_model()
118 ->GetWebContentsAt(2)
119 ->GetMainFrame()
120 ->GetProcess()
121 ->GetID()));
[email protected]e0448872013-01-11 19:35:02122 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53123
124 // We should have opened 2 new extension tabs. Including the original blank
125 // tab, we now have 3 tabs. The two app tabs should not be in the same
126 // process, since they do not have the background permission. (Thus, we
127 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02128 ASSERT_EQ(3, browser()->tab_strip_model()->count());
129 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
130 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37131 EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
132 tab2->GetMainFrame()->GetProcess());
[email protected]7b54ca02012-03-02 18:06:53133
134 // Opening tabs with window.open should keep the page in the opener's
135 // process.
scottmg34c5dd882016-02-03 05:21:54136 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
Devlin Croninf1afce252017-08-19 01:21:48137 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, true, NULL);
[email protected]7b54ca02012-03-02 18:06:53138 LOG(INFO) << "WindowOpenHelper 1.";
Devlin Croninf1afce252017-08-19 01:21:48139 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, true, NULL);
[email protected]7b54ca02012-03-02 18:06:53140 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27141 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53142 }
143};
144
[email protected]079b3cc2012-09-26 19:59:13145// Omits the disable-popup-blocking flag so we can cover that case.
146class BlockedAppApiTest : public AppApiTest {
147 protected:
avi3ef9ec9e2014-12-22 22:50:17148 void SetUpCommandLine(base::CommandLine* command_line) override {
Devlin Croninef3e37e2018-05-14 23:47:24149 extensions::ExtensionApiTest::SetUpCommandLine(command_line);
avi3ef9ec9e2014-12-22 22:50:17150 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]558878cc82013-11-09 01:25:51151 extensions::switches::kAllowHTTPBackgroundPage);
[email protected]079b3cc2012-09-26 19:59:13152 }
153};
154
[email protected]7b54ca02012-03-02 18:06:53155// Tests that hosted apps with the background permission get a process-per-app
156// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56157// http://crbug.com/172750
[email protected]2340a3c2013-06-17 20:54:36158IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41159 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59160
[email protected]fafdc842014-01-17 18:09:08161 extensions::ProcessMap* process_map =
162 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52163
[email protected]cbf4d1912010-08-12 18:24:57164 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30165
[email protected]87c7c292011-10-27 16:16:41166 LOG(INFO) << "Loaded extension.";
167
[email protected]cbf4d1912010-08-12 18:24:57168 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53169 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59170
[email protected]f0e13332011-05-20 22:41:14171 // Test both opening a URL in a new tab, and opening a tab and then navigating
172 // it. Either way, app tabs should be considered extension processes, but
173 // they have no elevated privileges and thus should not have WebUI bindings.
174 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19175 browser(), base_url.Resolve("path1/empty.html"),
176 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]f0e13332011-05-20 22:41:14177 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37178 EXPECT_TRUE(process_map->Contains(browser()
179 ->tab_strip_model()
180 ->GetWebContentsAt(1)
181 ->GetMainFrame()
182 ->GetProcess()
183 ->GetID()));
[email protected]e0448872013-01-11 19:35:02184 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41185 LOG(INFO) << "Nav 1.";
186
187 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19188 browser(), base_url.Resolve("path2/empty.html"),
189 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]87c7c292011-10-27 16:16:41190 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37191 EXPECT_TRUE(process_map->Contains(browser()
192 ->tab_strip_model()
193 ->GetWebContentsAt(2)
194 ->GetMainFrame()
195 ->GetProcess()
196 ->GetID()));
[email protected]e0448872013-01-11 19:35:02197 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41198 LOG(INFO) << "Nav 2.";
199
Evan Stadeacbfc3de2019-07-18 19:44:17200 ui_test_utils::TabAddedWaiter tab_add(browser());
[email protected]a37d4b02012-06-25 21:56:10201 chrome::NewTab(browser());
Evan Stadeacbfc3de2019-07-18 19:44:17202 tab_add.Wait();
[email protected]87c7c292011-10-27 16:16:41203 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57204 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41205 LOG(INFO) << "Nav 3.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37206 EXPECT_FALSE(process_map->Contains(browser()
207 ->tab_strip_model()
208 ->GetWebContentsAt(3)
209 ->GetMainFrame()
210 ->GetProcess()
211 ->GetID()));
[email protected]e0448872013-01-11 19:35:02212 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30213
[email protected]056ad2a2011-07-12 02:13:55214 // We should have opened 3 new extension tabs. Including the original blank
215 // tab, we now have 4 tabs. Because the app_process app has the background
216 // permission, all of its instances are in the same process. Thus two tabs
217 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02218 ASSERT_EQ(4, browser()->tab_strip_model()->count());
219 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57220
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37221 EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
222 ->tab_strip_model()
223 ->GetWebContentsAt(2)
224 ->GetMainFrame()
225 ->GetProcess());
226 EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
227 ->tab_strip_model()
228 ->GetWebContentsAt(3)
229 ->GetMainFrame()
230 ->GetProcess());
[email protected]3a8eecb2010-04-22 23:56:30231
232 // Now let's do the same using window.open. The same should happen.
scottmg34c5dd882016-02-03 05:21:54233 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
Devlin Croninf1afce252017-08-19 01:21:48234 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, true, NULL);
[email protected]87c7c292011-10-27 16:16:41235 LOG(INFO) << "WindowOpenHelper 1.";
Devlin Croninf1afce252017-08-19 01:21:48236 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, true, NULL);
[email protected]87c7c292011-10-27 16:16:41237 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15238 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17239 // argument), but we temporarily avoid swapping processes away from a hosted
240 // app if it has an opener, because some OAuth providers make script calls
241 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15242 // See crbug.com/59285.
Devlin Croninf1afce252017-08-19 01:21:48243 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, true, NULL);
[email protected]87c7c292011-10-27 16:16:41244 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30245
246 // Now let's have these pages navigate, into or out of the extension web
247 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36248 const GURL& app_url(base_url.Resolve("path1/empty.html"));
249 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02250 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
251 non_app_url);
[email protected]87c7c292011-10-27 16:16:41252 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02253 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
254 app_url);
[email protected]87c7c292011-10-27 16:16:41255 LOG(INFO) << "NavigateTabHelper 2.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37256 EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
257 ->tab_strip_model()
258 ->GetWebContentsAt(2)
259 ->GetMainFrame()
260 ->GetProcess());
261 EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
262 ->tab_strip_model()
263 ->GetWebContentsAt(3)
264 ->GetMainFrame()
265 ->GetProcess());
[email protected]08e94b82010-12-15 22:51:04266
267 // If one of the popup tabs navigates back to the app, window.opener should
268 // be valid.
[email protected]e0448872013-01-11 19:35:02269 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
270 app_url);
[email protected]87c7c292011-10-27 16:16:41271 LOG(INFO) << "NavigateTabHelper 3.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37272 EXPECT_EQ(tab->GetMainFrame()->GetProcess(), browser()
273 ->tab_strip_model()
274 ->GetWebContentsAt(6)
275 ->GetMainFrame()
276 ->GetProcess());
[email protected]08e94b82010-12-15 22:51:04277 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43278 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02279 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13280 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04281 &windowOpenerValid));
282 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41283
284 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30285}
[email protected]faf407b2011-01-05 01:24:32286
[email protected]056ad2a2011-07-12 02:13:55287// Test that hosted apps without the background permission use a process per app
288// instance model, such that separate instances are in separate processes.
[email protected]4ef849e2013-06-10 08:36:59289// Flaky on Windows. http://crbug.com/248047
290#if defined(OS_WIN)
291#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
292#else
293#define MAYBE_AppProcessInstances AppProcessInstances
294#endif
295IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53296 TestAppInstancesHelper("app_process_instances");
297}
[email protected]87c7c292011-10-27 16:16:41298
[email protected]7b54ca02012-03-02 18:06:53299// Test that hosted apps with the background permission but that set
300// allow_js_access to false also use a process per app instance model.
301// Separate instances should be in separate processes.
Devlin Cronin32182162017-09-13 01:36:27302IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53303 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55304}
305
[email protected]15877ca2011-11-18 22:40:52306// Tests that bookmark apps do not use the app process model and are treated
307// like normal web pages instead. http://crbug.com/104636.
[email protected]19506d542013-10-15 23:11:06308// Timing out on Windows. http://crbug.com/238777
309#if defined(OS_WIN)
310#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
311#else
312#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
313#endif
314IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
Devlin Cronin251bd412018-05-30 00:55:42315 extensions::ExtensionService* service =
316 extensions::ExtensionSystem::Get(browser()->profile())
317 ->extension_service();
[email protected]fafdc842014-01-17 18:09:08318 extensions::ProcessMap* process_map =
319 extensions::ProcessMap::Get(browser()->profile());
[email protected]15877ca2011-11-18 22:40:52320
[email protected]15877ca2011-11-18 22:40:52321 GURL base_url = GetTestBaseURL("app_process");
322
[email protected]c2f36e3a2011-12-14 01:27:19323 // Load an app as a bookmark app.
324 std::string error;
jam3f2d3932017-04-26 20:28:51325 scoped_refptr<const Extension> extension;
326 {
Francois Doraye6fb2d02017-10-18 21:29:13327 base::ScopedAllowBlockingForTesting allow_blocking;
jam3f2d3932017-04-26 20:28:51328 extension = extensions::file_util::LoadExtension(
329 test_data_dir_.AppendASCII("app_process"),
330 extensions::Manifest::UNPACKED, Extension::FROM_BOOKMARK, &error);
331 }
[email protected]dc24976f2013-06-02 21:15:09332 service->OnExtensionInstalled(extension.get(),
[email protected]98270432012-09-11 20:51:24333 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]4a1d9c0d2014-06-13 12:50:11334 extensions::kInstallFlagInstallImmediately);
[email protected]c2f36e3a2011-12-14 01:27:19335 ASSERT_TRUE(extension.get());
336 ASSERT_TRUE(extension->from_bookmark());
337
[email protected]15877ca2011-11-18 22:40:52338 // Test both opening a URL in a new tab, and opening a tab and then navigating
339 // it. Either way, bookmark app tabs should be considered normal processes
340 // with no elevated privileges and no WebUI bindings.
341 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19342 browser(), base_url.Resolve("path1/empty.html"),
343 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]15877ca2011-11-18 22:40:52344 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37345 EXPECT_FALSE(process_map->Contains(browser()
346 ->tab_strip_model()
347 ->GetWebContentsAt(1)
348 ->GetMainFrame()
349 ->GetProcess()
350 ->GetID()));
[email protected]e0448872013-01-11 19:35:02351 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52352
Evan Stadeacbfc3de2019-07-18 19:44:17353 ui_test_utils::TabAddedWaiter tab_add(browser());
[email protected]a37d4b02012-06-25 21:56:10354 chrome::NewTab(browser());
Evan Stadeacbfc3de2019-07-18 19:44:17355 tab_add.Wait();
[email protected]15877ca2011-11-18 22:40:52356 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37357 EXPECT_FALSE(process_map->Contains(browser()
358 ->tab_strip_model()
359 ->GetWebContentsAt(2)
360 ->GetMainFrame()
361 ->GetProcess()
362 ->GetID()));
[email protected]e0448872013-01-11 19:35:02363 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52364
365 // We should have opened 2 new bookmark app tabs. Including the original blank
366 // tab, we now have 3 tabs. Because normal pages use the
367 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02368 ASSERT_EQ(3, browser()->tab_strip_model()->count());
369 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37370 EXPECT_NE(tab->GetMainFrame()->GetProcess(), browser()
371 ->tab_strip_model()
372 ->GetWebContentsAt(2)
373 ->GetMainFrame()
374 ->GetProcess());
[email protected]15877ca2011-11-18 22:40:52375
376 // Now let's do the same using window.open. The same should happen.
scottmg34c5dd882016-02-03 05:21:54377 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
Devlin Croninf1afce252017-08-19 01:21:48378 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, true, NULL);
379 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, true, NULL);
[email protected]15877ca2011-11-18 22:40:52380
381 // Now let's have a tab navigate out of and back into the app's web
382 // extent. Neither navigation should switch processes.
383 const GURL& app_url(base_url.Resolve("path1/empty.html"));
384 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03385 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02386 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
387 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
388 non_app_url);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37389 EXPECT_EQ(host2->GetProcess(), browser()
390 ->tab_strip_model()
391 ->GetWebContentsAt(2)
392 ->GetMainFrame()
393 ->GetProcess());
[email protected]e0448872013-01-11 19:35:02394 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
395 app_url);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37396 EXPECT_EQ(host2->GetProcess(), browser()
397 ->tab_strip_model()
398 ->GetWebContentsAt(2)
399 ->GetMainFrame()
400 ->GetProcess());
[email protected]15877ca2011-11-18 22:40:52401}
402
[email protected]faf407b2011-01-05 01:24:32403// Tests that app process switching works properly in the following scenario:
404// 1. navigate to a page1 in the app
405// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
406// 3. page2 redirects back to a page in the app
407// The final navigation should end up in the app process.
408// See http://crbug.com/61757
John Abd-El-Malek3f7aec312014-08-27 03:18:10409// Flaky. http://crbug.com/341898
410IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32411 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
412
413 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53414 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32415
[email protected]a37d4b02012-06-25 21:56:10416 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32417 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10418 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17419 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48420 // 1. We navigate to redirect.html
421 // 2. Renderer navigates and finishes, counting as a load stop.
422 // 3. Renderer issues the meta refresh to navigate to server-redirect.
423 // 4. Renderer is now in a "provisional load", waiting for navigation to
424 // complete.
425 // 5. Browser sees a redirect response from server-redirect to empty.html, and
426 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17427 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
428 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48429 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17430 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32431
432 // 3 tabs, including the initial about:blank. The last 2 should be the same
433 // process.
[email protected]e0448872013-01-11 19:35:02434 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]c1dffe82013-06-26 20:59:05435 EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02436 browser()->tab_strip_model()->GetWebContentsAt(2)->
437 GetController().GetLastCommittedEntry()->GetURL().path());
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37438 EXPECT_EQ(browser()
439 ->tab_strip_model()
440 ->GetWebContentsAt(1)
441 ->GetMainFrame()
442 ->GetProcess(),
443 browser()
444 ->tab_strip_model()
445 ->GetWebContentsAt(2)
446 ->GetMainFrame()
447 ->GetProcess());
[email protected]faf407b2011-01-05 01:24:32448}
[email protected]d292d8a2011-05-25 03:47:11449
[email protected]aaef4752013-03-02 10:10:51450// Ensure that re-navigating to a URL after installing or uninstalling it as an
451// app correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36452//
[email protected]bc857a62013-05-08 16:44:53453// Fails on Windows. http://crbug.com/238670
[email protected]4c9d02082013-05-15 15:38:36454// Added logging to help diagnose the location of the problem.
[email protected]11170a772013-12-13 11:38:32455IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08456 extensions::ProcessMap* process_map =
457 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52458
[email protected]d292d8a2011-05-25 03:47:11459 // The app under test acts on URLs whose host is "localhost",
460 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53461 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11462
463 // Load an app URL before loading the app.
[email protected]4c9d02082013-05-15 15:38:36464 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11465 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36466 LOG(INFO) << "Loading path1/empty.html - done.";
[email protected]e0448872013-01-11 19:35:02467 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37468 EXPECT_FALSE(
469 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11470
[email protected]aaef4752013-03-02 10:10:51471 // Load app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36472 LOG(INFO) << "Loading extension.";
[email protected]d292d8a2011-05-25 03:47:11473 const Extension* app =
474 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36475 LOG(INFO) << "Loading extension - done.";
[email protected]d292d8a2011-05-25 03:47:11476 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36477 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11478 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36479 LOG(INFO) << "Loading path1/empty.html - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37480 EXPECT_TRUE(
481 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11482
[email protected]aaef4752013-03-02 10:10:51483 // Disable app and re-navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36484 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11485 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36486 LOG(INFO) << "Disabling extension - done.";
487 LOG(INFO) << "Loading path1/empty.html.";
[email protected]d292d8a2011-05-25 03:47:11488 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36489 LOG(INFO) << "Loading path1/empty.html - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37490 EXPECT_FALSE(
491 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]aaef4752013-03-02 10:10:51492}
493
494// Ensure that reloading a URL after installing or uninstalling it as an app
495// correctly swaps the tab to the app process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36496//
497// Added logging to help diagnose the location of the problem.
498// http://crbug.com/238670
[email protected]aaef4752013-03-02 10:10:51499IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
[email protected]fafdc842014-01-17 18:09:08500 extensions::ProcessMap* process_map =
501 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51502
[email protected]aaef4752013-03-02 10:10:51503 // The app under test acts on URLs whose host is "localhost",
504 // so the URLs we navigate to must have host "localhost".
505 GURL base_url = GetTestBaseURL("app_process");
506
507 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36508 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51509 const Extension* app =
510 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36511 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51512 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36513 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51514 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36515 LOG(INFO) << "Disabling extension - done.";
516 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51517 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36518 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51519 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lucas Furukawa Gadani5553a1582019-01-08 18:55:57520 content::NavigationController& controller = contents->GetController();
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37521 EXPECT_FALSE(
522 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
Nasko Oskovaee2f862018-06-15 00:05:52523 // The test starts with about:blank, then navigates to path1/empty.html,
524 // so there should be two entries.
525 EXPECT_EQ(2, controller.GetEntryCount());
[email protected]d292d8a2011-05-25 03:47:11526
[email protected]8d3132f62011-10-12 07:13:42527 // Enable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36528 LOG(INFO) << "Enabling extension.";
[email protected]8d3132f62011-10-12 07:13:42529 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36530 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45531 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42532 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50533 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02534 &browser()->tab_strip_model()->GetActiveWebContents()->
535 GetController()));
[email protected]4c9d02082013-05-15 15:38:36536 LOG(INFO) << "Reloading.";
nick3b04f322016-08-31 19:29:19537 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42538 reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36539 LOG(INFO) << "Reloading - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37540 EXPECT_TRUE(
541 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
Nasko Oskovaee2f862018-06-15 00:05:52542 // Reloading, even with changing SiteInstance/process should not add any
543 // more entries.
544 EXPECT_EQ(2, controller.GetEntryCount());
[email protected]8d3132f62011-10-12 07:13:42545
546 // Disable app and reload the page.
[email protected]4c9d02082013-05-15 15:38:36547 LOG(INFO) << "Disabling extension.";
[email protected]8d3132f62011-10-12 07:13:42548 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36549 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45550 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42551 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50552 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02553 &browser()->tab_strip_model()->GetActiveWebContents()->
554 GetController()));
[email protected]4c9d02082013-05-15 15:38:36555 LOG(INFO) << "Reloading.";
nick3b04f322016-08-31 19:29:19556 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42557 reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36558 LOG(INFO) << "Reloading - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37559 EXPECT_FALSE(
560 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
Nasko Oskovaee2f862018-06-15 00:05:52561 EXPECT_EQ(2, controller.GetEntryCount());
[email protected]aaef4752013-03-02 10:10:51562}
563
564// Ensure that reloading a URL with JavaScript after installing or uninstalling
565// it as an app correctly swaps the process. (http://crbug.com/80621)
[email protected]4c9d02082013-05-15 15:38:36566//
567// Crashes on Windows and Mac. http://crbug.com/238670
568// Added logging to help diagnose the location of the problem.
569IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
[email protected]fafdc842014-01-17 18:09:08570 extensions::ProcessMap* process_map =
571 extensions::ProcessMap::Get(browser()->profile());
[email protected]aaef4752013-03-02 10:10:51572
[email protected]aaef4752013-03-02 10:10:51573 // The app under test acts on URLs whose host is "localhost",
574 // so the URLs we navigate to must have host "localhost".
575 GURL base_url = GetTestBaseURL("app_process");
576
577 // Load app, disable it, and navigate to the page.
[email protected]4c9d02082013-05-15 15:38:36578 LOG(INFO) << "Loading extension.";
[email protected]aaef4752013-03-02 10:10:51579 const Extension* app =
580 LoadExtension(test_data_dir_.AppendASCII("app_process"));
[email protected]4c9d02082013-05-15 15:38:36581 LOG(INFO) << "Loading extension - done.";
[email protected]aaef4752013-03-02 10:10:51582 ASSERT_TRUE(app);
[email protected]4c9d02082013-05-15 15:38:36583 LOG(INFO) << "Disabling extension.";
[email protected]aaef4752013-03-02 10:10:51584 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36585 LOG(INFO) << "Disabling extension - done.";
586 LOG(INFO) << "Navigate to path1/empty.html.";
[email protected]aaef4752013-03-02 10:10:51587 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]4c9d02082013-05-15 15:38:36588 LOG(INFO) << "Navigate to path1/empty.html - done.";
[email protected]aaef4752013-03-02 10:10:51589 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37590 EXPECT_FALSE(
591 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42592
[email protected]d292d8a2011-05-25 03:47:11593 // Enable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36594 LOG(INFO) << "Enabling extension.";
[email protected]d292d8a2011-05-25 03:47:11595 EnableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36596 LOG(INFO) << "Enabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45597 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42598 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50599 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02600 &browser()->tab_strip_model()->GetActiveWebContents()->
601 GetController()));
[email protected]4c9d02082013-05-15 15:38:36602 LOG(INFO) << "Executing location.reload().";
[email protected]b6987e02013-01-04 18:30:43603 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42604 js_reload_observer.Wait();
[email protected]4c9d02082013-05-15 15:38:36605 LOG(INFO) << "Executing location.reload() - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37606 EXPECT_TRUE(
607 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11608
609 // Disable app and reload via JavaScript.
[email protected]4c9d02082013-05-15 15:38:36610 LOG(INFO) << "Disabling extension.";
[email protected]d292d8a2011-05-25 03:47:11611 DisableExtension(app->id());
[email protected]4c9d02082013-05-15 15:38:36612 LOG(INFO) << "Disabling extension - done.";
[email protected]a7fe9112012-07-20 02:34:45613 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42614 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50615 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02616 &browser()->tab_strip_model()->GetActiveWebContents()->
617 GetController()));
[email protected]4c9d02082013-05-15 15:38:36618 LOG(INFO) << "Executing location = location.";
[email protected]b6987e02013-01-04 18:30:43619 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42620 js_reload_observer2.Wait();
[email protected]4c9d02082013-05-15 15:38:36621 LOG(INFO) << "Executing location = location - done.";
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37622 EXPECT_FALSE(
623 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11624}
[email protected]118d3122011-08-10 17:09:53625
[email protected]079b3cc2012-09-26 19:59:13626// Similar to the previous test, but ensure that popup blocking bypass
627// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05628#if defined(OS_CHROMEOS)
629// http://crbug.com/153513
630#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
631#else
632#define MAYBE_OpenAppFromIframe OpenAppFromIframe
633#endif
634IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13635 // Load app and start URL (not in the app).
636 const Extension* app =
637 LoadExtension(test_data_dir_.AppendASCII("app_process"));
638 ASSERT_TRUE(app);
639
[email protected]079b3cc2012-09-26 19:59:13640 ui_test_utils::NavigateToURL(
641 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
Evan Stade2e327592019-07-08 17:55:57642 ui_test_utils::WaitForViewVisibility(browser(), VIEW_ID_CONTENT_SETTING_POPUP,
643 true);
[email protected]079b3cc2012-09-26 19:59:13644
[email protected]e0448872013-01-11 19:35:02645 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]e0731d72013-07-25 12:39:46646 PopupBlockerTabHelper* popup_blocker_tab_helper =
647 PopupBlockerTabHelper::FromWebContents(tab);
[email protected]992e2912013-08-19 15:05:24648 EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
[email protected]079b3cc2012-09-26 19:59:13649}
650
[email protected]88aae972011-12-16 01:14:18651// Tests that if an extension launches an app via chrome.tabs.create with an URL
[email protected]b0a29f22013-05-30 23:00:09652// that's not in the app's extent but that server redirects to it, we still end
653// up with an app process. See http://crbug.com/99349 for more details.
654IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
[email protected]88aae972011-12-16 01:14:18655 LoadExtension(test_data_dir_.AppendASCII("app_process"));
656 const Extension* launcher =
657 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
658
[email protected]6169a5772013-05-29 17:41:14659 // There should be two navigations by the time the app page is loaded.
[email protected]88aae972011-12-16 01:14:18660 // 1. The extension launcher page.
[email protected]6169a5772013-05-29 17:41:14661 // 2. The app's URL (which includes a server redirect).
662 // Note that the server redirect does not generate a navigation event.
[email protected]5b8ff1c2012-06-02 20:42:20663 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46664 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]6169a5772013-05-29 17:41:14665 2);
[email protected]cbb1ef592013-06-05 19:49:46666 test_navigation_observer.StartWatchingNewWebContents();
[email protected]88aae972011-12-16 01:14:18667
668 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18669 ui_test_utils::NavigateToURL(
670 browser(), launcher->GetResourceURL("server_redirect.html"));
[email protected]b0a29f22013-05-30 23:00:09671
672 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59673 test_navigation_observer.Wait();
[email protected]b0a29f22013-05-30 23:00:09674
675 // App has loaded, and chrome.app.isInstalled should be true.
676 bool is_installed = false;
677 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
678 browser()->tab_strip_model()->GetActiveWebContents(),
679 "window.domAutomationController.send(chrome.app.isInstalled)",
680 &is_installed));
681 ASSERT_TRUE(is_installed);
682}
683
684// Tests that if an extension launches an app via chrome.tabs.create with an URL
685// that's not in the app's extent but that client redirects to it, we still end
686// up with an app process.
687IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
[email protected]b0a29f22013-05-30 23:00:09688 LoadExtension(test_data_dir_.AppendASCII("app_process"));
689 const Extension* launcher =
690 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
691
692 // There should be three navigations by the time the app page is loaded.
693 // 1. The extension launcher page.
694 // 2. The URL that the extension launches, which client redirects.
695 // 3. The app's URL.
696 content::TestNavigationObserver test_navigation_observer(
[email protected]cbb1ef592013-06-05 19:49:46697 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]b0a29f22013-05-30 23:00:09698 3);
[email protected]cbb1ef592013-06-05 19:49:46699 test_navigation_observer.StartWatchingNewWebContents();
[email protected]b0a29f22013-05-30 23:00:09700
701 // Load the launcher extension, which should launch the app.
thestig53986dc2014-12-16 06:09:18702 ui_test_utils::NavigateToURL(
703 browser(), launcher->GetResourceURL("client_redirect.html"));
[email protected]88aae972011-12-16 01:14:18704
705 // Wait for app tab to be created and loaded.
[email protected]91621872013-10-08 04:04:59706 test_navigation_observer.Wait();
[email protected]88aae972011-12-16 01:14:18707
708 // App has loaded, and chrome.app.isInstalled should be true.
709 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43710 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02711 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13712 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18713 &is_installed));
714 ASSERT_TRUE(is_installed);
715}
716
[email protected]d55c2382011-08-18 23:10:36717// Tests that if we have an app process (path1/container.html) with a non-app
718// iframe (path3/iframe.html), then opening a link from that iframe to a new
719// window to a same-origin non-app URL (path3/empty.html) should keep the window
720// in the app process.
721// This is in contrast to OpenAppFromIframe, since here the popup will not be
722// missing special permissions and should be scriptable from the iframe.
723// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29724IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]fafdc842014-01-17 18:09:08725 extensions::ProcessMap* process_map =
726 extensions::ProcessMap::Get(browser()->profile());
[email protected]718eab62011-10-05 21:16:52727
[email protected]d55c2382011-08-18 23:10:36728 GURL base_url = GetTestBaseURL("app_process");
729
730 // Load app and start URL (in the app).
731 const Extension* app =
732 LoadExtension(test_data_dir_.AppendASCII("app_process"));
733 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29734
[email protected]19da16a92012-05-23 17:11:29735 ui_test_utils::NavigateToURL(browser(),
736 base_url.Resolve("path1/container.html"));
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37737 content::RenderProcessHost* process = browser()
738 ->tab_strip_model()
739 ->GetWebContentsAt(0)
740 ->GetMainFrame()
741 ->GetProcess();
[email protected]f3b1a082011-11-18 00:34:30742 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36743
Alex Moshchuka854a5e2018-04-09 23:37:14744 // Popup window should be in the app's process.
scottmg0d8e4ab2016-01-28 00:34:55745 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]415dc61612013-10-29 04:35:27746 EXPECT_EQ(2U, active_browser_list->size());
747 content::WebContents* popup_contents =
748 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
749 content::WaitForLoadStop(popup_contents);
750
rdevlin.cronine29bde72015-07-17 15:11:35751 content::RenderProcessHost* popup_process =
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37752 popup_contents->GetMainFrame()->GetProcess();
Alex Moshchuka854a5e2018-04-09 23:37:14753 EXPECT_EQ(process, popup_process);
754 EXPECT_TRUE(process_map->Contains(popup_process->GetID()));
[email protected]d55c2382011-08-18 23:10:36755}
756
[email protected]a344b762012-03-16 18:53:49757// http://crbug.com/118502
758#if defined(OS_MACOSX) || defined(OS_LINUX)
759#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
760#else
761#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
762#endif
763IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]fafdc842014-01-17 18:09:08764 extensions::ProcessMap* process_map =
765 extensions::ProcessMap::Get(browser()->profile());
[email protected]6f371442011-11-09 06:45:46766
[email protected]a09add52011-08-12 03:59:23767 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
768
769 GURL base_url = GetTestBaseURL("app_process");
770
771 // Load the app, chrome.app.isInstalled should be true.
772 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02773 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
Lukasz Anforowicz3f0b84ca2017-09-28 13:02:37774 EXPECT_TRUE(
775 process_map->Contains(contents->GetMainFrame()->GetProcess()->GetID()));
[email protected]a09add52011-08-12 03:59:23776 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43777 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
778 contents,
[email protected]06bc5d92013-01-02 22:44:13779 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23780 &is_installed));
781 ASSERT_TRUE(is_installed);
782
783 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02784 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45785 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37786 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50787 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02788 &browser()->tab_strip_model()->GetActiveWebContents()->
789 GetController()));
nick3b04f322016-08-31 19:29:19790 chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37791 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43792 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
793 contents,
[email protected]06bc5d92013-01-02 22:44:13794 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23795 &is_installed));
796 ASSERT_TRUE(is_installed);
797}
[email protected]2aca9a92013-12-03 05:16:07798
Alex Moshchuk7e26eca2018-03-03 01:34:29799// Test that a cross-site renderer-initiated navigation away from a hosted app
800// stays in the same BrowsingInstance, so that postMessage calls to the app's
801// other windows still work, and a cross-site browser-initiated navigation away
802// from a hosted app switches BrowsingInstances.
803IN_PROC_BROWSER_TEST_F(AppApiTest, NavigatePopupFromAppToOutsideApp) {
[email protected]fafdc842014-01-17 18:09:08804 extensions::ProcessMap* process_map =
805 extensions::ProcessMap::Get(browser()->profile());
[email protected]2aca9a92013-12-03 05:16:07806
[email protected]2aca9a92013-12-03 05:16:07807 GURL base_url = GetTestBaseURL("app_process");
808
809 // Load app and start URL (in the app).
810 const Extension* app =
811 LoadExtension(test_data_dir_.AppendASCII("app_process"));
812 ASSERT_TRUE(app);
813
814 ui_test_utils::NavigateToURL(browser(),
815 base_url.Resolve("path1/iframe.html"));
816 content::SiteInstance* app_instance =
817 browser()->tab_strip_model()->GetWebContentsAt(0)->GetSiteInstance();
818 EXPECT_TRUE(process_map->Contains(app_instance->GetProcess()->GetID()));
819
820 // Popup window should be in the app's process.
scottmg0d8e4ab2016-01-28 00:34:55821 const BrowserList* active_browser_list = BrowserList::GetInstance();
[email protected]2aca9a92013-12-03 05:16:07822 EXPECT_EQ(2U, active_browser_list->size());
823 content::WebContents* popup_contents =
824 active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
825 content::WaitForLoadStop(popup_contents);
826
827 SiteInstance* popup_instance = popup_contents->GetSiteInstance();
828 EXPECT_EQ(app_instance, popup_instance);
829
Alex Moshchuk7e26eca2018-03-03 01:34:29830 // Do a renderer-initiated navigation in the popup to a URL outside the app.
[email protected]2aca9a92013-12-03 05:16:07831 GURL non_app_url(base_url.Resolve("path3/empty.html"));
Alex Moshchuk7e26eca2018-03-03 01:34:29832 content::TestNavigationObserver observer(popup_contents);
833 EXPECT_TRUE(ExecuteScript(
834 popup_contents,
835 base::StringPrintf("location = '%s';", non_app_url.spec().c_str())));
836 observer.Wait();
[email protected]2aca9a92013-12-03 05:16:07837
Alex Moshchuka854a5e2018-04-09 23:37:14838 // The popup will stay in the same SiteInstance, even in
839 // --site-per-process mode, because the popup is still same-site with its
840 // opener. Staying in same SiteInstance implies that postMessage will still
841 // work.
Alex Moshchuk7e26eca2018-03-03 01:34:29842 EXPECT_TRUE(
843 app_instance->IsRelatedSiteInstance(popup_contents->GetSiteInstance()));
Alex Moshchuka854a5e2018-04-09 23:37:14844 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
Alex Moshchuk7e26eca2018-03-03 01:34:29845
Alex Moshchuka854a5e2018-04-09 23:37:14846 // Go back in the popup.
Alex Moshchuk7e26eca2018-03-03 01:34:29847 {
848 content::TestNavigationObserver observer(popup_contents);
849 popup_contents->GetController().GoBack();
850 observer.Wait();
851 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
852 }
853
Alex Moshchuka854a5e2018-04-09 23:37:14854 // Do a browser-initiated navigation in the popup to a same-site URL outside
855 // the app.
856 // TODO(alexmos): This could swap BrowsingInstances, since a
857 // browser-initiated navigation breaks the scripting relationship between the
858 // popup and the app, but it currently does not, since we keep the scripting
859 // relationship regardless of whether the navigation is browser or
860 // renderer-initiated (see https://crbug.com/828720). Consider changing
861 // this in the future as part of https://crbug.com/718516.
Alex Moshchuk7e26eca2018-03-03 01:34:29862 {
863 content::TestNavigationObserver observer(popup_contents);
864 ui_test_utils::NavigateToURL(active_browser_list->get(1), non_app_url);
865 observer.Wait();
Alex Moshchuka854a5e2018-04-09 23:37:14866 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
867 EXPECT_TRUE(
868 app_instance->IsRelatedSiteInstance(popup_contents->GetSiteInstance()));
869 }
870
871 // Go back in the popup.
872 {
873 content::TestNavigationObserver observer(popup_contents);
874 popup_contents->GetController().GoBack();
875 observer.Wait();
876 EXPECT_EQ(app_instance, popup_contents->GetSiteInstance());
877 }
878
879 // Do a browser-initiated navigation in the popup to a cross-site URL outside
880 // the app. This should swap BrowsingInstances.
881 {
882 content::TestNavigationObserver observer(popup_contents);
883 GURL cross_site_url(
884 embedded_test_server()->GetURL("foo.com", "/title1.html"));
885 ui_test_utils::NavigateToURL(active_browser_list->get(1), cross_site_url);
886 observer.Wait();
Alex Moshchuk7e26eca2018-03-03 01:34:29887 EXPECT_NE(app_instance, popup_contents->GetSiteInstance());
888 EXPECT_FALSE(
889 app_instance->IsRelatedSiteInstance(popup_contents->GetSiteInstance()));
890 }
[email protected]2aca9a92013-12-03 05:16:07891}