blob: 33f8fcc91c467e03c16d1d2bd99dbe6e4e1f8a49 [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]3a8eecb2010-04-22 23:56:3019#include "net/base/mock_host_resolver.h"
20
21class AppApiTest : public ExtensionApiTest {
[email protected]118d3122011-08-10 17:09:5322 protected:
23 // Gets the base URL for files for a specific test, making sure that it uses
24 // "localhost" as the hostname, since that is what the extent is declared
25 // as in the test apps manifests.
26 GURL GetTestBaseURL(std::string test_directory) {
27 GURL::Replacements replace_host;
28 std::string host_str("localhost"); // must stay in scope with replace_host
29 replace_host.SetHostStr(host_str);
30 GURL base_url = test_server()->GetURL(
31 "files/extensions/api_test/" + test_directory + "/");
32 return base_url.ReplaceComponents(replace_host);
33 }
[email protected]3a8eecb2010-04-22 23:56:3034};
35
36// Simulates a page calling window.open on an URL, and waits for the navigation.
37static void WindowOpenHelper(Browser* browser,
[email protected]12ea9b272010-08-24 11:31:4038 RenderViewHost* opener_host,
39 const GURL& url,
40 bool newtab_process_should_equal_opener) {
[email protected]3114db2c2011-09-12 20:09:0541 ui_test_utils::WindowedNotificationObserver observer(
42 content::NOTIFICATION_LOAD_STOP, NotificationService::AllSources());
[email protected]9fabbf72010-09-30 21:50:0543 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
44 opener_host, L"", L"window.open('" + UTF8ToWide(url.spec()) + L"');"));
[email protected]3a8eecb2010-04-22 23:56:3045
[email protected]12ea9b272010-08-24 11:31:4046 // The above window.open call is not user-initiated, it will create
47 // a popup window instead of a new tab in current window.
48 // Now the active tab in last active window should be the new tab.
49 Browser* last_active_browser = BrowserList::GetLastActive();
50 EXPECT_TRUE(last_active_browser);
51 TabContents* newtab = last_active_browser->GetSelectedTabContents();
52 EXPECT_TRUE(newtab);
[email protected]3114db2c2011-09-12 20:09:0553 observer.Wait();
[email protected]3a8eecb2010-04-22 23:56:3054 EXPECT_EQ(url, newtab->controller().GetLastCommittedEntry()->url());
[email protected]12ea9b272010-08-24 11:31:4055 if (newtab_process_should_equal_opener)
56 EXPECT_EQ(opener_host->process(), newtab->render_view_host()->process());
57 else
58 EXPECT_NE(opener_host->process(), newtab->render_view_host()->process());
[email protected]3a8eecb2010-04-22 23:56:3059}
60
61// Simulates a page navigating itself to an URL, and waits for the navigation.
62static void NavigateTabHelper(TabContents* contents, const GURL& url) {
63 bool result = false;
[email protected]3114db2c2011-09-12 20:09:0564 ui_test_utils::WindowedNotificationObserver observer(
65 content::NOTIFICATION_LOAD_STOP,
66 NotificationService::AllSources());
[email protected]9fabbf72010-09-30 21:50:0567 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
[email protected]3a8eecb2010-04-22 23:56:3068 contents->render_view_host(), L"",
[email protected]d38f83f2010-04-30 23:25:5769 L"window.addEventListener('unload', function() {"
70 L" window.domAutomationController.send(true);"
71 L"}, false);"
72 L"window.location = '" + UTF8ToWide(url.spec()) + L"';",
[email protected]9fabbf72010-09-30 21:50:0573 &result));
[email protected]3a8eecb2010-04-22 23:56:3074 ASSERT_TRUE(result);
[email protected]3114db2c2011-09-12 20:09:0575 observer.Wait();
[email protected]3a8eecb2010-04-22 23:56:3076 EXPECT_EQ(url, contents->controller().GetLastCommittedEntry()->url());
77}
78
[email protected]d54ade62011-07-03 00:32:1379#if defined(OS_WIN)
80// AppProcess sometimes hangs on Windows
81// http://crbug.com/88316
82#define MAYBE_AppProcess DISABLED_AppProcess
83#else
84#define MAYBE_AppProcess AppProcess
85#endif
86
87IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcess) {
[email protected]12ea9b272010-08-24 11:31:4088 CommandLine::ForCurrentProcess()->AppendSwitch(
89 switches::kDisablePopupBlocking);
90
[email protected]718eab62011-10-05 21:16:5291 ExtensionProcessManager* extension_process_manager =
92 browser()->profile()->GetExtensionProcessManager();
93
[email protected]3a8eecb2010-04-22 23:56:3094 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]95409e12010-08-17 20:07:1195 ASSERT_TRUE(test_server()->Start());
[email protected]3a8eecb2010-04-22 23:56:3096
[email protected]cbf4d1912010-08-12 18:24:5797 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:3098
[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]718eab62011-10-05 21:16:52108 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
109 browser()->GetTabContentsAt(1)->render_view_host()->process()->id()));
[email protected]f0e13332011-05-20 22:41:14110 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
[email protected]cbf4d1912010-08-12 18:24:57111 browser()->NewTab();
112 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
[email protected]718eab62011-10-05 21:16:52113 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
114 browser()->GetTabContentsAt(2)->render_view_host()->process()->id()));
[email protected]f0e13332011-05-20 22:41:14115 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
[email protected]cbf4d1912010-08-12 18:24:57116 browser()->NewTab();
117 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]718eab62011-10-05 21:16:52118 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
119 browser()->GetTabContentsAt(3)->render_view_host()->process()->id()));
[email protected]f0e13332011-05-20 22:41:14120 EXPECT_FALSE(browser()->GetTabContentsAt(3)->web_ui());
[email protected]3a8eecb2010-04-22 23:56:30121
[email protected]056ad2a2011-07-12 02:13:55122 // We should have opened 3 new extension tabs. Including the original blank
123 // tab, we now have 4 tabs. Because the app_process app has the background
124 // permission, all of its instances are in the same process. Thus two tabs
125 // should be part of the extension app and grouped in the same process.
[email protected]3a8eecb2010-04-22 23:56:30126 ASSERT_EQ(4, browser()->tab_count());
[email protected]cbf4d1912010-08-12 18:24:57127 RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host();
[email protected]cbf4d1912010-08-12 18:24:57128
129 EXPECT_EQ(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30130 browser()->GetTabContentsAt(2)->render_view_host()->process());
[email protected]cbf4d1912010-08-12 18:24:57131 EXPECT_NE(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30132 browser()->GetTabContentsAt(3)->render_view_host()->process());
133
134 // Now let's do the same using window.open. The same should happen.
[email protected]12ea9b272010-08-24 11:31:40135 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
[email protected]cbf4d1912010-08-12 18:24:57136 WindowOpenHelper(browser(), host,
[email protected]12ea9b272010-08-24 11:31:40137 base_url.Resolve("path1/empty.html"), true);
[email protected]cbf4d1912010-08-12 18:24:57138 WindowOpenHelper(browser(), host,
[email protected]12ea9b272010-08-24 11:31:40139 base_url.Resolve("path2/empty.html"), true);
[email protected]361a5f1f2011-10-05 20:11:15140 // TODO(creis): This should open in a new process (i.e., false for the last
141 // argument), but we temporarily avoid swapping processes away from an app
142 // until we're able to support cross-process postMessage calls.
143 // See crbug.com/59285.
[email protected]cbf4d1912010-08-12 18:24:57144 WindowOpenHelper(browser(), host,
[email protected]361a5f1f2011-10-05 20:11:15145 base_url.Resolve("path3/empty.html"), true);
[email protected]3a8eecb2010-04-22 23:56:30146
147 // Now let's have these pages navigate, into or out of the extension web
148 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36149 const GURL& app_url(base_url.Resolve("path1/empty.html"));
150 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]cbf4d1912010-08-12 18:24:57151 NavigateTabHelper(browser()->GetTabContentsAt(2), non_app_url);
[email protected]3a8eecb2010-04-22 23:56:30152 NavigateTabHelper(browser()->GetTabContentsAt(3), app_url);
[email protected]361a5f1f2011-10-05 20:11:15153 // TODO(creis): This should swap out of the app's process (i.e., EXPECT_NE),
154 // but we temporarily avoid swapping away from an app in case the window
155 // tries to send a postMessage to the app. See crbug.com/59285.
156 EXPECT_EQ(host->process(),
[email protected]cbf4d1912010-08-12 18:24:57157 browser()->GetTabContentsAt(2)->render_view_host()->process());
158 EXPECT_EQ(host->process(),
[email protected]3a8eecb2010-04-22 23:56:30159 browser()->GetTabContentsAt(3)->render_view_host()->process());
[email protected]08e94b82010-12-15 22:51:04160
161 // If one of the popup tabs navigates back to the app, window.opener should
162 // be valid.
163 NavigateTabHelper(browser()->GetTabContentsAt(6), app_url);
164 EXPECT_EQ(host->process(),
165 browser()->GetTabContentsAt(6)->render_view_host()->process());
166 bool windowOpenerValid = false;
167 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
168 browser()->GetTabContentsAt(6)->render_view_host(), L"",
169 L"window.domAutomationController.send(window.opener != null)",
170 &windowOpenerValid));
171 ASSERT_TRUE(windowOpenerValid);
[email protected]3a8eecb2010-04-22 23:56:30172}
[email protected]faf407b2011-01-05 01:24:32173
[email protected]727db1f2011-07-19 19:35:02174
175#if defined(OS_WIN)
176// Seems to timeout sometimes on Windows: http://crbug.com/89766
177#define MAYBE_AppProcessInstances FLAKY_AppProcessInstances
178#else
179#define MAYBE_AppProcessInstances AppProcessInstances
180#endif
181
[email protected]056ad2a2011-07-12 02:13:55182// Test that hosted apps without the background permission use a process per app
183// instance model, such that separate instances are in separate processes.
[email protected]727db1f2011-07-19 19:35:02184IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
[email protected]056ad2a2011-07-12 02:13:55185 CommandLine::ForCurrentProcess()->AppendSwitch(
186 switches::kDisablePopupBlocking);
187
[email protected]718eab62011-10-05 21:16:52188 ExtensionProcessManager* extension_process_manager =
189 browser()->profile()->GetExtensionProcessManager();
190
[email protected]056ad2a2011-07-12 02:13:55191 host_resolver()->AddRule("*", "127.0.0.1");
192 ASSERT_TRUE(test_server()->Start());
193
194 ASSERT_TRUE(LoadExtension(
195 test_data_dir_.AppendASCII("app_process_instances")));
196
197 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53198 GURL base_url = GetTestBaseURL("app_process_instances");
[email protected]056ad2a2011-07-12 02:13:55199
200 // Test both opening a URL in a new tab, and opening a tab and then navigating
201 // it. Either way, app tabs should be considered extension processes, but
202 // they have no elevated privileges and thus should not have WebUI bindings.
203 ui_test_utils::NavigateToURLWithDisposition(
204 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
205 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]718eab62011-10-05 21:16:52206 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
207 browser()->GetTabContentsAt(1)->render_view_host()->process()->id()));
[email protected]056ad2a2011-07-12 02:13:55208 EXPECT_FALSE(browser()->GetTabContentsAt(1)->web_ui());
209 browser()->NewTab();
210 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
[email protected]718eab62011-10-05 21:16:52211 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
212 browser()->GetTabContentsAt(2)->render_view_host()->process()->id()));
[email protected]056ad2a2011-07-12 02:13:55213 EXPECT_FALSE(browser()->GetTabContentsAt(2)->web_ui());
214
215 // We should have opened 2 new extension tabs. Including the original blank
216 // tab, we now have 3 tabs. The two app tabs should not be in the same
217 // process, since they do not have the background permission. (Thus, we want
218 // to separate them to improve responsiveness.)
219 ASSERT_EQ(3, browser()->tab_count());
220 RenderViewHost* host1 = browser()->GetTabContentsAt(1)->render_view_host();
221 RenderViewHost* host2 = browser()->GetTabContentsAt(2)->render_view_host();
222 EXPECT_NE(host1->process(), host2->process());
223
224 // Opening tabs with window.open should keep the page in the opener's process.
225 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
226 WindowOpenHelper(browser(), host1,
227 base_url.Resolve("path1/empty.html"), true);
228 WindowOpenHelper(browser(), host2,
229 base_url.Resolve("path2/empty.html"), true);
230}
231
[email protected]faf407b2011-01-05 01:24:32232// Tests that app process switching works properly in the following scenario:
233// 1. navigate to a page1 in the app
234// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
235// 3. page2 redirects back to a page in the app
236// The final navigation should end up in the app process.
237// See http://crbug.com/61757
238IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessRedirectBack) {
239 CommandLine::ForCurrentProcess()->AppendSwitch(
240 switches::kDisablePopupBlocking);
241
242 host_resolver()->AddRule("*", "127.0.0.1");
243 ASSERT_TRUE(test_server()->Start());
244
245 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
246
247 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53248 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32249
250 browser()->NewTab();
251 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
252 browser()->NewTab();
[email protected]faf407b2011-01-05 01:24:32253 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]089e8c332011-01-06 21:37:29254 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
255 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32256
257 // 3 tabs, including the initial about:blank. The last 2 should be the same
258 // process.
259 ASSERT_EQ(3, browser()->tab_count());
[email protected]089e8c332011-01-06 21:37:29260 EXPECT_EQ("/files/extensions/api_test/app_process/path1/empty.html",
261 browser()->GetTabContentsAt(2)->controller().
262 GetLastCommittedEntry()->url().path());
[email protected]faf407b2011-01-05 01:24:32263 RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host();
264 EXPECT_EQ(host->process(),
265 browser()->GetTabContentsAt(2)->render_view_host()->process());
266}
[email protected]d292d8a2011-05-25 03:47:11267
268// Ensure that reloading a URL after installing or uninstalling it as an app
269// correctly swaps the process. (http://crbug.com/80621)
270IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
271 CommandLine::ForCurrentProcess()->AppendSwitch(
272 switches::kDisablePopupBlocking);
273
[email protected]718eab62011-10-05 21:16:52274 ExtensionProcessManager* extension_process_manager =
275 browser()->profile()->GetExtensionProcessManager();
276
[email protected]d292d8a2011-05-25 03:47:11277 host_resolver()->AddRule("*", "127.0.0.1");
278 ASSERT_TRUE(test_server()->Start());
279
280 // The app under test acts on URLs whose host is "localhost",
281 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53282 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11283
284 // Load an app URL before loading the app.
285 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
286 TabContents* contents = browser()->GetTabContentsAt(0);
[email protected]718eab62011-10-05 21:16:52287 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
288 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11289
[email protected]8d3132f62011-10-12 07:13:42290 // Load app and navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11291 const Extension* app =
292 LoadExtension(test_data_dir_.AppendASCII("app_process"));
293 ASSERT_TRUE(app);
294 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]718eab62011-10-05 21:16:52295 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
296 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11297
[email protected]8d3132f62011-10-12 07:13:42298 // Disable app and navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11299 DisableExtension(app->id());
300 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]718eab62011-10-05 21:16:52301 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
302 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11303
[email protected]8d3132f62011-10-12 07:13:42304 // Enable app and reload the page.
305 EnableExtension(app->id());
306 ui_test_utils::WindowedNotificationObserver reload_observer(
307 content::NOTIFICATION_LOAD_STOP,
308 Source<NavigationController>(
309 &browser()->GetSelectedTabContentsWrapper()->controller()));
310 browser()->Reload(CURRENT_TAB);
311 reload_observer.Wait();
312 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
313 contents->render_view_host()->process()->id()));
314
315 // Disable app and reload the page.
316 DisableExtension(app->id());
317 ui_test_utils::WindowedNotificationObserver reload_observer2(
318 content::NOTIFICATION_LOAD_STOP,
319 Source<NavigationController>(
320 &browser()->GetSelectedTabContentsWrapper()->controller()));
321 browser()->Reload(CURRENT_TAB);
322 reload_observer2.Wait();
323 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
324 contents->render_view_host()->process()->id()));
325
[email protected]d292d8a2011-05-25 03:47:11326 // Enable app and reload via JavaScript.
327 EnableExtension(app->id());
[email protected]8d3132f62011-10-12 07:13:42328 ui_test_utils::WindowedNotificationObserver js_reload_observer(
329 content::NOTIFICATION_LOAD_STOP,
330 Source<NavigationController>(
331 &browser()->GetSelectedTabContentsWrapper()->controller()));
[email protected]d292d8a2011-05-25 03:47:11332 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
333 L"", L"location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42334 js_reload_observer.Wait();
[email protected]718eab62011-10-05 21:16:52335 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
336 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11337
338 // Disable app and reload via JavaScript.
339 DisableExtension(app->id());
[email protected]8d3132f62011-10-12 07:13:42340 ui_test_utils::WindowedNotificationObserver js_reload_observer2(
341 content::NOTIFICATION_LOAD_STOP,
342 Source<NavigationController>(
343 &browser()->GetSelectedTabContentsWrapper()->controller()));
[email protected]d292d8a2011-05-25 03:47:11344 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(contents->render_view_host(),
345 L"", L"location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42346 js_reload_observer2.Wait();
[email protected]718eab62011-10-05 21:16:52347 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
348 contents->render_view_host()->process()->id()));
[email protected]d292d8a2011-05-25 03:47:11349}
[email protected]118d3122011-08-10 17:09:53350
351
352// Tests that if we have a non-app process (path3/container.html) that has an
353// iframe with a URL in the app's extent (path1/iframe.html), then opening a
354// link from that iframe to a new window to a URL in the app's extent (path1/
355// empty.html) results in the new window being in an app process. See
356// http://crbug.com/89272 for more details.
357IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
358 CommandLine::ForCurrentProcess()->AppendSwitch(
359 switches::kDisablePopupBlocking);
360
[email protected]718eab62011-10-05 21:16:52361 ExtensionProcessManager* extension_process_manager =
362 browser()->profile()->GetExtensionProcessManager();
363
[email protected]118d3122011-08-10 17:09:53364 host_resolver()->AddRule("*", "127.0.0.1");
365 ASSERT_TRUE(test_server()->Start());
366
367 GURL base_url = GetTestBaseURL("app_process");
368
369 // Load app and start URL (not in the app).
370 const Extension* app =
371 LoadExtension(test_data_dir_.AppendASCII("app_process"));
372 ASSERT_TRUE(app);
373 ui_test_utils::NavigateToURLWithDisposition(
374 browser(),
375 base_url.Resolve("path3/container.html"),
376 CURRENT_TAB,
377 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
378 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]718eab62011-10-05 21:16:52379 EXPECT_FALSE(extension_process_manager->IsExtensionProcess(
380 browser()->GetTabContentsAt(0)->render_view_host()->process()->id()));
[email protected]118d3122011-08-10 17:09:53381
382 // Wait for popup window to appear.
383 GURL app_url = base_url.Resolve("path1/empty.html");
384 Browser* last_active_browser = BrowserList::GetLastActive();
385 EXPECT_TRUE(last_active_browser);
386 ASSERT_NE(browser(), last_active_browser);
387 TabContents* newtab = last_active_browser->GetSelectedTabContents();
388 EXPECT_TRUE(newtab);
389 if (!newtab->controller().GetLastCommittedEntry() ||
[email protected]160f17f12011-10-19 00:40:00390 newtab->controller().GetLastCommittedEntry()->url() != app_url) {
391 // TODO(gbillock): This still looks racy. Need to make a custom
392 // observer to intercept new window creation and then look for
393 // NAV_ENTRY_COMMITTED on the new tab there.
394 ui_test_utils::WindowedNotificationObserver observer(
395 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
396 Source<NavigationController>(&(newtab->controller())));
397 observer.Wait();
398 }
[email protected]118d3122011-08-10 17:09:53399
400 // Popup window should be in the app's process.
[email protected]718eab62011-10-05 21:16:52401 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
402 last_active_browser->GetTabContentsAt(0)->render_view_host()->process()->
403 id()));
[email protected]118d3122011-08-10 17:09:53404}
[email protected]a09add52011-08-12 03:59:23405
[email protected]d55c2382011-08-18 23:10:36406// Tests that if we have an app process (path1/container.html) with a non-app
407// iframe (path3/iframe.html), then opening a link from that iframe to a new
408// window to a same-origin non-app URL (path3/empty.html) should keep the window
409// in the app process.
410// This is in contrast to OpenAppFromIframe, since here the popup will not be
411// missing special permissions and should be scriptable from the iframe.
412// See http://crbug.com/92669 for more details.
413IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
414 CommandLine::ForCurrentProcess()->AppendSwitch(
415 switches::kDisablePopupBlocking);
416
[email protected]718eab62011-10-05 21:16:52417 ExtensionProcessManager* extension_process_manager =
418 browser()->profile()->GetExtensionProcessManager();
419
[email protected]d55c2382011-08-18 23:10:36420 host_resolver()->AddRule("*", "127.0.0.1");
421 ASSERT_TRUE(test_server()->Start());
422
423 GURL base_url = GetTestBaseURL("app_process");
424
425 // Load app and start URL (in the app).
426 const Extension* app =
427 LoadExtension(test_data_dir_.AppendASCII("app_process"));
428 ASSERT_TRUE(app);
[email protected]160f17f12011-10-19 00:40:00429 ui_test_utils::WindowedNotificationObserver observer(
430 content::NOTIFICATION_LOAD_STOP,
431 NotificationService::AllSources());
[email protected]d55c2382011-08-18 23:10:36432 ui_test_utils::NavigateToURLWithDisposition(
433 browser(),
434 base_url.Resolve("path1/container.html"),
435 CURRENT_TAB,
436 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION |
437 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
438 RenderProcessHost* process =
439 browser()->GetTabContentsAt(0)->render_view_host()->process();
[email protected]718eab62011-10-05 21:16:52440 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
441 process->id()));
[email protected]d55c2382011-08-18 23:10:36442
443 // Wait for popup window to appear. The new Browser may not have been
444 // added with SetLastActive, in which case we need to show it first.
445 // This is necessary for popup windows without a cross-site transition.
446 if (browser() == BrowserList::GetLastActive()) {
447 // Grab the second window and show it.
448 ASSERT_TRUE(BrowserList::size() == 2);
449 Browser* popup_browser = *(++BrowserList::begin());
450 popup_browser->window()->Show();
451 }
452 Browser* last_active_browser = BrowserList::GetLastActive();
453 EXPECT_TRUE(last_active_browser);
454 ASSERT_NE(browser(), last_active_browser);
455 TabContents* newtab = last_active_browser->GetSelectedTabContents();
456 EXPECT_TRUE(newtab);
457 GURL non_app_url = base_url.Resolve("path3/empty.html");
[email protected]160f17f12011-10-19 00:40:00458 observer.Wait();
[email protected]d55c2382011-08-18 23:10:36459
460 // Popup window should be in the app's process.
461 RenderProcessHost* popup_process =
462 last_active_browser->GetTabContentsAt(0)->render_view_host()->process();
463 EXPECT_EQ(process, popup_process);
464}
465
[email protected]a09add52011-08-12 03:59:23466IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadAppAfterCrash) {
[email protected]718eab62011-10-05 21:16:52467 ExtensionProcessManager* extension_process_manager =
468 browser()->profile()->GetExtensionProcessManager();
[email protected]a09add52011-08-12 03:59:23469 host_resolver()->AddRule("*", "127.0.0.1");
470 ASSERT_TRUE(test_server()->Start());
471
472 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
473
474 GURL base_url = GetTestBaseURL("app_process");
475
476 // Load the app, chrome.app.isInstalled should be true.
477 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
478 TabContents* contents = browser()->GetTabContentsAt(0);
[email protected]718eab62011-10-05 21:16:52479 EXPECT_TRUE(extension_process_manager->IsExtensionProcess(
480 contents->render_view_host()->process()->id()));
[email protected]a09add52011-08-12 03:59:23481 bool is_installed = false;
482 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
483 contents->render_view_host(), L"",
484 L"window.domAutomationController.send(chrome.app.isInstalled)",
485 &is_installed));
486 ASSERT_TRUE(is_installed);
487
488 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
489 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]ae673742011-08-24 19:48:37490 ui_test_utils::WindowedNotificationObserver observer(
491 content::NOTIFICATION_LOAD_STOP,
492 Source<NavigationController>(
493 &browser()->GetSelectedTabContentsWrapper()->controller()));
[email protected]a09add52011-08-12 03:59:23494 browser()->Reload(CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37495 observer.Wait();
[email protected]a09add52011-08-12 03:59:23496 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
497 contents->render_view_host(), L"",
498 L"window.domAutomationController.send(chrome.app.isInstalled)",
499 &is_installed));
500 ASSERT_TRUE(is_installed);
501}