blob: 4382c4db875ef20b9b47e6b51d5e71957d2c5b5f [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"
8#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]8ecad5e2010-12-02 21:18:339#include "chrome/browser/profiles/profile.h"
[email protected]7b5dc002010-11-16 23:08:1010#include "chrome/browser/ui/browser.h"
[email protected]71b73f02011-04-06 15:57:2911#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3612#include "chrome/browser/ui/browser_window.h"
[email protected]ae673742011-08-24 19:48:3713#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]3a8eecb2010-04-22 23:56:3014#include "chrome/common/chrome_switches.h"
[email protected]814a7bf0f2011-08-13 05:30:5915#include "chrome/common/extensions/extension.h"
[email protected]af44e7fb2011-07-29 18:32:3216#include "chrome/test/base/ui_test_utils.h"
[email protected]a035dfda2011-03-02 01:01:4917#include "content/browser/renderer_host/render_view_host.h"
18#include "content/browser/tab_contents/tab_contents.h"
[email protected]ad50def52011-10-19 23:17:0719#include "content/public/browser/notification_service.h"
[email protected]3a8eecb2010-04-22 23:56:3020#include "net/base/mock_host_resolver.h"
21
22class AppApiTest : public ExtensionApiTest {
[email protected]118d3122011-08-10 17:09:5323 protected:
24 // Gets the base URL for files for a specific test, making sure that it uses
25 // "localhost" as the hostname, since that is what the extent is declared
26 // as in the test apps manifests.
27 GURL GetTestBaseURL(std::string test_directory) {
28 GURL::Replacements replace_host;
29 std::string host_str("localhost"); // must stay in scope with replace_host
30 replace_host.SetHostStr(host_str);
31 GURL base_url = test_server()->GetURL(
32 "files/extensions/api_test/" + test_directory + "/");
33 return base_url.ReplaceComponents(replace_host);
34 }
[email protected]3a8eecb2010-04-22 23:56:3035};
36
37// Simulates a page calling window.open on an URL, and waits for the navigation.
38static void WindowOpenHelper(Browser* browser,
[email protected]12ea9b272010-08-24 11:31:4039 RenderViewHost* opener_host,
40 const GURL& url,
41 bool newtab_process_should_equal_opener) {
[email protected]3114db2c2011-09-12 20:09:0542 ui_test_utils::WindowedNotificationObserver observer(
[email protected]ad50def52011-10-19 23:17:0743 content::NOTIFICATION_LOAD_STOP,
44 content::NotificationService::AllSources());
[email protected]9fabbf72010-09-30 21:50:0545 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
46 opener_host, L"", L"window.open('" + UTF8ToWide(url.spec()) + L"');"));
[email protected]3a8eecb2010-04-22 23:56:3047
[email protected]12ea9b272010-08-24 11:31:4048 // The above window.open call is not user-initiated, it will create
49 // a popup window instead of a new tab in current window.
50 // Now the active tab in last active window should be the new tab.
51 Browser* last_active_browser = BrowserList::GetLastActive();
52 EXPECT_TRUE(last_active_browser);
53 TabContents* newtab = last_active_browser->GetSelectedTabContents();
54 EXPECT_TRUE(newtab);
[email protected]3114db2c2011-09-12 20:09:0555 observer.Wait();
[email protected]3a8eecb2010-04-22 23:56:3056 EXPECT_EQ(url, newtab->controller().GetLastCommittedEntry()->url());
[email protected]12ea9b272010-08-24 11:31:4057 if (newtab_process_should_equal_opener)
58 EXPECT_EQ(opener_host->process(), newtab->render_view_host()->process());
59 else
60 EXPECT_NE(opener_host->process(), newtab->render_view_host()->process());
[email protected]3a8eecb2010-04-22 23:56:3061}
62
63// Simulates a page navigating itself to an URL, and waits for the navigation.
64static void NavigateTabHelper(TabContents* contents, const GURL& url) {
65 bool result = false;
[email protected]3114db2c2011-09-12 20:09:0566 ui_test_utils::WindowedNotificationObserver observer(
67 content::NOTIFICATION_LOAD_STOP,
[email protected]ad50def52011-10-19 23:17:0768 content::NotificationService::AllSources());
[email protected]9fabbf72010-09-30 21:50:0569 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
[email protected]3a8eecb2010-04-22 23:56:3070 contents->render_view_host(), L"",
[email protected]d38f83f2010-04-30 23:25:5771 L"window.addEventListener('unload', function() {"
72 L" window.domAutomationController.send(true);"
73 L"}, false);"
74 L"window.location = '" + UTF8ToWide(url.spec()) + L"';",
[email protected]9fabbf72010-09-30 21:50:0575 &result));
[email protected]3a8eecb2010-04-22 23:56:3076 ASSERT_TRUE(result);
[email protected]3114db2c2011-09-12 20:09:0577 observer.Wait();
[email protected]3a8eecb2010-04-22 23:56:3078 EXPECT_EQ(url, contents->controller().GetLastCommittedEntry()->url());
79}
80
[email protected]9b600832011-10-26 20:31:5981#if defined(OS_WIN)
82// AppProcess sometimes hangs on Windows
83// http://crbug.com/88316
84#define MAYBE_AppProcess DISABLED_AppProcess
85#else
86#define MAYBE_AppProcess AppProcess
87#endif
88
89IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcess) {
[email protected]12ea9b272010-08-24 11:31:4090 CommandLine::ForCurrentProcess()->AppendSwitch(
91 switches::kDisablePopupBlocking);
92
[email protected]718eab62011-10-05 21:16:5293 ExtensionProcessManager* extension_process_manager =
94 browser()->profile()->GetExtensionProcessManager();
95
[email protected]3a8eecb2010-04-22 23:56:3096 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]95409e12010-08-17 20:07:1197 ASSERT_TRUE(test_server()->Start());
[email protected]3a8eecb2010-04-22 23:56:3098
[email protected]cbf4d1912010-08-12 18:24:5799 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30100
[email protected]cbf4d1912010-08-12 18:24:57101 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53102 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59103
[email protected]f0e13332011-05-20 22:41:14104 // Test both opening a URL in a new tab, and opening a tab and then navigating
105 // it. Either way, app tabs should be considered extension processes, but
106 // they have no elevated privileges and thus should not have WebUI bindings.
107 ui_test_utils::NavigateToURLWithDisposition(
108 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
109 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]718eab62011-10-05 21:16:52110 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
111 browser()->GetTabContentsAt(1)->render_view_host()->process()->id()));
[email protected]f0e13332011-05-20 22:41:14112 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
[email protected]9b600832011-10-26 20:31:59113 browser()->NewTab();
114 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
[email protected]718eab62011-10-05 21:16:52115 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
116 browser()->GetTabContentsAt(2)->render_view_host()->process()->id()));
[email protected]f0e13332011-05-20 22:41:14117 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
[email protected]cbf4d1912010-08-12 18:24:57118 browser()->NewTab();
119 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]718eab62011-10-05 21:16:52120 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
121 browser()->GetTabContentsAt(3)->render_view_host()->process()->id()));
[email protected]f0e13332011-05-20 22:41:14122 EXPECT_FALSE(browser()->GetTabContentsAt(3)->web_ui());
[email protected]3a8eecb2010-04-22 23:56:30123
[email protected]056ad2a2011-07-12 02:13:55124 // We should have opened 3 new extension tabs. Including the original blank
125 // tab, we now have 4 tabs. Because the app_process app has the background
126 // permission, all of its instances are in the same process. Thus two tabs
127 // should be part of the extension app and grouped in the same process.
[email protected]3a8eecb2010-04-22 23:56:30128 ASSERT_EQ(4, browser()->tab_count());
[email protected]cbf4d1912010-08-12 18:24:57129 RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host();
[email protected]cbf4d1912010-08-12 18:24:57130
131 EXPECT_EQ(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30132 browser()->GetTabContentsAt(2)->render_view_host()->process());
[email protected]cbf4d1912010-08-12 18:24:57133 EXPECT_NE(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30134 browser()->GetTabContentsAt(3)->render_view_host()->process());
135
136 // Now let's do the same using window.open. The same should happen.
[email protected]12ea9b272010-08-24 11:31:40137 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
[email protected]cbf4d1912010-08-12 18:24:57138 WindowOpenHelper(browser(), host,
[email protected]12ea9b272010-08-24 11:31:40139 base_url.Resolve("path1/empty.html"), true);
[email protected]cbf4d1912010-08-12 18:24:57140 WindowOpenHelper(browser(), host,
[email protected]12ea9b272010-08-24 11:31:40141 base_url.Resolve("path2/empty.html"), true);
[email protected]361a5f1f2011-10-05 20:11:15142 // TODO(creis): This should open in a new process (i.e., false for the last
143 // argument), but we temporarily avoid swapping processes away from an app
144 // until we're able to support cross-process postMessage calls.
145 // See crbug.com/59285.
[email protected]cbf4d1912010-08-12 18:24:57146 WindowOpenHelper(browser(), host,
[email protected]361a5f1f2011-10-05 20:11:15147 base_url.Resolve("path3/empty.html"), true);
[email protected]3a8eecb2010-04-22 23:56:30148
149 // Now let's have these pages navigate, into or out of the extension web
150 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36151 const GURL& app_url(base_url.Resolve("path1/empty.html"));
152 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]cbf4d1912010-08-12 18:24:57153 NavigateTabHelper(browser()->GetTabContentsAt(2), non_app_url);
[email protected]3a8eecb2010-04-22 23:56:30154 NavigateTabHelper(browser()->GetTabContentsAt(3), app_url);
[email protected]361a5f1f2011-10-05 20:11:15155 // TODO(creis): This should swap out of the app's process (i.e., EXPECT_NE),
156 // but we temporarily avoid swapping away from an app in case the window
157 // tries to send a postMessage to the app. See crbug.com/59285.
158 EXPECT_EQ(host->process(),
[email protected]cbf4d1912010-08-12 18:24:57159 browser()->GetTabContentsAt(2)->render_view_host()->process());
160 EXPECT_EQ(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30161 browser()->GetTabContentsAt(3)->render_view_host()->process());
[email protected]08e94b82010-12-15 22:51:04162
163 // If one of the popup tabs navigates back to the app, window.opener should
164 // be valid.
165 NavigateTabHelper(browser()->GetTabContentsAt(6), app_url);
166 EXPECT_EQ(host->process(),
167 browser()->GetTabContentsAt(6)->render_view_host()->process());
168 bool windowOpenerValid = false;
169 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
170 browser()->GetTabContentsAt(6)->render_view_host(), L"",
171 L"window.domAutomationController.send(window.opener != null)",
172 &windowOpenerValid));
173 ASSERT_TRUE(windowOpenerValid);
[email protected]3a8eecb2010-04-22 23:56:30174}
[email protected]faf407b2011-01-05 01:24:32175
[email protected]9b600832011-10-26 20:31:59176
177#if defined(OS_WIN)
178// Seems to timeout sometimes on Windows: http://crbug.com/89766
179#define MAYBE_AppProcessInstances FLAKY_AppProcessInstances
180#else
181#define MAYBE_AppProcessInstances AppProcessInstances
182#endif
183
[email protected]056ad2a2011-07-12 02:13:55184// Test that hosted apps without the background permission use a process per app
185// instance model, such that separate instances are in separate processes.
[email protected]9b600832011-10-26 20:31:59186IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]056ad2a2011-07-12 02:13:55187 CommandLine::ForCurrentProcess()->AppendSwitch(
188 switches::kDisablePopupBlocking);
189
[email protected]718eab62011-10-05 21:16:52190 ExtensionProcessManager* extension_process_manager =
191 browser()->profile()->GetExtensionProcessManager();
192
[email protected]056ad2a2011-07-12 02:13:55193 host_resolver()->AddRule("*", "127.0.0.1");
194 ASSERT_TRUE(test_server()->Start());
195
196 ASSERT_TRUE(LoadExtension(
197 test_data_dir_.AppendASCII("app_process_instances")));
198
199 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53200 GURL base_url = GetTestBaseURL("app_process_instances");
[email protected]056ad2a2011-07-12 02:13:55201
202 // Test both opening a URL in a new tab, and opening a tab and then navigating
203 // it. Either way, app tabs should be considered extension processes, but
204 // they have no elevated privileges and thus should not have WebUI bindings.
205 ui_test_utils::NavigateToURLWithDisposition(
206 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
207 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]718eab62011-10-05 21:16:52208 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
209 browser()->GetTabContentsAt(1)->render_view_host()->process()->id()));
[email protected]056ad2a2011-07-12 02:13:55210 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
211 browser()->NewTab();
212 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
[email protected]718eab62011-10-05 21:16:52213 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
214 browser()->GetTabContentsAt(2)->render_view_host()->process()->id()));
[email protected]056ad2a2011-07-12 02:13:55215 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
216
217 // We should have opened 2 new extension tabs. Including the original blank
218 // tab, we now have 3 tabs. The two app tabs should not be in the same
219 // process, since they do not have the background permission. (Thus, we want
220 // to separate them to improve responsiveness.)
221 ASSERT_EQ(3, browser()->tab_count());
222 RenderViewHost* host1 = browser()->GetTabContentsAt(1)->render_view_host();
223 RenderViewHost* host2 = browser()->GetTabContentsAt(2)->render_view_host();
224 EXPECT_NE(host1->process(), host2->process());
225
226 // Opening tabs with window.open should keep the page in the opener's process.
227 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
228 WindowOpenHelper(browser(), host1,
229 base_url.Resolve("path1/empty.html"), true);
230 WindowOpenHelper(browser(), host2,
231 base_url.Resolve("path2/empty.html"), true);
232}
233
[email protected]faf407b2011-01-05 01:24:32234// Tests that app process switching works properly in the following scenario:
235// 1. navigate to a page1 in the app
236// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
237// 3. page2 redirects back to a page in the app
238// The final navigation should end up in the app process.
239// See http://crbug.com/61757
240IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessRedirectBack) {
241 CommandLine::ForCurrentProcess()->AppendSwitch(
242 switches::kDisablePopupBlocking);
243
244 host_resolver()->AddRule("*", "127.0.0.1");
245 ASSERT_TRUE(test_server()->Start());
246
247 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
248
249 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53250 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32251
252 browser()->NewTab();
253 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
254 browser()->NewTab();
[email protected]faf407b2011-01-05 01:24:32255 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]089e8c332011-01-06 21:37:29256 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
257 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32258
259 // 3 tabs, including the initial about:blank. The last 2 should be the same
260 // process.
261 ASSERT_EQ(3, browser()->tab_count());
[email protected]089e8c332011-01-06 21:37:29262 EXPECT_EQ("/files/extensions/api_test/app_process/path1/empty.html",
263 browser()->GetTabContentsAt(2)->controller().
264 GetLastCommittedEntry()->url().path());
[email protected]faf407b2011-01-05 01:24:32265 RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host();
266 EXPECT_EQ(host->process(),
267 browser()->GetTabContentsAt(2)->render_view_host()->process());
268}
[email protected]d292d8a2011-05-25 03:47:11269
270// Ensure that reloading a URL after installing or uninstalling it as an app
271// correctly swaps the process. (http://crbug.com/80621)
272IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
273 CommandLine::ForCurrentProcess()->AppendSwitch(
274 switches::kDisablePopupBlocking);
275
[email protected]718eab62011-10-05 21:16:52276 ExtensionProcessManager* extension_process_manager =
277 browser()->profile()->GetExtensionProcessManager();
278
[email protected]d292d8a2011-05-25 03:47:11279 host_resolver()->AddRule("*", "127.0.0.1");
280 ASSERT_TRUE(test_server()->Start());
281
282 // The app under test acts on URLs whose host is "localhost",
283 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53284 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11285
286 // Load an app URL before loading the app.
287 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
288 TabContents* contents = browser()->GetTabContentsAt(0);
[email protected]718eab62011-10-05 21:16:52289 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
290 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11291
[email protected]8d3132f62011-10-12 07:13:42292 // Load app and navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11293 const Extension* app =
294 LoadExtension(test_data_dir_.AppendASCII("app_process"));
295 ASSERT_TRUE(app);
296 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]718eab62011-10-05 21:16:52297 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
298 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11299
[email protected]8d3132f62011-10-12 07:13:42300 // Disable app and navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11301 DisableExtension(app->id());
302 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]718eab62011-10-05 21:16:52303 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
304 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11305
[email protected]8d3132f62011-10-12 07:13:42306 // Enable app and reload the page.
307 EnableExtension(app->id());
308 ui_test_utils::WindowedNotificationObserver reload_observer(
309 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53310 content::Source<NavigationController>(
[email protected]8d3132f62011-10-12 07:13:42311 &browser()->GetSelectedTabContentsWrapper()->controller()));
312 browser()->Reload(CURRENT_TAB);
313 reload_observer.Wait();
314 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
315 contents->render_view_host()->process()->id()));
316
317 // Disable app and reload the page.
318 DisableExtension(app->id());
319 ui_test_utils::WindowedNotificationObserver reload_observer2(
320 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53321 content::Source<NavigationController>(
[email protected]8d3132f62011-10-12 07:13:42322 &browser()->GetSelectedTabContentsWrapper()->controller()));
323 browser()->Reload(CURRENT_TAB);
324 reload_observer2.Wait();
325 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
326 contents->render_view_host()->process()->id()));
327
[email protected]d292d8a2011-05-25 03:47:11328 // Enable app and reload via JavaScript.
329 EnableExtension(app->id());
[email protected]8d3132f62011-10-12 07:13:42330 ui_test_utils::WindowedNotificationObserver js_reload_observer(
331 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53332 content::Source<NavigationController>(
[email protected]8d3132f62011-10-12 07:13:42333 &browser()->GetSelectedTabContentsWrapper()->controller()));
[email protected]d292d8a2011-05-25 03:47:11334 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
335 L"", L"location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42336 js_reload_observer.Wait();
[email protected]718eab62011-10-05 21:16:52337 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
338 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11339
340 // Disable app and reload via JavaScript.
341 DisableExtension(app->id());
[email protected]8d3132f62011-10-12 07:13:42342 ui_test_utils::WindowedNotificationObserver js_reload_observer2(
343 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53344 content::Source<NavigationController>(
[email protected]8d3132f62011-10-12 07:13:42345 &browser()->GetSelectedTabContentsWrapper()->controller()));
[email protected]d292d8a2011-05-25 03:47:11346 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
347 L"", L"location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42348 js_reload_observer2.Wait();
[email protected]718eab62011-10-05 21:16:52349 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
350 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11351}
[email protected]118d3122011-08-10 17:09:53352
353
354// Tests that if we have a non-app process (path3/container.html) that has an
355// iframe with a URL in the app's extent (path1/iframe.html), then opening a
356// link from that iframe to a new window to a URL in the app's extent (path1/
357// empty.html) results in the new window being in an app process. See
358// http://crbug.com/89272 for more details.
359IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
360 CommandLine::ForCurrentProcess()->AppendSwitch(
361 switches::kDisablePopupBlocking);
362
[email protected]718eab62011-10-05 21:16:52363 ExtensionProcessManager* extension_process_manager =
364 browser()->profile()->GetExtensionProcessManager();
365
[email protected]118d3122011-08-10 17:09:53366 host_resolver()->AddRule("*", "127.0.0.1");
367 ASSERT_TRUE(test_server()->Start());
368
369 GURL base_url = GetTestBaseURL("app_process");
370
371 // Load app and start URL (not in the app).
372 const Extension* app =
373 LoadExtension(test_data_dir_.AppendASCII("app_process"));
374 ASSERT_TRUE(app);
375 ui_test_utils::NavigateToURLWithDisposition(
376 browser(),
377 base_url.Resolve("path3/container.html"),
378 CURRENT_TAB,
379 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
380 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]718eab62011-10-05 21:16:52381 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
382 browser()->GetTabContentsAt(0)->render_view_host()->process()->id()));
[email protected]118d3122011-08-10 17:09:53383
384 // Wait for popup window to appear.
385 GURL app_url = base_url.Resolve("path1/empty.html");
386 Browser* last_active_browser = BrowserList::GetLastActive();
387 EXPECT_TRUE(last_active_browser);
388 ASSERT_NE(browser(), last_active_browser);
389 TabContents* newtab = last_active_browser->GetSelectedTabContents();
390 EXPECT_TRUE(newtab);
391 if (!newtab->controller().GetLastCommittedEntry() ||
[email protected]160f17f12011-10-19 00:40:00392 newtab->controller().GetLastCommittedEntry()->url() != app_url) {
393 // TODO(gbillock): This still looks racy. Need to make a custom
394 // observer to intercept new window creation and then look for
395 // NAV_ENTRY_COMMITTED on the new tab there.
396 ui_test_utils::WindowedNotificationObserver observer(
397 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
[email protected]86ab86b2011-10-19 03:07:55398 content::Source<NavigationController>(&(newtab->controller())));
[email protected]160f17f12011-10-19 00:40:00399 observer.Wait();
400 }
[email protected]118d3122011-08-10 17:09:53401
402 // Popup window should be in the app's process.
[email protected]718eab62011-10-05 21:16:52403 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
404 last_active_browser->GetTabContentsAt(0)->render_view_host()->process()->
405 id()));
[email protected]118d3122011-08-10 17:09:53406}
[email protected]a09add52011-08-12 03:59:23407
[email protected]d55c2382011-08-18 23:10:36408// Tests that if we have an app process (path1/container.html) with a non-app
409// iframe (path3/iframe.html), then opening a link from that iframe to a new
410// window to a same-origin non-app URL (path3/empty.html) should keep the window
411// in the app process.
412// This is in contrast to OpenAppFromIframe, since here the popup will not be
413// missing special permissions and should be scriptable from the iframe.
414// See http://crbug.com/92669 for more details.
415IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
416 CommandLine::ForCurrentProcess()->AppendSwitch(
417 switches::kDisablePopupBlocking);
418
[email protected]718eab62011-10-05 21:16:52419 ExtensionProcessManager* extension_process_manager =
420 browser()->profile()->GetExtensionProcessManager();
421
[email protected]d55c2382011-08-18 23:10:36422 host_resolver()->AddRule("*", "127.0.0.1");
423 ASSERT_TRUE(test_server()->Start());
424
425 GURL base_url = GetTestBaseURL("app_process");
426
427 // Load app and start URL (in the app).
428 const Extension* app =
429 LoadExtension(test_data_dir_.AppendASCII("app_process"));
430 ASSERT_TRUE(app);
[email protected]160f17f12011-10-19 00:40:00431 ui_test_utils::WindowedNotificationObserver observer(
432 content::NOTIFICATION_LOAD_STOP,
[email protected]ad50def52011-10-19 23:17:07433 content::NotificationService::AllSources());
[email protected]d55c2382011-08-18 23:10:36434 ui_test_utils::NavigateToURLWithDisposition(
435 browser(),
436 base_url.Resolve("path1/container.html"),
437 CURRENT_TAB,
438 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
439 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
440 RenderProcessHost* process =
441 browser()->GetTabContentsAt(0)->render_view_host()->process();
[email protected]718eab62011-10-05 21:16:52442 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
443 process->id()));
[email protected]d55c2382011-08-18 23:10:36444
445 // Wait for popup window to appear. The new Browser may not have been
446 // added with SetLastActive, in which case we need to show it first.
447 // This is necessary for popup windows without a cross-site transition.
448 if (browser() == BrowserList::GetLastActive()) {
449 // Grab the second window and show it.
450 ASSERT_TRUE(BrowserList::size() == 2);
451 Browser* popup_browser = *(++BrowserList::begin());
452 popup_browser->window()->Show();
453 }
454 Browser* last_active_browser = BrowserList::GetLastActive();
455 EXPECT_TRUE(last_active_browser);
456 ASSERT_NE(browser(), last_active_browser);
457 TabContents* newtab = last_active_browser->GetSelectedTabContents();
458 EXPECT_TRUE(newtab);
459 GURL non_app_url = base_url.Resolve("path3/empty.html");
[email protected]160f17f12011-10-19 00:40:00460 observer.Wait();
[email protected]d55c2382011-08-18 23:10:36461
462 // Popup window should be in the app's process.
463 RenderProcessHost* popup_process =
464 last_active_browser->GetTabContentsAt(0)->render_view_host()->process();
465 EXPECT_EQ(process, popup_process);
466}
467
[email protected]a09add52011-08-12 03:59:23468IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadAppAfterCrash) {
[email protected]718eab62011-10-05 21:16:52469 ExtensionProcessManager* extension_process_manager =
470 browser()->profile()->GetExtensionProcessManager();
[email protected]a09add52011-08-12 03:59:23471 host_resolver()->AddRule("*", "127.0.0.1");
472 ASSERT_TRUE(test_server()->Start());
473
474 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
475
476 GURL base_url = GetTestBaseURL("app_process");
477
478 // Load the app, chrome.app.isInstalled should be true.
479 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
480 TabContents* contents = browser()->GetTabContentsAt(0);
[email protected]718eab62011-10-05 21:16:52481 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
482 contents->render_view_host()->process()->id()));
[email protected]a09add52011-08-12 03:59:23483 bool is_installed = false;
484 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
485 contents->render_view_host(), L"",
486 L"window.domAutomationController.send(chrome.app.isInstalled)",
487 &is_installed));
488 ASSERT_TRUE(is_installed);
489
490 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
491 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]ae673742011-08-24 19:48:37492 ui_test_utils::WindowedNotificationObserver observer(
493 content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53494 content::Source<NavigationController>(
[email protected]ae673742011-08-24 19:48:37495 &browser()->GetSelectedTabContentsWrapper()->controller()));
[email protected]a09add52011-08-12 03:59:23496 browser()->Reload(CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37497 observer.Wait();
[email protected]a09add52011-08-12 03:59:23498 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
499 contents->render_view_host(), L"",
500 L"window.domAutomationController.send(chrome.app.isInstalled)",
501 &is_installed));
502 ASSERT_TRUE(is_installed);
503}