Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / isolated_app_browsertest.cc
blobc9439ef67445f8ee072b2206557b245e28363092
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/stringprintf.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/extensions/extension_apitest.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/browser_commands.h"
10 #include "chrome/browser/ui/tabs/tab_strip_model.h"
11 #include "chrome/common/url_constants.h"
12 #include "chrome/test/base/ui_test_utils.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/site_instance.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/test/browser_test_utils.h"
18 #include "extensions/browser/extension_host.h"
19 #include "extensions/browser/extension_registry.h"
20 #include "extensions/browser/process_map.h"
21 #include "extensions/common/switches.h"
22 #include "net/dns/mock_host_resolver.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "net/test/embedded_test_server/http_request.h"
25 #include "net/test/embedded_test_server/http_response.h"
27 using content::ExecuteScript;
28 using content::ExecuteScriptAndExtractString;
29 using content::NavigationController;
30 using content::RenderViewHost;
31 using content::WebContents;
33 namespace extensions {
35 namespace {
37 std::string WrapForJavascriptAndExtract(const char* javascript_expression) {
38 return std::string("window.domAutomationController.send(") +
39 javascript_expression + ")";
42 scoped_ptr<net::test_server::HttpResponse> HandleExpectAndSetCookieRequest(
43 const net::test_server::EmbeddedTestServer* test_server,
44 const net::test_server::HttpRequest& request) {
45 if (!base::StartsWith(request.relative_url, "/expect-and-set-cookie?",
46 base::CompareCase::SENSITIVE))
47 return scoped_ptr<net::test_server::HttpResponse>();
49 scoped_ptr<net::test_server::BasicHttpResponse> http_response(
50 new net::test_server::BasicHttpResponse);
51 http_response->set_code(net::HTTP_OK);
53 std::string request_cookies;
54 std::map<std::string, std::string>::const_iterator it =
55 request.headers.find("Cookie");
56 if (it != request.headers.end())
57 request_cookies = it->second;
59 size_t query_string_pos = request.relative_url.find('?');
60 std::string query_string =
61 request.relative_url.substr(query_string_pos + 1);
62 url::Component query(0, query_string.length()), key_pos, value_pos;
63 bool expectations_satisfied = true;
64 std::vector<std::string> cookies_to_set;
65 while (url::ExtractQueryKeyValue(query_string.c_str(), &query, &key_pos,
66 &value_pos)) {
67 std::string escaped_key(query_string.substr(key_pos.begin, key_pos.len));
68 std::string escaped_value(
69 query_string.substr(value_pos.begin, value_pos.len));
71 std::string key =
72 net::UnescapeURLComponent(escaped_key,
73 net::UnescapeRule::NORMAL |
74 net::UnescapeRule::SPACES |
75 net::UnescapeRule::URL_SPECIAL_CHARS);
77 std::string value =
78 net::UnescapeURLComponent(escaped_value,
79 net::UnescapeRule::NORMAL |
80 net::UnescapeRule::SPACES |
81 net::UnescapeRule::URL_SPECIAL_CHARS);
83 if (key == "expect") {
84 if (request_cookies.find(value) == std::string::npos)
85 expectations_satisfied = false;
86 } else if (key == "set") {
87 cookies_to_set.push_back(value);
88 } else {
89 return nullptr;
93 if (expectations_satisfied) {
94 for (size_t i = 0; i < cookies_to_set.size(); i++)
95 http_response->AddCustomHeader("Set-Cookie", cookies_to_set[i]);
98 return http_response.Pass();
101 class IsolatedAppTest : public ExtensionBrowserTest {
102 public:
103 // Returns whether the given tab's current URL has the given cookie.
104 bool WARN_UNUSED_RESULT HasCookie(WebContents* contents, std::string cookie) {
105 int value_size;
106 std::string actual_cookie;
107 ui_test_utils::GetCookies(contents->GetURL(), contents, &value_size,
108 &actual_cookie);
109 return actual_cookie.find(cookie) != std::string::npos;
112 const Extension* GetInstalledApp(WebContents* contents) {
113 content::BrowserContext* browser_context = contents->GetBrowserContext();
114 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
115 std::set<std::string> extension_ids =
116 ProcessMap::Get(browser_context)->GetExtensionsInProcess(
117 contents->GetRenderViewHost()->GetProcess()->GetID());
118 for (std::set<std::string>::iterator iter = extension_ids.begin();
119 iter != extension_ids.end(); ++iter) {
120 const Extension* installed_app =
121 registry->enabled_extensions().GetByID(*iter);
122 if (installed_app && installed_app->is_app())
123 return installed_app;
125 return NULL;
128 private:
129 void SetUpCommandLine(base::CommandLine* command_line) override {
130 ExtensionBrowserTest::SetUpCommandLine(command_line);
131 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
135 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, CrossProcessClientRedirect) {
136 host_resolver()->AddRule("*", "127.0.0.1");
137 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
139 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1")));
140 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app2")));
142 GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/");
143 GURL::Replacements replace_host;
144 replace_host.SetHostStr("localhost");
145 base_url = base_url.ReplaceComponents(replace_host);
146 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html"));
148 // Redirect to app2.
149 GURL redirect_url(embedded_test_server()->GetURL(
150 "/extensions/isolated_apps/app2/redirect.html"));
151 ui_test_utils::NavigateToURL(browser(), redirect_url);
153 // Go back twice.
154 // If bug fixed, we cannot go back anymore.
155 // If not fixed, we will redirect back to app2 and can go back again.
156 EXPECT_TRUE(chrome::CanGoBack(browser()));
157 chrome::GoBack(browser(), CURRENT_TAB);
158 EXPECT_TRUE(chrome::CanGoBack(browser()));
159 chrome::GoBack(browser(), CURRENT_TAB);
160 EXPECT_FALSE(chrome::CanGoBack(browser()));
162 // We also need to test script-initialized navigation (document.location.href)
163 // happened after page finishes loading. This one will also triggered the
164 // willPerformClientRedirect hook in RenderViewImpl but should not replace
165 // the previous history entry.
166 ui_test_utils::NavigateToURLWithDisposition(
167 browser(), base_url.Resolve("non_app/main.html"),
168 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
170 WebContents* tab0 = browser()->tab_strip_model()->GetWebContentsAt(1);
172 // Using JavaScript to navigate to app2 page,
173 // after the non_app page has finished loading.
174 content::WindowedNotificationObserver observer1(
175 content::NOTIFICATION_LOAD_STOP,
176 content::Source<NavigationController>(
177 &browser()->tab_strip_model()->GetActiveWebContents()->
178 GetController()));
179 std::string script = base::StringPrintf(
180 "document.location.href=\"%s\";",
181 base_url.Resolve("app2/main.html").spec().c_str());
182 EXPECT_TRUE(ExecuteScript(tab0, script));
183 observer1.Wait();
185 // This kind of navigation should not replace previous navigation entry.
186 EXPECT_TRUE(chrome::CanGoBack(browser()));
187 chrome::GoBack(browser(), CURRENT_TAB);
188 EXPECT_FALSE(chrome::CanGoBack(browser()));
191 // Tests that cookies set within an isolated app are not visible to normal
192 // pages or other apps.
194 // TODO(ajwong): Also test what happens if an app spans multiple sites in its
195 // extent. These origins should also be isolated, but still have origin-based
196 // separation as you would expect.
198 // This test is disabled due to being flaky. http://crbug.com/86562
199 #if defined(OS_WIN)
200 #define MAYBE_CookieIsolation DISABLED_CookieIsolation
201 #else
202 #define MAYBE_CookieIsolation CookieIsolation
203 #endif
204 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, MAYBE_CookieIsolation) {
205 host_resolver()->AddRule("*", "127.0.0.1");
206 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
208 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1")));
209 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app2")));
211 // The app under test acts on URLs whose host is "localhost",
212 // so the URLs we navigate to must have host "localhost".
213 GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/");
214 GURL::Replacements replace_host;
215 replace_host.SetHostStr("localhost");
216 base_url = base_url.ReplaceComponents(replace_host);
218 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html"));
219 ui_test_utils::NavigateToURLWithDisposition(
220 browser(), base_url.Resolve("app2/main.html"),
221 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
222 ui_test_utils::NavigateToURLWithDisposition(
223 browser(), base_url.Resolve("non_app/main.html"),
224 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
226 ASSERT_EQ(3, browser()->tab_strip_model()->count());
228 // Ensure first two tabs have installed apps.
229 WebContents* tab0 = browser()->tab_strip_model()->GetWebContentsAt(0);
230 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
231 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
232 ASSERT_TRUE(GetInstalledApp(tab0));
233 ASSERT_TRUE(GetInstalledApp(tab1));
234 ASSERT_TRUE(!GetInstalledApp(tab2));
236 // Check that tabs see cannot each other's localStorage even though they are
237 // in the same origin.
238 ASSERT_TRUE(ExecuteScript(
239 tab0, "window.localStorage.setItem('testdata', 'ls_app1');"));
240 ASSERT_TRUE(ExecuteScript(
241 tab1, "window.localStorage.setItem('testdata', 'ls_app2');"));
242 ASSERT_TRUE(ExecuteScript(
243 tab2, "window.localStorage.setItem('testdata', 'ls_normal');"));
245 const std::string& kRetrieveLocalStorage =
246 WrapForJavascriptAndExtract(
247 "window.localStorage.getItem('testdata') || 'badval'");
248 std::string result;
249 ASSERT_TRUE(ExecuteScriptAndExtractString(
250 tab0, kRetrieveLocalStorage.c_str(), &result));
251 EXPECT_EQ("ls_app1", result);
252 ASSERT_TRUE(ExecuteScriptAndExtractString(
253 tab1, kRetrieveLocalStorage.c_str(), &result));
254 EXPECT_EQ("ls_app2", result);
255 ASSERT_TRUE(ExecuteScriptAndExtractString(
256 tab2, kRetrieveLocalStorage.c_str(), &result));
257 EXPECT_EQ("ls_normal", result);
259 // Check that each tab sees its own cookie.
260 EXPECT_TRUE(HasCookie(tab0, "app1=3"));
261 EXPECT_TRUE(HasCookie(tab1, "app2=4"));
262 EXPECT_TRUE(HasCookie(tab2, "normalPage=5"));
264 // Check that app1 tab cannot see the other cookies.
265 EXPECT_FALSE(HasCookie(tab0, "app2"));
266 EXPECT_FALSE(HasCookie(tab0, "normalPage"));
268 // Check that app2 tab cannot see the other cookies.
269 EXPECT_FALSE(HasCookie(tab1, "app1"));
270 EXPECT_FALSE(HasCookie(tab1, "normalPage"));
272 // Check that normal tab cannot see the other cookies.
273 EXPECT_FALSE(HasCookie(tab2, "app1"));
274 EXPECT_FALSE(HasCookie(tab2, "app2"));
276 // Check that the non_app iframe cookie is associated with app1 and not the
277 // normal tab. (For now, iframes are always rendered in their parent
278 // process, even if they aren't in the app manifest.)
279 EXPECT_TRUE(HasCookie(tab0, "nonAppFrame=6"));
280 EXPECT_FALSE(HasCookie(tab2, "nonAppFrame"));
282 // Check that isolation persists even if the tab crashes and is reloaded.
283 chrome::SelectNumberedTab(browser(), 0);
284 content::CrashTab(tab0);
285 content::WindowedNotificationObserver observer(
286 content::NOTIFICATION_LOAD_STOP,
287 content::Source<NavigationController>(
288 &browser()->tab_strip_model()->GetActiveWebContents()->
289 GetController()));
290 chrome::Reload(browser(), CURRENT_TAB);
291 observer.Wait();
292 EXPECT_TRUE(HasCookie(tab0, "app1=3"));
293 EXPECT_FALSE(HasCookie(tab0, "app2"));
294 EXPECT_FALSE(HasCookie(tab0, "normalPage"));
297 // This test is disabled due to being flaky. http://crbug.com/145588
298 // Ensure that cookies are not isolated if the isolated apps are not installed.
299 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, DISABLED_NoCookieIsolationWithoutApp) {
300 host_resolver()->AddRule("*", "127.0.0.1");
301 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
303 // The app under test acts on URLs whose host is "localhost",
304 // so the URLs we navigate to must have host "localhost".
305 GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/");
306 GURL::Replacements replace_host;
307 replace_host.SetHostStr("localhost");
308 base_url = base_url.ReplaceComponents(replace_host);
310 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html"));
311 ui_test_utils::NavigateToURLWithDisposition(
312 browser(), base_url.Resolve("app2/main.html"),
313 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
314 ui_test_utils::NavigateToURLWithDisposition(
315 browser(), base_url.Resolve("non_app/main.html"),
316 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
318 ASSERT_EQ(3, browser()->tab_strip_model()->count());
320 // Check that tabs see each other's cookies.
321 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(0),
322 "app2=4"));
323 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(0),
324 "normalPage=5"));
325 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(0),
326 "nonAppFrame=6"));
327 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(1),
328 "app1=3"));
329 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(1),
330 "normalPage=5"));
331 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(1),
332 "nonAppFrame=6"));
333 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(2),
334 "app1=3"));
335 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(2),
336 "app2=4"));
337 EXPECT_TRUE(HasCookie(browser()->tab_strip_model()->GetWebContentsAt(2),
338 "nonAppFrame=6"));
340 // Check that all tabs share the same localStorage if they have the same
341 // origin.
342 WebContents* app1_wc = browser()->tab_strip_model()->GetWebContentsAt(0);
343 WebContents* app2_wc = browser()->tab_strip_model()->GetWebContentsAt(1);
344 WebContents* non_app_wc = browser()->tab_strip_model()->GetWebContentsAt(2);
345 ASSERT_TRUE(ExecuteScript(
346 app1_wc, "window.localStorage.setItem('testdata', 'ls_app1');"));
347 ASSERT_TRUE(ExecuteScript(
348 app2_wc, "window.localStorage.setItem('testdata', 'ls_app2');"));
349 ASSERT_TRUE(ExecuteScript(
350 non_app_wc, "window.localStorage.setItem('testdata', 'ls_normal');"));
352 const std::string& kRetrieveLocalStorage =
353 WrapForJavascriptAndExtract("window.localStorage.getItem('testdata')");
354 std::string result;
355 ASSERT_TRUE(ExecuteScriptAndExtractString(
356 app1_wc, kRetrieveLocalStorage.c_str(), &result));
357 EXPECT_EQ("ls_normal", result);
358 ASSERT_TRUE(ExecuteScriptAndExtractString(
359 app2_wc, kRetrieveLocalStorage.c_str(), &result));
360 EXPECT_EQ("ls_normal", result);
361 ASSERT_TRUE(ExecuteScriptAndExtractString(
362 non_app_wc, kRetrieveLocalStorage.c_str(), &result));
363 EXPECT_EQ("ls_normal", result);
366 // http://crbug.com/174926
367 #if (defined(OS_WIN) && !defined(NDEBUG)) || defined(OS_MACOSX)
368 #define MAYBE_SubresourceCookieIsolation DISABLED_SubresourceCookieIsolation
369 #else
370 #define MAYBE_SubresourceCookieIsolation SubresourceCookieIsolation
371 #endif // (defined(OS_WIN) && !defined(NDEBUG)) || defined(OS_MACOSX)
373 // Tests that subresource and media requests use the app's cookie store.
374 // See http://crbug.com/141172.
375 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, MAYBE_SubresourceCookieIsolation) {
376 embedded_test_server()->RegisterRequestHandler(
377 base::Bind(&HandleExpectAndSetCookieRequest, embedded_test_server()));
379 host_resolver()->AddRule("*", "127.0.0.1");
380 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
382 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1")));
384 // The app under test acts on URLs whose host is "localhost",
385 // so the URLs we navigate to must have host "localhost".
386 GURL root_url = embedded_test_server()->GetURL("/");
387 GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/");
388 GURL::Replacements replace_host;
389 replace_host.SetHostStr("localhost");
390 root_url = root_url.ReplaceComponents(replace_host);
391 base_url = base_url.ReplaceComponents(replace_host);
393 // First set cookies inside and outside the app.
394 ui_test_utils::NavigateToURL(
395 browser(), root_url.Resolve("expect-and-set-cookie?set=nonApp%3d1"));
396 WebContents* tab0 = browser()->tab_strip_model()->GetWebContentsAt(0);
397 ASSERT_FALSE(GetInstalledApp(tab0));
398 ui_test_utils::NavigateToURLWithDisposition(
399 browser(), base_url.Resolve("app1/main.html"),
400 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
401 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
402 ASSERT_TRUE(GetInstalledApp(tab1));
404 // Check that each tab sees its own cookie.
405 EXPECT_TRUE(HasCookie(tab0, "nonApp=1"));
406 EXPECT_FALSE(HasCookie(tab0, "app1=3"));
407 EXPECT_FALSE(HasCookie(tab1, "nonApp=1"));
408 EXPECT_TRUE(HasCookie(tab1, "app1=3"));
410 // Now visit an app page that loads subresources located outside the app.
411 // For both images and video tags, it loads two URLs:
412 // - One will set nonApp{Media,Image}=1 cookies if nonApp=1 is set.
413 // - One will set app1{Media,Image}=1 cookies if app1=3 is set.
414 // We expect only the app's cookies to be present.
415 // We must wait for the onload event, to allow the subresources to finish.
416 content::WindowedNotificationObserver observer(
417 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
418 content::Source<WebContents>(
419 browser()->tab_strip_model()->GetActiveWebContents()));
420 ui_test_utils::NavigateToURL(
421 browser(), base_url.Resolve("app1/app_subresources.html"));
422 observer.Wait();
423 EXPECT_FALSE(HasCookie(tab1, "nonAppMedia=1"));
424 EXPECT_TRUE(HasCookie(tab1, "app1Media=1"));
425 EXPECT_FALSE(HasCookie(tab1, "nonAppImage=1"));
426 EXPECT_TRUE(HasCookie(tab1, "app1Image=1"));
428 // Also create a non-app tab to ensure no new cookies were set in that jar.
429 ui_test_utils::NavigateToURLWithDisposition(
430 browser(), root_url,
431 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
432 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
433 EXPECT_FALSE(HasCookie(tab2, "nonAppMedia=1"));
434 EXPECT_FALSE(HasCookie(tab2, "app1Media=1"));
435 EXPECT_FALSE(HasCookie(tab2, "nonAppImage=1"));
436 EXPECT_FALSE(HasCookie(tab2, "app1Image=1"));
439 // Test is flaky on Windows.
440 // http://crbug.com/247667
441 #if defined(OS_WIN)
442 #define MAYBE_IsolatedAppProcessModel DISABLED_IsolatedAppProcessModel
443 #else
444 #define MAYBE_IsolatedAppProcessModel IsolatedAppProcessModel
445 #endif // defined(OS_WIN)
447 // Tests that isolated apps processes do not render top-level non-app pages.
448 // This is true even in the case of the OAuth workaround for hosted apps,
449 // where non-app popups may be kept in the hosted app process.
450 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, MAYBE_IsolatedAppProcessModel) {
451 host_resolver()->AddRule("*", "127.0.0.1");
452 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
454 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1")));
456 // The app under test acts on URLs whose host is "localhost",
457 // so the URLs we navigate to must have host "localhost".
458 GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/");
459 GURL::Replacements replace_host;
460 replace_host.SetHostStr("localhost");
461 base_url = base_url.ReplaceComponents(replace_host);
463 // Create three tabs in the isolated app in different ways.
464 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html"));
465 ui_test_utils::NavigateToURLWithDisposition(
466 browser(), base_url.Resolve("app1/main.html"),
467 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
468 // For the third tab, use window.open to keep it in process with an opener.
469 OpenWindow(browser()->tab_strip_model()->GetWebContentsAt(0),
470 base_url.Resolve("app1/main.html"), true, NULL);
472 // In a fourth tab, use window.open to a non-app URL. It should open in a
473 // separate process, even though this would trigger the OAuth workaround
474 // for hosted apps (from http://crbug.com/59285).
475 OpenWindow(browser()->tab_strip_model()->GetWebContentsAt(0),
476 base_url.Resolve("non_app/main.html"), false, NULL);
478 // We should now have four tabs, the first and third sharing a process.
479 // The second one is an independent instance in a separate process.
480 ASSERT_EQ(4, browser()->tab_strip_model()->count());
481 int process_id_0 = browser()->tab_strip_model()->GetWebContentsAt(0)->
482 GetRenderProcessHost()->GetID();
483 int process_id_1 = browser()->tab_strip_model()->GetWebContentsAt(1)->
484 GetRenderProcessHost()->GetID();
485 EXPECT_NE(process_id_0, process_id_1);
486 EXPECT_EQ(process_id_0,
487 browser()->tab_strip_model()->GetWebContentsAt(2)->
488 GetRenderProcessHost()->GetID());
489 EXPECT_NE(process_id_0,
490 browser()->tab_strip_model()->GetWebContentsAt(3)->
491 GetRenderProcessHost()->GetID());
493 // Navigating the second tab out of the app should cause a process swap.
494 const GURL& non_app_url(base_url.Resolve("non_app/main.html"));
495 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(1),
496 non_app_url);
497 EXPECT_NE(process_id_1,
498 browser()->tab_strip_model()->GetWebContentsAt(1)->
499 GetRenderProcessHost()->GetID());
502 // This test no longer passes, since we don't properly isolate sessionStorage
503 // for isolated apps. This was broken as part of the changes for storage
504 // partition support for webview tags.
505 // TODO(nasko): If isolated apps is no longer developed, this test should be
506 // removed. http://crbug.com/159932
507 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, DISABLED_SessionStorage) {
508 host_resolver()->AddRule("*", "127.0.0.1");
509 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
511 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1")));
512 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app2")));
514 // The app under test acts on URLs whose host is "localhost",
515 // so the URLs we navigate to must have host "localhost".
516 GURL base_url = embedded_test_server()->GetURL("/extensions/isolated_apps/");
517 GURL::Replacements replace_host;
518 replace_host.SetHostStr("localhost");
519 base_url = base_url.ReplaceComponents(replace_host);
521 // Enter some state into sessionStorage three times on the same origin, but
522 // for three URLs that correspond to app1, app2, and a non-isolated site.
523 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html"));
524 ASSERT_TRUE(ExecuteScript(
525 browser()->tab_strip_model()->GetWebContentsAt(0),
526 "window.sessionStorage.setItem('testdata', 'ss_app1');"));
528 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app2/main.html"));
529 ASSERT_TRUE(ExecuteScript(
530 browser()->tab_strip_model()->GetWebContentsAt(0),
531 "window.sessionStorage.setItem('testdata', 'ss_app2');"));
533 ui_test_utils::NavigateToURL(
534 browser(), base_url.Resolve("non_app/main.html"));
535 ASSERT_TRUE(ExecuteScript(
536 browser()->tab_strip_model()->GetWebContentsAt(0),
537 "window.sessionStorage.setItem('testdata', 'ss_normal');"));
539 // Now, ensure that the sessionStorage is correctly partitioned, and persists
540 // when we navigate around all over the dang place.
541 const std::string& kRetrieveSessionStorage =
542 WrapForJavascriptAndExtract(
543 "window.sessionStorage.getItem('testdata') || 'badval'");
544 std::string result;
545 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app1/main.html"));
546 ASSERT_TRUE(ExecuteScriptAndExtractString(
547 browser()->tab_strip_model()->GetWebContentsAt(0),
548 kRetrieveSessionStorage.c_str(), &result));
549 EXPECT_EQ("ss_app1", result);
551 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("app2/main.html"));
552 ASSERT_TRUE(ExecuteScriptAndExtractString(
553 browser()->tab_strip_model()->GetWebContentsAt(0),
554 kRetrieveSessionStorage.c_str(), &result));
555 EXPECT_EQ("ss_app2", result);
557 ui_test_utils::NavigateToURL(
558 browser(), base_url.Resolve("non_app/main.html"));
559 ASSERT_TRUE(ExecuteScriptAndExtractString(
560 browser()->tab_strip_model()->GetWebContentsAt(0),
561 kRetrieveSessionStorage.c_str(), &result));
562 EXPECT_EQ("ss_normal", result);
565 } // namespace
567 } // namespace extensions