blob: 0ae9eadd69a7b9a837f4b8ea697f03057b6425f5 [file] [log] [blame]
[email protected]71b73f02011-04-06 15:57:291// Copyright (c) 2011 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]ce7f62e32010-08-10 23:43:595#include "base/utf_string_conversions.h"
[email protected]3a8eecb2010-04-22 23:56:306#include "chrome/browser/extensions/extension_apitest.h"
7#include "chrome/browser/extensions/extension_host.h"
[email protected]6f371442011-11-09 06:45:468#include "chrome/browser/extensions/extension_service.h"
9#include "chrome/browser/extensions/process_map.h"
[email protected]8ecad5e2010-12-02 21:18:3310#include "chrome/browser/profiles/profile.h"
[email protected]7b5dc002010-11-16 23:08:1011#include "chrome/browser/ui/browser.h"
[email protected]71b73f02011-04-06 15:57:2912#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3613#include "chrome/browser/ui/browser_window.h"
[email protected]ae673742011-08-24 19:48:3714#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]3a8eecb2010-04-22 23:56:3015#include "chrome/common/chrome_switches.h"
[email protected]814a7bf0f2011-08-13 05:30:5916#include "chrome/common/extensions/extension.h"
[email protected]c2f36e3a2011-12-14 01:27:1917#include "chrome/common/extensions/extension_file_util.h"
[email protected]af44e7fb2011-07-29 18:32:3218#include "chrome/test/base/ui_test_utils.h"
[email protected]a035dfda2011-03-02 01:01:4919#include "content/browser/renderer_host/render_view_host.h"
20#include "content/browser/tab_contents/tab_contents.h"
[email protected]ad50def52011-10-19 23:17:0721#include "content/public/browser/notification_service.h"
[email protected]3a8eecb2010-04-22 23:56:3022#include "net/base/mock_host_resolver.h"
23
24class AppApiTest : public ExtensionApiTest {
[email protected]118d3122011-08-10 17:09:5325 protected:
26 // Gets the base URL for files for a specific test, making sure that it uses
27 // "localhost" as the hostname, since that is what the extent is declared
28 // as in the test apps manifests.
29 GURL GetTestBaseURL(std::string test_directory) {
30 GURL::Replacements replace_host;
31 std::string host_str("localhost"); // must stay in scope with replace_host
32 replace_host.SetHostStr(host_str);
33 GURL base_url = test_server()->GetURL(
34 "files/extensions/api_test/" + test_directory + "/");
35 return base_url.ReplaceComponents(replace_host);
36 }
[email protected]3a8eecb2010-04-22 23:56:3037};
38
39// Simulates a page calling window.open on an URL, and waits for the navigation.
40static void WindowOpenHelper(Browser* browser,
[email protected]12ea9b272010-08-24 11:31:4041 RenderViewHost* opener_host,
42 const GURL& url,
43 bool newtab_process_should_equal_opener) {
[email protected]3114db2c2011-09-12 20:09:0544 ui_test_utils::WindowedNotificationObserver observer(
[email protected]ad50def52011-10-19 23:17:0745 content::NOTIFICATION_LOAD_STOP,
46 content::NotificationService::AllSources());
[email protected]9fabbf72010-09-30 21:50:0547 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
48 opener_host, L"", L"window.open('" + UTF8ToWide(url.spec()) + L"');"));
[email protected]3a8eecb2010-04-22 23:56:3049
[email protected]12ea9b272010-08-24 11:31:4050 // The above window.open call is not user-initiated, it will create
51 // a popup window instead of a new tab in current window.
52 // Now the active tab in last active window should be the new tab.
53 Browser* last_active_browser = BrowserList::GetLastActive();
54 EXPECT_TRUE(last_active_browser);
55 TabContents* newtab = last_active_browser->GetSelectedTabContents();
56 EXPECT_TRUE(newtab);
[email protected]3114db2c2011-09-12 20:09:0557 observer.Wait();
[email protected]3a8eecb2010-04-22 23:56:3058 EXPECT_EQ(url, newtab->controller().GetLastCommittedEntry()->url());
[email protected]12ea9b272010-08-24 11:31:4059 if (newtab_process_should_equal_opener)
60 EXPECT_EQ(opener_host->process(), newtab->render_view_host()->process());
61 else
62 EXPECT_NE(opener_host->process(), newtab->render_view_host()->process());
[email protected]3a8eecb2010-04-22 23:56:3063}
64
65// Simulates a page navigating itself to an URL, and waits for the navigation.
66static void NavigateTabHelper(TabContents* contents, const GURL& url) {
67 bool result = false;
[email protected]3114db2c2011-09-12 20:09:0568 ui_test_utils::WindowedNotificationObserver observer(
69 content::NOTIFICATION_LOAD_STOP,
[email protected]ad50def52011-10-19 23:17:0770 content::NotificationService::AllSources());
[email protected]9fabbf72010-09-30 21:50:0571 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
[email protected]3a8eecb2010-04-22 23:56:3072 contents->render_view_host(), L"",
[email protected]d38f83f2010-04-30 23:25:5773 L"window.addEventListener('unload', function() {"
74 L" window.domAutomationController.send(true);"
75 L"}, false);"
76 L"window.location = '" + UTF8ToWide(url.spec()) + L"';",
[email protected]9fabbf72010-09-30 21:50:0577 &result));
[email protected]3a8eecb2010-04-22 23:56:3078 ASSERT_TRUE(result);
[email protected]3114db2c2011-09-12 20:09:0579 observer.Wait();
[email protected]3a8eecb2010-04-22 23:56:3080 EXPECT_EQ(url, contents->controller().GetLastCommittedEntry()->url());
81}
82
[email protected]87c7c292011-10-27 16:16:4183IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) {
84 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:5985
[email protected]12ea9b272010-08-24 11:31:4086 CommandLine::ForCurrentProcess()->AppendSwitch(
87 switches::kDisablePopupBlocking);
88
[email protected]6f371442011-11-09 06:45:4689 extensions::ProcessMap* process_map =
90 browser()->profile()->GetExtensionService()->process_map();
[email protected]718eab62011-10-05 21:16:5291
[email protected]3a8eecb2010-04-22 23:56:3092 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]95409e12010-08-17 20:07:1193 ASSERT_TRUE(test_server()->Start());
[email protected]3a8eecb2010-04-22 23:56:3094
[email protected]cbf4d1912010-08-12 18:24:5795 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:3096
[email protected]87c7c292011-10-27 16:16:4197 LOG(INFO) << "Loaded extension.";
98
[email protected]cbf4d1912010-08-12 18:24:5799 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53100 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59101
[email protected]f0e13332011-05-20 22:41:14102 // Test both opening a URL in a new tab, and opening a tab and then navigating
103 // it. Either way, app tabs should be considered extension processes, but
104 // they have no elevated privileges and thus should not have WebUI bindings.
105 ui_test_utils::NavigateToURLWithDisposition(
106 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
107 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46108 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30109 browser()->GetTabContentsAt(1)->render_view_host()->process()->GetID()));
[email protected]f0e13332011-05-20 22:41:14110 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
[email protected]87c7c292011-10-27 16:16:41111 LOG(INFO) << "Nav 1.";
112
113 ui_test_utils::NavigateToURLWithDisposition(
114 browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
115 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46116 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30117 browser()->GetTabContentsAt(2)->render_view_host()->process()->GetID()));
[email protected]f0e13332011-05-20 22:41:14118 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
[email protected]87c7c292011-10-27 16:16:41119 LOG(INFO) << "Nav 2.";
120
121 ui_test_utils::WindowedNotificationObserver tab_added_observer(
122 content::NOTIFICATION_TAB_ADDED,
123 content::NotificationService::AllSources());
[email protected]cbf4d1912010-08-12 18:24:57124 browser()->NewTab();
[email protected]87c7c292011-10-27 16:16:41125 tab_added_observer.Wait();
126 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57127 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41128 LOG(INFO) << "Nav 3.";
[email protected]6f371442011-11-09 06:45:46129 EXPECT_FALSE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30130 browser()->GetTabContentsAt(3)->render_view_host()->process()->GetID()));
[email protected]f0e13332011-05-20 22:41:14131 EXPECT_FALSE(browser()->GetTabContentsAt(3)->web_ui());
[email protected]3a8eecb2010-04-22 23:56:30132
[email protected]056ad2a2011-07-12 02:13:55133 // We should have opened 3 new extension tabs. Including the original blank
134 // tab, we now have 4 tabs. Because the app_process app has the background
135 // permission, all of its instances are in the same process. Thus two tabs
136 // should be part of the extension app and grouped in the same process.
[email protected]3a8eecb2010-04-22 23:56:30137 ASSERT_EQ(4, browser()->tab_count());
[email protected]cbf4d1912010-08-12 18:24:57138 RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host();
[email protected]cbf4d1912010-08-12 18:24:57139
140 EXPECT_EQ(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30141 browser()->GetTabContentsAt(2)->render_view_host()->process());
[email protected]cbf4d1912010-08-12 18:24:57142 EXPECT_NE(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30143 browser()->GetTabContentsAt(3)->render_view_host()->process());
144
145 // Now let's do the same using window.open. The same should happen.
[email protected]12ea9b272010-08-24 11:31:40146 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
[email protected]cbf4d1912010-08-12 18:24:57147 WindowOpenHelper(browser(), host,
[email protected]12ea9b272010-08-24 11:31:40148 base_url.Resolve("path1/empty.html"), true);
[email protected]87c7c292011-10-27 16:16:41149 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]cbf4d1912010-08-12 18:24:57150 WindowOpenHelper(browser(), host,
[email protected]12ea9b272010-08-24 11:31:40151 base_url.Resolve("path2/empty.html"), true);
[email protected]87c7c292011-10-27 16:16:41152 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15153 // TODO(creis): This should open in a new process (i.e., false for the last
154 // argument), but we temporarily avoid swapping processes away from an app
155 // until we're able to support cross-process postMessage calls.
156 // See crbug.com/59285.
[email protected]cbf4d1912010-08-12 18:24:57157 WindowOpenHelper(browser(), host,
[email protected]361a5f1f2011-10-05 20:11:15158 base_url.Resolve("path3/empty.html"), true);
[email protected]87c7c292011-10-27 16:16:41159 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30160
161 // Now let's have these pages navigate, into or out of the extension web
162 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36163 const GURL& app_url(base_url.Resolve("path1/empty.html"));
164 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]cbf4d1912010-08-12 18:24:57165 NavigateTabHelper(browser()->GetTabContentsAt(2), non_app_url);
[email protected]87c7c292011-10-27 16:16:41166 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]3a8eecb2010-04-22 23:56:30167 NavigateTabHelper(browser()->GetTabContentsAt(3), app_url);
[email protected]87c7c292011-10-27 16:16:41168 LOG(INFO) << "NavigateTabHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15169 // TODO(creis): This should swap out of the app's process (i.e., EXPECT_NE),
170 // but we temporarily avoid swapping away from an app in case the window
171 // tries to send a postMessage to the app. See crbug.com/59285.
172 EXPECT_EQ(host->process(),
[email protected]cbf4d1912010-08-12 18:24:57173 browser()->GetTabContentsAt(2)->render_view_host()->process());
174 EXPECT_EQ(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30175 browser()->GetTabContentsAt(3)->render_view_host()->process());
[email protected]08e94b82010-12-15 22:51:04176
177 // If one of the popup tabs navigates back to the app, window.opener should
178 // be valid.
179 NavigateTabHelper(browser()->GetTabContentsAt(6), app_url);
[email protected]87c7c292011-10-27 16:16:41180 LOG(INFO) << "NavigateTabHelper 3.";
[email protected]08e94b82010-12-15 22:51:04181 EXPECT_EQ(host->process(),
182 browser()->GetTabContentsAt(6)->render_view_host()->process());
183 bool windowOpenerValid = false;
184 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
185 browser()->GetTabContentsAt(6)->render_view_host(), L"",
186 L"window.domAutomationController.send(window.opener != null)",
187 &windowOpenerValid));
188 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41189
190 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30191}
[email protected]faf407b2011-01-05 01:24:32192
[email protected]056ad2a2011-07-12 02:13:55193// Test that hosted apps without the background permission use a process per app
194// instance model, such that separate instances are in separate processes.
[email protected]87c7c292011-10-27 16:16:41195IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessInstances) {
196 LOG(INFO) << "Start of test.";
197
[email protected]056ad2a2011-07-12 02:13:55198 CommandLine::ForCurrentProcess()->AppendSwitch(
199 switches::kDisablePopupBlocking);
200
[email protected]6f371442011-11-09 06:45:46201 extensions::ProcessMap* process_map =
202 browser()->profile()->GetExtensionService()->process_map();
[email protected]718eab62011-10-05 21:16:52203
[email protected]056ad2a2011-07-12 02:13:55204 host_resolver()->AddRule("*", "127.0.0.1");
205 ASSERT_TRUE(test_server()->Start());
206
207 ASSERT_TRUE(LoadExtension(
208 test_data_dir_.AppendASCII("app_process_instances")));
209
210 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53211 GURL base_url = GetTestBaseURL("app_process_instances");
[email protected]056ad2a2011-07-12 02:13:55212
213 // Test both opening a URL in a new tab, and opening a tab and then navigating
214 // it. Either way, app tabs should be considered extension processes, but
215 // they have no elevated privileges and thus should not have WebUI bindings.
216 ui_test_utils::NavigateToURLWithDisposition(
217 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
218 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]87c7c292011-10-27 16:16:41219 LOG(INFO) << "Nav 1.";
[email protected]6f371442011-11-09 06:45:46220 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30221 browser()->GetTabContentsAt(1)->render_view_host()->process()->GetID()));
[email protected]056ad2a2011-07-12 02:13:55222 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
[email protected]87c7c292011-10-27 16:16:41223
224 ui_test_utils::WindowedNotificationObserver tab_added_observer(
225 content::NOTIFICATION_TAB_ADDED,
226 content::NotificationService::AllSources());
[email protected]056ad2a2011-07-12 02:13:55227 browser()->NewTab();
[email protected]87c7c292011-10-27 16:16:41228 tab_added_observer.Wait();
229 LOG(INFO) << "New tab.";
[email protected]056ad2a2011-07-12 02:13:55230 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
[email protected]87c7c292011-10-27 16:16:41231 LOG(INFO) << "Nav 2.";
[email protected]6f371442011-11-09 06:45:46232 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30233 browser()->GetTabContentsAt(2)->render_view_host()->process()->GetID()));
[email protected]056ad2a2011-07-12 02:13:55234 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
235
236 // We should have opened 2 new extension tabs. Including the original blank
237 // tab, we now have 3 tabs. The two app tabs should not be in the same
238 // process, since they do not have the background permission. (Thus, we want
239 // to separate them to improve responsiveness.)
240 ASSERT_EQ(3, browser()->tab_count());
241 RenderViewHost* host1 = browser()->GetTabContentsAt(1)->render_view_host();
242 RenderViewHost* host2 = browser()->GetTabContentsAt(2)->render_view_host();
243 EXPECT_NE(host1->process(), host2->process());
244
245 // Opening tabs with window.open should keep the page in the opener's process.
246 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
247 WindowOpenHelper(browser(), host1,
248 base_url.Resolve("path1/empty.html"), true);
[email protected]87c7c292011-10-27 16:16:41249 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]056ad2a2011-07-12 02:13:55250 WindowOpenHelper(browser(), host2,
251 base_url.Resolve("path2/empty.html"), true);
[email protected]87c7c292011-10-27 16:16:41252 LOG(INFO) << "End of test.";
[email protected]056ad2a2011-07-12 02:13:55253}
254
[email protected]15877ca2011-11-18 22:40:52255// Tests that bookmark apps do not use the app process model and are treated
256// like normal web pages instead. http://crbug.com/104636.
[email protected]c2f36e3a2011-12-14 01:27:19257IN_PROC_BROWSER_TEST_F(AppApiTest, BookmarkAppGetsNormalProcess) {
[email protected]15877ca2011-11-18 22:40:52258 CommandLine::ForCurrentProcess()->AppendSwitch(
259 switches::kDisablePopupBlocking);
260
[email protected]c2f36e3a2011-12-14 01:27:19261 ExtensionService* service = browser()->profile()->GetExtensionService();
262 extensions::ProcessMap* process_map = service->process_map();
[email protected]15877ca2011-11-18 22:40:52263
264 host_resolver()->AddRule("*", "127.0.0.1");
265 ASSERT_TRUE(test_server()->Start());
[email protected]15877ca2011-11-18 22:40:52266 GURL base_url = GetTestBaseURL("app_process");
267
[email protected]c2f36e3a2011-12-14 01:27:19268 // Load an app as a bookmark app.
269 std::string error;
270 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
271 test_data_dir_.AppendASCII("app_process"),
272 Extension::LOAD,
273 Extension::FROM_BOOKMARK,
274 &error));
275 service->OnExtensionInstalled(extension, false, 0);
276 ASSERT_TRUE(extension.get());
277 ASSERT_TRUE(extension->from_bookmark());
278
[email protected]15877ca2011-11-18 22:40:52279 // Test both opening a URL in a new tab, and opening a tab and then navigating
280 // it. Either way, bookmark app tabs should be considered normal processes
281 // with no elevated privileges and no WebUI bindings.
282 ui_test_utils::NavigateToURLWithDisposition(
283 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
284 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
285 EXPECT_FALSE(process_map->Contains(
286 browser()->GetTabContentsAt(1)->render_view_host()->process()->GetID()));
287 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
288
289 ui_test_utils::WindowedNotificationObserver tab_added_observer(
290 content::NOTIFICATION_TAB_ADDED,
291 content::NotificationService::AllSources());
292 browser()->NewTab();
293 tab_added_observer.Wait();
294 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
295 EXPECT_FALSE(process_map->Contains(
296 browser()->GetTabContentsAt(2)->render_view_host()->process()->GetID()));
297 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
298
299 // We should have opened 2 new bookmark app tabs. Including the original blank
300 // tab, we now have 3 tabs. Because normal pages use the
301 // process-per-site-instance model, each should be in its own process.
302 ASSERT_EQ(3, browser()->tab_count());
303 RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host();
304 EXPECT_NE(host->process(),
305 browser()->GetTabContentsAt(2)->render_view_host()->process());
306
307 // Now let's do the same using window.open. The same should happen.
308 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
309 WindowOpenHelper(browser(), host,
310 base_url.Resolve("path1/empty.html"), true);
311 WindowOpenHelper(browser(), host,
312 base_url.Resolve("path2/empty.html"), true);
313
314 // Now let's have a tab navigate out of and back into the app's web
315 // extent. Neither navigation should switch processes.
316 const GURL& app_url(base_url.Resolve("path1/empty.html"));
317 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
318 RenderViewHost* host2 = browser()->GetTabContentsAt(2)->render_view_host();
319 NavigateTabHelper(browser()->GetTabContentsAt(2), non_app_url);
320 EXPECT_EQ(host2->process(),
321 browser()->GetTabContentsAt(2)->render_view_host()->process());
322 NavigateTabHelper(browser()->GetTabContentsAt(2), app_url);
323 EXPECT_EQ(host2->process(),
324 browser()->GetTabContentsAt(2)->render_view_host()->process());
325}
326
[email protected]faf407b2011-01-05 01:24:32327// Tests that app process switching works properly in the following scenario:
328// 1. navigate to a page1 in the app
329// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
330// 3. page2 redirects back to a page in the app
331// The final navigation should end up in the app process.
332// See http://crbug.com/61757
[email protected]c374f8a82011-12-01 00:45:08333// This test occasionally timeout on aura. See crbug.com/105957.
334#if defined(USE_AURA)
335#define MAYBE_AppProcessRedirectBack DISABLED_AppProcessRedirectBack
336#else
337#define MAYBE_AppProcessRedirectBack AppProcessRedirectBack
338#endif
339IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32340 CommandLine::ForCurrentProcess()->AppendSwitch(
341 switches::kDisablePopupBlocking);
342
343 host_resolver()->AddRule("*", "127.0.0.1");
344 ASSERT_TRUE(test_server()->Start());
345
346 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
347
348 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53349 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32350
351 browser()->NewTab();
352 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
353 browser()->NewTab();
[email protected]4ad5d77d2011-12-03 02:00:48354 // Wait until the second tab finishes its redirect train (3 hops).
355 // 1. We navigate to redirect.html
356 // 2. Renderer navigates and finishes, counting as a load stop.
357 // 3. Renderer issues the meta refresh to navigate to server-redirect.
358 // 4. Renderer is now in a "provisional load", waiting for navigation to
359 // complete.
360 // 5. Browser sees a redirect response from server-redirect to empty.html, and
361 // transfers that to a new navigation, using RequestTransferURL.
362 // 6. We navigate to empty.html.
363 // 7. Renderer is still in a provisional load to server-redirect, so that is
364 // cancelled, and counts as a load stop
365 // 8. Renderer navigates to empty.html, and finishes loading, counting as the
366 // third load stop
[email protected]4ad5d77d2011-12-03 02:00:48367 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
368 browser(), base_url.Resolve("path1/redirect.html"), 3);
[email protected]faf407b2011-01-05 01:24:32369
370 // 3 tabs, including the initial about:blank. The last 2 should be the same
371 // process.
372 ASSERT_EQ(3, browser()->tab_count());
[email protected]089e8c332011-01-06 21:37:29373 EXPECT_EQ("/files/extensions/api_test/app_process/path1/empty.html",
374 browser()->GetTabContentsAt(2)->controller().
375 GetLastCommittedEntry()->url().path());
[email protected]4ad5d77d2011-12-03 02:00:48376 EXPECT_EQ(browser()->GetTabContentsAt(1)->render_view_host()->process(),
[email protected]faf407b2011-01-05 01:24:32377 browser()->GetTabContentsAt(2)->render_view_host()->process());
378}
[email protected]d292d8a2011-05-25 03:47:11379
380// Ensure that reloading a URL after installing or uninstalling it as an app
381// correctly swaps the process. (http://crbug.com/80621)
[email protected]95df17a2011-11-03 23:03:06382// Disabled until we get a correct fix for 80621. See http://crbug.com/102408.
383IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_ReloadIntoAppProcess) {
[email protected]d292d8a2011-05-25 03:47:11384 CommandLine::ForCurrentProcess()->AppendSwitch(
385 switches::kDisablePopupBlocking);
386
[email protected]6f371442011-11-09 06:45:46387 extensions::ProcessMap* process_map =
388 browser()->profile()->GetExtensionService()->process_map();
[email protected]718eab62011-10-05 21:16:52389
[email protected]d292d8a2011-05-25 03:47:11390 host_resolver()->AddRule("*", "127.0.0.1");
391 ASSERT_TRUE(test_server()->Start());
392
393 // The app under test acts on URLs whose host is "localhost",
394 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53395 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11396
397 // Load an app URL before loading the app.
398 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
399 TabContents* contents = browser()->GetTabContentsAt(0);
[email protected]6f371442011-11-09 06:45:46400 EXPECT_FALSE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30401 contents->render_view_host()->process()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11402
[email protected]8d3132f62011-10-12 07:13:42403 // Load app and navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11404 const Extension* app =
405 LoadExtension(test_data_dir_.AppendASCII("app_process"));
406 ASSERT_TRUE(app);
407 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]6f371442011-11-09 06:45:46408 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30409 contents->render_view_host()->process()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11410
[email protected]8d3132f62011-10-12 07:13:42411 // Disable app and navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11412 DisableExtension(app->id());
413 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]6f371442011-11-09 06:45:46414 EXPECT_FALSE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30415 contents->render_view_host()->process()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11416
[email protected]8d3132f62011-10-12 07:13:42417 // Enable app and reload the page.
418 EnableExtension(app->id());
419 ui_test_utils::WindowedNotificationObserver reload_observer(
420 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53421 content::Source<NavigationController>(
[email protected]4a63e242011-12-12 15:23:08422 &browser()->GetSelectedTabContentsWrapper()->tab_contents()->
423 controller()));
[email protected]8d3132f62011-10-12 07:13:42424 browser()->Reload(CURRENT_TAB);
425 reload_observer.Wait();
[email protected]6f371442011-11-09 06:45:46426 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30427 contents->render_view_host()->process()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42428
429 // Disable app and reload the page.
430 DisableExtension(app->id());
431 ui_test_utils::WindowedNotificationObserver reload_observer2(
432 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53433 content::Source<NavigationController>(
[email protected]4a63e242011-12-12 15:23:08434 &browser()->GetSelectedTabContentsWrapper()->tab_contents()->
435 controller()));
[email protected]8d3132f62011-10-12 07:13:42436 browser()->Reload(CURRENT_TAB);
437 reload_observer2.Wait();
[email protected]6f371442011-11-09 06:45:46438 EXPECT_FALSE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30439 contents->render_view_host()->process()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42440
[email protected]d292d8a2011-05-25 03:47:11441 // Enable app and reload via JavaScript.
442 EnableExtension(app->id());
[email protected]8d3132f62011-10-12 07:13:42443 ui_test_utils::WindowedNotificationObserver js_reload_observer(
444 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53445 content::Source<NavigationController>(
[email protected]4a63e242011-12-12 15:23:08446 &browser()->GetSelectedTabContentsWrapper()->tab_contents()->
447 controller()));
[email protected]d292d8a2011-05-25 03:47:11448 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
449 L"", L"location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42450 js_reload_observer.Wait();
[email protected]6f371442011-11-09 06:45:46451 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30452 contents->render_view_host()->process()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11453
454 // Disable app and reload via JavaScript.
455 DisableExtension(app->id());
[email protected]8d3132f62011-10-12 07:13:42456 ui_test_utils::WindowedNotificationObserver js_reload_observer2(
457 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53458 content::Source<NavigationController>(
[email protected]4a63e242011-12-12 15:23:08459 &browser()->GetSelectedTabContentsWrapper()->tab_contents()->
460 controller()));
[email protected]d292d8a2011-05-25 03:47:11461 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
462 L"", L"location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42463 js_reload_observer2.Wait();
[email protected]6f371442011-11-09 06:45:46464 EXPECT_FALSE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30465 contents->render_view_host()->process()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11466}
[email protected]118d3122011-08-10 17:09:53467
[email protected]118d3122011-08-10 17:09:53468// Tests that if we have a non-app process (path3/container.html) that has an
469// iframe with a URL in the app's extent (path1/iframe.html), then opening a
470// link from that iframe to a new window to a URL in the app's extent (path1/
471// empty.html) results in the new window being in an app process. See
472// http://crbug.com/89272 for more details.
473IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
474 CommandLine::ForCurrentProcess()->AppendSwitch(
475 switches::kDisablePopupBlocking);
476
[email protected]6f371442011-11-09 06:45:46477 extensions::ProcessMap* process_map =
478 browser()->profile()->GetExtensionService()->process_map();
[email protected]718eab62011-10-05 21:16:52479
[email protected]118d3122011-08-10 17:09:53480 host_resolver()->AddRule("*", "127.0.0.1");
481 ASSERT_TRUE(test_server()->Start());
482
483 GURL base_url = GetTestBaseURL("app_process");
484
485 // Load app and start URL (not in the app).
486 const Extension* app =
487 LoadExtension(test_data_dir_.AppendASCII("app_process"));
488 ASSERT_TRUE(app);
489 ui_test_utils::NavigateToURLWithDisposition(
490 browser(),
491 base_url.Resolve("path3/container.html"),
492 CURRENT_TAB,
493 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
494 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]6f371442011-11-09 06:45:46495 EXPECT_FALSE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30496 browser()->GetTabContentsAt(0)->render_view_host()->process()->GetID()));
[email protected]118d3122011-08-10 17:09:53497
498 // Wait for popup window to appear.
499 GURL app_url = base_url.Resolve("path1/empty.html");
500 Browser* last_active_browser = BrowserList::GetLastActive();
501 EXPECT_TRUE(last_active_browser);
502 ASSERT_NE(browser(), last_active_browser);
503 TabContents* newtab = last_active_browser->GetSelectedTabContents();
504 EXPECT_TRUE(newtab);
505 if (!newtab->controller().GetLastCommittedEntry() ||
[email protected]160f17f12011-10-19 00:40:00506 newtab->controller().GetLastCommittedEntry()->url() != app_url) {
507 // TODO(gbillock): This still looks racy. Need to make a custom
508 // observer to intercept new window creation and then look for
509 // NAV_ENTRY_COMMITTED on the new tab there.
510 ui_test_utils::WindowedNotificationObserver observer(
511 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
[email protected]86ab86b2011-10-19 03:07:55512 content::Source<NavigationController>(&(newtab->controller())));
[email protected]160f17f12011-10-19 00:40:00513 observer.Wait();
514 }
[email protected]118d3122011-08-10 17:09:53515
516 // Popup window should be in the app's process.
[email protected]6f371442011-11-09 06:45:46517 EXPECT_TRUE(process_map->Contains(
[email protected]718eab62011-10-05 21:16:52518 last_active_browser->GetTabContentsAt(0)->render_view_host()->process()->
[email protected]f3b1a082011-11-18 00:34:30519 GetID()));
[email protected]118d3122011-08-10 17:09:53520}
[email protected]a09add52011-08-12 03:59:23521
[email protected]d55c2382011-08-18 23:10:36522// Tests that if we have an app process (path1/container.html) with a non-app
523// iframe (path3/iframe.html), then opening a link from that iframe to a new
524// window to a same-origin non-app URL (path3/empty.html) should keep the window
525// in the app process.
526// This is in contrast to OpenAppFromIframe, since here the popup will not be
527// missing special permissions and should be scriptable from the iframe.
528// See http://crbug.com/92669 for more details.
529IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
530 CommandLine::ForCurrentProcess()->AppendSwitch(
531 switches::kDisablePopupBlocking);
532
[email protected]6f371442011-11-09 06:45:46533 extensions::ProcessMap* process_map =
534 browser()->profile()->GetExtensionService()->process_map();
[email protected]718eab62011-10-05 21:16:52535
[email protected]d55c2382011-08-18 23:10:36536 host_resolver()->AddRule("*", "127.0.0.1");
537 ASSERT_TRUE(test_server()->Start());
538
539 GURL base_url = GetTestBaseURL("app_process");
540
541 // Load app and start URL (in the app).
542 const Extension* app =
543 LoadExtension(test_data_dir_.AppendASCII("app_process"));
544 ASSERT_TRUE(app);
[email protected]160f17f12011-10-19 00:40:00545 ui_test_utils::WindowedNotificationObserver observer(
546 content::NOTIFICATION_LOAD_STOP,
[email protected]ad50def52011-10-19 23:17:07547 content::NotificationService::AllSources());
[email protected]d55c2382011-08-18 23:10:36548 ui_test_utils::NavigateToURLWithDisposition(
549 browser(),
550 base_url.Resolve("path1/container.html"),
551 CURRENT_TAB,
552 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
553 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]f3b1a082011-11-18 00:34:30554 content::RenderProcessHost* process =
[email protected]d55c2382011-08-18 23:10:36555 browser()->GetTabContentsAt(0)->render_view_host()->process();
[email protected]f3b1a082011-11-18 00:34:30556 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36557
558 // Wait for popup window to appear. The new Browser may not have been
559 // added with SetLastActive, in which case we need to show it first.
560 // This is necessary for popup windows without a cross-site transition.
561 if (browser() == BrowserList::GetLastActive()) {
562 // Grab the second window and show it.
563 ASSERT_TRUE(BrowserList::size() == 2);
564 Browser* popup_browser = *(++BrowserList::begin());
565 popup_browser->window()->Show();
566 }
567 Browser* last_active_browser = BrowserList::GetLastActive();
568 EXPECT_TRUE(last_active_browser);
569 ASSERT_NE(browser(), last_active_browser);
570 TabContents* newtab = last_active_browser->GetSelectedTabContents();
571 EXPECT_TRUE(newtab);
572 GURL non_app_url = base_url.Resolve("path3/empty.html");
[email protected]160f17f12011-10-19 00:40:00573 observer.Wait();
[email protected]d55c2382011-08-18 23:10:36574
575 // Popup window should be in the app's process.
[email protected]f3b1a082011-11-18 00:34:30576 content::RenderProcessHost* popup_process =
[email protected]d55c2382011-08-18 23:10:36577 last_active_browser->GetTabContentsAt(0)->render_view_host()->process();
578 EXPECT_EQ(process, popup_process);
579}
580
[email protected]a09add52011-08-12 03:59:23581IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadAppAfterCrash) {
[email protected]6f371442011-11-09 06:45:46582 extensions::ProcessMap* process_map =
583 browser()->profile()->GetExtensionService()->process_map();
584
[email protected]a09add52011-08-12 03:59:23585 host_resolver()->AddRule("*", "127.0.0.1");
586 ASSERT_TRUE(test_server()->Start());
587
588 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
589
590 GURL base_url = GetTestBaseURL("app_process");
591
592 // Load the app, chrome.app.isInstalled should be true.
593 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
594 TabContents* contents = browser()->GetTabContentsAt(0);
[email protected]6f371442011-11-09 06:45:46595 EXPECT_TRUE(process_map->Contains(
[email protected]f3b1a082011-11-18 00:34:30596 contents->render_view_host()->process()->GetID()));
[email protected]a09add52011-08-12 03:59:23597 bool is_installed = false;
598 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
599 contents->render_view_host(), L"",
600 L"window.domAutomationController.send(chrome.app.isInstalled)",
601 &is_installed));
602 ASSERT_TRUE(is_installed);
603
604 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
605 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]ae673742011-08-24 19:48:37606 ui_test_utils::WindowedNotificationObserver observer(
607 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53608 content::Source<NavigationController>(
[email protected]4a63e242011-12-12 15:23:08609 &browser()->GetSelectedTabContentsWrapper()->tab_contents()->
610 controller()));
[email protected]a09add52011-08-12 03:59:23611 browser()->Reload(CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37612 observer.Wait();
[email protected]a09add52011-08-12 03:59:23613 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
614 contents->render_view_host(), L"",
615 L"window.domAutomationController.send(chrome.app.isInstalled)",
616 &is_installed));
617 ASSERT_TRUE(is_installed);
618}