| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include <set> | |
| 6 | |
| 7 #include "base/json/json_reader.h" | |
| 8 #include "base/memory/ref_counted.h" | |
| 9 #include "base/path_service.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "base/values.h" | |
| 12 #include "content/browser/renderer_host/render_view_host_impl.h" | |
| 13 #include "content/browser/site_instance_impl.h" | |
| 14 #include "content/browser/web_contents/web_contents_impl.h" | |
| 15 #include "content/common/content_constants_internal.h" | |
| 16 #include "content/public/browser/navigation_controller.h" | |
| 17 #include "content/public/browser/navigation_entry.h" | |
| 18 #include "content/public/browser/notification_details.h" | |
| 19 #include "content/public/browser/notification_observer.h" | |
| 20 #include "content/public/browser/notification_registrar.h" | |
| 21 #include "content/public/browser/notification_types.h" | |
| 22 #include "content/public/browser/render_process_host.h" | |
| 23 #include "content/public/browser/web_contents.h" | |
| 24 #include "content/public/browser/web_contents_observer.h" | |
| 25 #include "content/public/common/url_constants.h" | |
| 26 #include "content/public/test/browser_test_utils.h" | |
| 27 #include "content/public/test/test_navigation_observer.h" | |
| 28 #include "content/public/test/test_utils.h" | |
| 29 #include "content/shell/browser/shell.h" | |
| 30 #include "content/test/content_browser_test.h" | |
| 31 #include "content/test/content_browser_test_utils.h" | |
| 32 #include "net/base/net_util.h" | |
| 33 #include "net/test/spawned_test_server/spawned_test_server.h" | |
| 34 | |
| 35 namespace content { | |
| 36 | |
| 37 class RenderViewHostManagerTest : public ContentBrowserTest { | |
| 38 public: | |
| 39 RenderViewHostManagerTest() {} | |
| 40 | |
| 41 static bool GetFilePathWithHostAndPortReplacement( | |
| 42 const std::string& original_file_path, | |
| 43 const net::HostPortPair& host_port_pair, | |
| 44 std::string* replacement_path) { | |
| 45 std::vector<net::SpawnedTestServer::StringPair> replacement_text; | |
| 46 replacement_text.push_back( | |
| 47 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString())); | |
| 48 return net::SpawnedTestServer::GetFilePathWithReplacements( | |
| 49 original_file_path, replacement_text, replacement_path); | |
| 50 } | |
| 51 }; | |
| 52 | |
| 53 // Web pages should not have script access to the swapped out page. | |
| 54 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 55 DISABLED_NoScriptAccessAfterSwapOut) { | |
| 56 // Start two servers with different sites. | |
| 57 ASSERT_TRUE(test_server()->Start()); | |
| 58 net::SpawnedTestServer https_server( | |
| 59 net::SpawnedTestServer::TYPE_HTTPS, | |
| 60 net::SpawnedTestServer::kLocalhost, | |
| 61 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 62 ASSERT_TRUE(https_server.Start()); | |
| 63 | |
| 64 // Load a page with links that open in a new window. | |
| 65 std::string replacement_path; | |
| 66 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 67 "files/click-noreferrer-links.html", | |
| 68 https_server.host_port_pair(), | |
| 69 &replacement_path)); | |
| 70 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 71 | |
| 72 // Get the original SiteInstance for later comparison. | |
| 73 scoped_refptr<SiteInstance> orig_site_instance( | |
| 74 shell()->web_contents()->GetSiteInstance()); | |
| 75 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 76 | |
| 77 // Open a same-site link in a new window. | |
| 78 ShellAddedObserver new_shell_observer; | |
| 79 bool success = false; | |
| 80 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 81 shell()->web_contents(), | |
| 82 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 83 &success)); | |
| 84 EXPECT_TRUE(success); | |
| 85 Shell* new_shell = new_shell_observer.GetShell(); | |
| 86 | |
| 87 // Wait for the navigation in the new window to finish, if it hasn't. | |
| 88 WaitForLoadStop(new_shell->web_contents()); | |
| 89 EXPECT_EQ("/files/navigate_opener.html", | |
| 90 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 91 | |
| 92 // Should have the same SiteInstance. | |
| 93 scoped_refptr<SiteInstance> blank_site_instance( | |
| 94 new_shell->web_contents()->GetSiteInstance()); | |
| 95 EXPECT_EQ(orig_site_instance, blank_site_instance); | |
| 96 | |
| 97 // We should have access to the opened window's location. | |
| 98 success = false; | |
| 99 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 100 shell()->web_contents(), | |
| 101 "window.domAutomationController.send(testScriptAccessToWindow());", | |
| 102 &success)); | |
| 103 EXPECT_TRUE(success); | |
| 104 | |
| 105 // Now navigate the new window to a different site. | |
| 106 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 107 scoped_refptr<SiteInstance> new_site_instance( | |
| 108 new_shell->web_contents()->GetSiteInstance()); | |
| 109 EXPECT_NE(orig_site_instance, new_site_instance); | |
| 110 | |
| 111 // We should no longer have script access to the opened window's location. | |
| 112 success = false; | |
| 113 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 114 shell()->web_contents(), | |
| 115 "window.domAutomationController.send(testScriptAccessToWindow());", | |
| 116 &success)); | |
| 117 EXPECT_FALSE(success); | |
| 118 } | |
| 119 | |
| 120 // Test for crbug.com/24447. Following a cross-site link with rel=noreferrer | |
| 121 // and target=_blank should create a new SiteInstance. | |
| 122 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 123 SwapProcessWithRelNoreferrerAndTargetBlank) { | |
| 124 // Start two servers with different sites. | |
| 125 ASSERT_TRUE(test_server()->Start()); | |
| 126 net::SpawnedTestServer https_server( | |
| 127 net::SpawnedTestServer::TYPE_HTTPS, | |
| 128 net::SpawnedTestServer::kLocalhost, | |
| 129 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 130 ASSERT_TRUE(https_server.Start()); | |
| 131 | |
| 132 // Load a page with links that open in a new window. | |
| 133 std::string replacement_path; | |
| 134 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 135 "files/click-noreferrer-links.html", | |
| 136 https_server.host_port_pair(), | |
| 137 &replacement_path)); | |
| 138 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 139 | |
| 140 // Get the original SiteInstance for later comparison. | |
| 141 scoped_refptr<SiteInstance> orig_site_instance( | |
| 142 shell()->web_contents()->GetSiteInstance()); | |
| 143 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 144 | |
| 145 // Test clicking a rel=noreferrer + target=blank link. | |
| 146 ShellAddedObserver new_shell_observer; | |
| 147 bool success = false; | |
| 148 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 149 shell()->web_contents(), | |
| 150 "window.domAutomationController.send(clickNoRefTargetBlankLink());", | |
| 151 &success)); | |
| 152 EXPECT_TRUE(success); | |
| 153 | |
| 154 // Wait for the window to open. | |
| 155 Shell* new_shell = new_shell_observer.GetShell(); | |
| 156 | |
| 157 EXPECT_EQ("/files/title2.html", | |
| 158 new_shell->web_contents()->GetVisibleURL().path()); | |
| 159 | |
| 160 // Wait for the cross-site transition in the new tab to finish. | |
| 161 WaitForLoadStop(new_shell->web_contents()); | |
| 162 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( | |
| 163 new_shell->web_contents()); | |
| 164 EXPECT_FALSE(web_contents->GetRenderManagerForTesting()-> | |
| 165 pending_render_view_host()); | |
| 166 | |
| 167 // Should have a new SiteInstance. | |
| 168 scoped_refptr<SiteInstance> noref_blank_site_instance( | |
| 169 new_shell->web_contents()->GetSiteInstance()); | |
| 170 EXPECT_NE(orig_site_instance, noref_blank_site_instance); | |
| 171 } | |
| 172 | |
| 173 // As of crbug.com/69267, we create a new BrowsingInstance (and SiteInstance) | |
| 174 // for rel=noreferrer links in new windows, even to same site pages and named | |
| 175 // targets. | |
| 176 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 177 SwapProcessWithSameSiteRelNoreferrer) { | |
| 178 // Start two servers with different sites. | |
| 179 ASSERT_TRUE(test_server()->Start()); | |
| 180 net::SpawnedTestServer https_server( | |
| 181 net::SpawnedTestServer::TYPE_HTTPS, | |
| 182 net::SpawnedTestServer::kLocalhost, | |
| 183 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 184 ASSERT_TRUE(https_server.Start()); | |
| 185 | |
| 186 // Load a page with links that open in a new window. | |
| 187 std::string replacement_path; | |
| 188 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 189 "files/click-noreferrer-links.html", | |
| 190 https_server.host_port_pair(), | |
| 191 &replacement_path)); | |
| 192 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 193 | |
| 194 // Get the original SiteInstance for later comparison. | |
| 195 scoped_refptr<SiteInstance> orig_site_instance( | |
| 196 shell()->web_contents()->GetSiteInstance()); | |
| 197 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 198 | |
| 199 // Test clicking a same-site rel=noreferrer + target=foo link. | |
| 200 ShellAddedObserver new_shell_observer; | |
| 201 bool success = false; | |
| 202 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 203 shell()->web_contents(), | |
| 204 "window.domAutomationController.send(clickSameSiteNoRefTargetedLink());", | |
| 205 &success)); | |
| 206 EXPECT_TRUE(success); | |
| 207 | |
| 208 // Wait for the window to open. | |
| 209 Shell* new_shell = new_shell_observer.GetShell(); | |
| 210 | |
| 211 // Opens in new window. | |
| 212 EXPECT_EQ("/files/title2.html", | |
| 213 new_shell->web_contents()->GetVisibleURL().path()); | |
| 214 | |
| 215 // Wait for the cross-site transition in the new tab to finish. | |
| 216 WaitForLoadStop(new_shell->web_contents()); | |
| 217 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( | |
| 218 new_shell->web_contents()); | |
| 219 EXPECT_FALSE(web_contents->GetRenderManagerForTesting()-> | |
| 220 pending_render_view_host()); | |
| 221 | |
| 222 // Should have a new SiteInstance (in a new BrowsingInstance). | |
| 223 scoped_refptr<SiteInstance> noref_blank_site_instance( | |
| 224 new_shell->web_contents()->GetSiteInstance()); | |
| 225 EXPECT_NE(orig_site_instance, noref_blank_site_instance); | |
| 226 } | |
| 227 | |
| 228 // Test for crbug.com/24447. Following a cross-site link with just | |
| 229 // target=_blank should not create a new SiteInstance. | |
| 230 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 231 DontSwapProcessWithOnlyTargetBlank) { | |
| 232 // Start two servers with different sites. | |
| 233 ASSERT_TRUE(test_server()->Start()); | |
| 234 net::SpawnedTestServer https_server( | |
| 235 net::SpawnedTestServer::TYPE_HTTPS, | |
| 236 net::SpawnedTestServer::kLocalhost, | |
| 237 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 238 ASSERT_TRUE(https_server.Start()); | |
| 239 | |
| 240 // Load a page with links that open in a new window. | |
| 241 std::string replacement_path; | |
| 242 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 243 "files/click-noreferrer-links.html", | |
| 244 https_server.host_port_pair(), | |
| 245 &replacement_path)); | |
| 246 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 247 | |
| 248 // Get the original SiteInstance for later comparison. | |
| 249 scoped_refptr<SiteInstance> orig_site_instance( | |
| 250 shell()->web_contents()->GetSiteInstance()); | |
| 251 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 252 | |
| 253 // Test clicking a target=blank link. | |
| 254 ShellAddedObserver new_shell_observer; | |
| 255 bool success = false; | |
| 256 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 257 shell()->web_contents(), | |
| 258 "window.domAutomationController.send(clickTargetBlankLink());", | |
| 259 &success)); | |
| 260 EXPECT_TRUE(success); | |
| 261 | |
| 262 // Wait for the window to open. | |
| 263 Shell* new_shell = new_shell_observer.GetShell(); | |
| 264 | |
| 265 // Wait for the cross-site transition in the new tab to finish. | |
| 266 WaitForLoadStop(new_shell->web_contents()); | |
| 267 EXPECT_EQ("/files/title2.html", | |
| 268 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 269 | |
| 270 // Should have the same SiteInstance. | |
| 271 scoped_refptr<SiteInstance> blank_site_instance( | |
| 272 new_shell->web_contents()->GetSiteInstance()); | |
| 273 EXPECT_EQ(orig_site_instance, blank_site_instance); | |
| 274 } | |
| 275 | |
| 276 // Test for crbug.com/24447. Following a cross-site link with rel=noreferrer | |
| 277 // and no target=_blank should not create a new SiteInstance. | |
| 278 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 279 DontSwapProcessWithOnlyRelNoreferrer) { | |
| 280 // Start two servers with different sites. | |
| 281 ASSERT_TRUE(test_server()->Start()); | |
| 282 net::SpawnedTestServer https_server( | |
| 283 net::SpawnedTestServer::TYPE_HTTPS, | |
| 284 net::SpawnedTestServer::kLocalhost, | |
| 285 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 286 ASSERT_TRUE(https_server.Start()); | |
| 287 | |
| 288 // Load a page with links that open in a new window. | |
| 289 std::string replacement_path; | |
| 290 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 291 "files/click-noreferrer-links.html", | |
| 292 https_server.host_port_pair(), | |
| 293 &replacement_path)); | |
| 294 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 295 | |
| 296 // Get the original SiteInstance for later comparison. | |
| 297 scoped_refptr<SiteInstance> orig_site_instance( | |
| 298 shell()->web_contents()->GetSiteInstance()); | |
| 299 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 300 | |
| 301 // Test clicking a rel=noreferrer link. | |
| 302 bool success = false; | |
| 303 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 304 shell()->web_contents(), | |
| 305 "window.domAutomationController.send(clickNoRefLink());", | |
| 306 &success)); | |
| 307 EXPECT_TRUE(success); | |
| 308 | |
| 309 // Wait for the cross-site transition in the current tab to finish. | |
| 310 WaitForLoadStop(shell()->web_contents()); | |
| 311 | |
| 312 // Opens in same window. | |
| 313 EXPECT_EQ(1u, Shell::windows().size()); | |
| 314 EXPECT_EQ("/files/title2.html", | |
| 315 shell()->web_contents()->GetLastCommittedURL().path()); | |
| 316 | |
| 317 // Should have the same SiteInstance. | |
| 318 scoped_refptr<SiteInstance> noref_site_instance( | |
| 319 shell()->web_contents()->GetSiteInstance()); | |
| 320 EXPECT_EQ(orig_site_instance, noref_site_instance); | |
| 321 } | |
| 322 | |
| 323 // Test for crbug.com/116192. Targeted links should still work after the | |
| 324 // named target window has swapped processes. | |
| 325 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 326 AllowTargetedNavigationsAfterSwap) { | |
| 327 // Start two servers with different sites. | |
| 328 ASSERT_TRUE(test_server()->Start()); | |
| 329 net::SpawnedTestServer https_server( | |
| 330 net::SpawnedTestServer::TYPE_HTTPS, | |
| 331 net::SpawnedTestServer::kLocalhost, | |
| 332 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 333 ASSERT_TRUE(https_server.Start()); | |
| 334 | |
| 335 // Load a page with links that open in a new window. | |
| 336 std::string replacement_path; | |
| 337 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 338 "files/click-noreferrer-links.html", | |
| 339 https_server.host_port_pair(), | |
| 340 &replacement_path)); | |
| 341 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 342 | |
| 343 // Get the original SiteInstance for later comparison. | |
| 344 scoped_refptr<SiteInstance> orig_site_instance( | |
| 345 shell()->web_contents()->GetSiteInstance()); | |
| 346 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 347 | |
| 348 // Test clicking a target=foo link. | |
| 349 ShellAddedObserver new_shell_observer; | |
| 350 bool success = false; | |
| 351 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 352 shell()->web_contents(), | |
| 353 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 354 &success)); | |
| 355 EXPECT_TRUE(success); | |
| 356 Shell* new_shell = new_shell_observer.GetShell(); | |
| 357 | |
| 358 // Wait for the navigation in the new tab to finish, if it hasn't. | |
| 359 WaitForLoadStop(new_shell->web_contents()); | |
| 360 EXPECT_EQ("/files/navigate_opener.html", | |
| 361 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 362 | |
| 363 // Should have the same SiteInstance. | |
| 364 scoped_refptr<SiteInstance> blank_site_instance( | |
| 365 new_shell->web_contents()->GetSiteInstance()); | |
| 366 EXPECT_EQ(orig_site_instance, blank_site_instance); | |
| 367 | |
| 368 // Now navigate the new tab to a different site. | |
| 369 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 370 scoped_refptr<SiteInstance> new_site_instance( | |
| 371 new_shell->web_contents()->GetSiteInstance()); | |
| 372 EXPECT_NE(orig_site_instance, new_site_instance); | |
| 373 | |
| 374 // Clicking the original link in the first tab should cause us to swap back. | |
| 375 TestNavigationObserver navigation_observer(new_shell->web_contents()); | |
| 376 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 377 shell()->web_contents(), | |
| 378 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 379 &success)); | |
| 380 EXPECT_TRUE(success); | |
| 381 navigation_observer.Wait(); | |
| 382 | |
| 383 // Should have swapped back and shown the new window again. | |
| 384 scoped_refptr<SiteInstance> revisit_site_instance( | |
| 385 new_shell->web_contents()->GetSiteInstance()); | |
| 386 EXPECT_EQ(orig_site_instance, revisit_site_instance); | |
| 387 | |
| 388 // If it navigates away to another process, the original window should | |
| 389 // still be able to close it (using a cross-process close message). | |
| 390 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 391 EXPECT_EQ(new_site_instance, | |
| 392 new_shell->web_contents()->GetSiteInstance()); | |
| 393 WebContentsDestroyedWatcher close_watcher(new_shell->web_contents()); | |
| 394 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 395 shell()->web_contents(), | |
| 396 "window.domAutomationController.send(testCloseWindow());", | |
| 397 &success)); | |
| 398 EXPECT_TRUE(success); | |
| 399 close_watcher.Wait(); | |
| 400 } | |
| 401 | |
| 402 // Test that setting the opener to null in a window affects cross-process | |
| 403 // navigations, including those to existing entries. http://crbug.com/156669. | |
| 404 // Flaky on windows: http://crbug.com/291249 | |
| 405 #if defined(OS_WIN) | |
| 406 #define MAYBE_DisownOpener DISABLED_DisownOpener | |
| 407 #else | |
| 408 #define MAYBE_DisownOpener DisownOpener | |
| 409 #endif | |
| 410 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, MAYBE_DisownOpener) { | |
| 411 // Start two servers with different sites. | |
| 412 ASSERT_TRUE(test_server()->Start()); | |
| 413 net::SpawnedTestServer https_server( | |
| 414 net::SpawnedTestServer::TYPE_HTTPS, | |
| 415 net::SpawnedTestServer::kLocalhost, | |
| 416 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 417 ASSERT_TRUE(https_server.Start()); | |
| 418 | |
| 419 // Load a page with links that open in a new window. | |
| 420 std::string replacement_path; | |
| 421 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 422 "files/click-noreferrer-links.html", | |
| 423 https_server.host_port_pair(), | |
| 424 &replacement_path)); | |
| 425 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 426 | |
| 427 // Get the original SiteInstance for later comparison. | |
| 428 scoped_refptr<SiteInstance> orig_site_instance( | |
| 429 shell()->web_contents()->GetSiteInstance()); | |
| 430 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 431 | |
| 432 // Test clicking a target=_blank link. | |
| 433 ShellAddedObserver new_shell_observer; | |
| 434 bool success = false; | |
| 435 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 436 shell()->web_contents(), | |
| 437 "window.domAutomationController.send(clickSameSiteTargetBlankLink());", | |
| 438 &success)); | |
| 439 EXPECT_TRUE(success); | |
| 440 Shell* new_shell = new_shell_observer.GetShell(); | |
| 441 | |
| 442 // Wait for the navigation in the new tab to finish, if it hasn't. | |
| 443 WaitForLoadStop(new_shell->web_contents()); | |
| 444 EXPECT_EQ("/files/title2.html", | |
| 445 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 446 | |
| 447 // Should have the same SiteInstance. | |
| 448 scoped_refptr<SiteInstance> blank_site_instance( | |
| 449 new_shell->web_contents()->GetSiteInstance()); | |
| 450 EXPECT_EQ(orig_site_instance, blank_site_instance); | |
| 451 | |
| 452 // Now navigate the new tab to a different site. | |
| 453 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 454 scoped_refptr<SiteInstance> new_site_instance( | |
| 455 new_shell->web_contents()->GetSiteInstance()); | |
| 456 EXPECT_NE(orig_site_instance, new_site_instance); | |
| 457 | |
| 458 // Now disown the opener. | |
| 459 EXPECT_TRUE(ExecuteScript(new_shell->web_contents(), | |
| 460 "window.opener = null;")); | |
| 461 | |
| 462 // Go back and ensure the opener is still null. | |
| 463 { | |
| 464 TestNavigationObserver back_nav_load_observer(new_shell->web_contents()); | |
| 465 new_shell->web_contents()->GetController().GoBack(); | |
| 466 back_nav_load_observer.Wait(); | |
| 467 } | |
| 468 success = false; | |
| 469 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 470 new_shell->web_contents(), | |
| 471 "window.domAutomationController.send(window.opener == null);", | |
| 472 &success)); | |
| 473 EXPECT_TRUE(success); | |
| 474 | |
| 475 // Now navigate forward again (creating a new process) and check opener. | |
| 476 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 477 success = false; | |
| 478 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 479 new_shell->web_contents(), | |
| 480 "window.domAutomationController.send(window.opener == null);", | |
| 481 &success)); | |
| 482 EXPECT_TRUE(success); | |
| 483 } | |
| 484 | |
| 485 // Test that subframes can disown their openers. http://crbug.com/225528. | |
| 486 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, DisownSubframeOpener) { | |
| 487 const GURL frame_url("data:text/html,<iframe name=\"foo\"></iframe>"); | |
| 488 NavigateToURL(shell(), frame_url); | |
| 489 | |
| 490 // Give the frame an opener using window.open. | |
| 491 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), | |
| 492 "window.open('about:blank','foo');")); | |
| 493 | |
| 494 // Now disown the frame's opener. Shouldn't crash. | |
| 495 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), | |
| 496 "window.frames[0].opener = null;")); | |
| 497 } | |
| 498 | |
| 499 // Test for crbug.com/99202. PostMessage calls should still work after | |
| 500 // navigating the source and target windows to different sites. | |
| 501 // Specifically: | |
| 502 // 1) Create 3 windows (opener, "foo", and _blank) and send "foo" cross-process. | |
| 503 // 2) Fail to post a message from "foo" to opener with the wrong target origin. | |
| 504 // 3) Post a message from "foo" to opener, which replies back to "foo". | |
| 505 // 4) Post a message from _blank to "foo". | |
| 506 // 5) Post a message from "foo" to a subframe of opener, which replies back. | |
| 507 // 6) Post a message from _blank to a subframe of "foo". | |
| 508 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 509 SupportCrossProcessPostMessage) { | |
| 510 // Start two servers with different sites. | |
| 511 ASSERT_TRUE(test_server()->Start()); | |
| 512 net::SpawnedTestServer https_server( | |
| 513 net::SpawnedTestServer::TYPE_HTTPS, | |
| 514 net::SpawnedTestServer::kLocalhost, | |
| 515 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 516 ASSERT_TRUE(https_server.Start()); | |
| 517 | |
| 518 // Load a page with links that open in a new window. | |
| 519 std::string replacement_path; | |
| 520 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 521 "files/click-noreferrer-links.html", | |
| 522 https_server.host_port_pair(), | |
| 523 &replacement_path)); | |
| 524 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 525 | |
| 526 // Get the original SiteInstance and RVHM for later comparison. | |
| 527 WebContents* opener_contents = shell()->web_contents(); | |
| 528 scoped_refptr<SiteInstance> orig_site_instance( | |
| 529 opener_contents->GetSiteInstance()); | |
| 530 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 531 RenderViewHostManager* opener_manager = static_cast<WebContentsImpl*>( | |
| 532 opener_contents)->GetRenderManagerForTesting(); | |
| 533 | |
| 534 // 1) Open two more windows, one named. These initially have openers but no | |
| 535 // reference to each other. We will later post a message between them. | |
| 536 | |
| 537 // First, a named target=foo window. | |
| 538 ShellAddedObserver new_shell_observer; | |
| 539 bool success = false; | |
| 540 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 541 opener_contents, | |
| 542 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 543 &success)); | |
| 544 EXPECT_TRUE(success); | |
| 545 Shell* new_shell = new_shell_observer.GetShell(); | |
| 546 | |
| 547 // Wait for the navigation in the new window to finish, if it hasn't, then | |
| 548 // send it to post_message.html on a different site. | |
| 549 WebContents* foo_contents = new_shell->web_contents(); | |
| 550 WaitForLoadStop(foo_contents); | |
| 551 EXPECT_EQ("/files/navigate_opener.html", | |
| 552 foo_contents->GetLastCommittedURL().path()); | |
| 553 NavigateToURL(new_shell, https_server.GetURL("files/post_message.html")); | |
| 554 scoped_refptr<SiteInstance> foo_site_instance( | |
| 555 foo_contents->GetSiteInstance()); | |
| 556 EXPECT_NE(orig_site_instance, foo_site_instance); | |
| 557 | |
| 558 // Second, a target=_blank window. | |
| 559 ShellAddedObserver new_shell_observer2; | |
| 560 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 561 shell()->web_contents(), | |
| 562 "window.domAutomationController.send(clickSameSiteTargetBlankLink());", | |
| 563 &success)); | |
| 564 EXPECT_TRUE(success); | |
| 565 | |
| 566 // Wait for the navigation in the new window to finish, if it hasn't, then | |
| 567 // send it to post_message.html on the original site. | |
| 568 Shell* new_shell2 = new_shell_observer2.GetShell(); | |
| 569 WebContents* new_contents = new_shell2->web_contents(); | |
| 570 WaitForLoadStop(new_contents); | |
| 571 EXPECT_EQ("/files/title2.html", new_contents->GetLastCommittedURL().path()); | |
| 572 NavigateToURL(new_shell2, test_server()->GetURL("files/post_message.html")); | |
| 573 EXPECT_EQ(orig_site_instance, new_contents->GetSiteInstance()); | |
| 574 RenderViewHostManager* new_manager = | |
| 575 static_cast<WebContentsImpl*>(new_contents)->GetRenderManagerForTesting(); | |
| 576 | |
| 577 // We now have three windows. The opener should have a swapped out RVH | |
| 578 // for the new SiteInstance, but the _blank window should not. | |
| 579 EXPECT_EQ(3u, Shell::windows().size()); | |
| 580 EXPECT_TRUE( | |
| 581 opener_manager->GetSwappedOutRenderViewHost(foo_site_instance.get())); | |
| 582 EXPECT_FALSE( | |
| 583 new_manager->GetSwappedOutRenderViewHost(foo_site_instance.get())); | |
| 584 | |
| 585 // 2) Fail to post a message from the foo window to the opener if the target | |
| 586 // origin is wrong. We won't see an error, but we can check for the right | |
| 587 // number of received messages below. | |
| 588 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 589 foo_contents, | |
| 590 "window.domAutomationController.send(postToOpener('msg'," | |
| 591 " 'http://google.com'));", | |
| 592 &success)); | |
| 593 EXPECT_TRUE(success); | |
| 594 ASSERT_FALSE( | |
| 595 opener_manager->GetSwappedOutRenderViewHost(orig_site_instance.get())); | |
| 596 | |
| 597 // 3) Post a message from the foo window to the opener. The opener will | |
| 598 // reply, causing the foo window to update its own title. | |
| 599 base::string16 expected_title = ASCIIToUTF16("msg"); | |
| 600 TitleWatcher title_watcher(foo_contents, expected_title); | |
| 601 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 602 foo_contents, | |
| 603 "window.domAutomationController.send(postToOpener('msg','*'));", | |
| 604 &success)); | |
| 605 EXPECT_TRUE(success); | |
| 606 ASSERT_FALSE( | |
| 607 opener_manager->GetSwappedOutRenderViewHost(orig_site_instance.get())); | |
| 608 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); | |
| 609 | |
| 610 // We should have received only 1 message in the opener and "foo" tabs, | |
| 611 // and updated the title. | |
| 612 int opener_received_messages = 0; | |
| 613 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
| 614 opener_contents, | |
| 615 "window.domAutomationController.send(window.receivedMessages);", | |
| 616 &opener_received_messages)); | |
| 617 int foo_received_messages = 0; | |
| 618 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
| 619 foo_contents, | |
| 620 "window.domAutomationController.send(window.receivedMessages);", | |
| 621 &foo_received_messages)); | |
| 622 EXPECT_EQ(1, foo_received_messages); | |
| 623 EXPECT_EQ(1, opener_received_messages); | |
| 624 EXPECT_EQ(ASCIIToUTF16("msg"), foo_contents->GetTitle()); | |
| 625 | |
| 626 // 4) Now post a message from the _blank window to the foo window. The | |
| 627 // foo window will update its title and will not reply. | |
| 628 expected_title = ASCIIToUTF16("msg2"); | |
| 629 TitleWatcher title_watcher2(foo_contents, expected_title); | |
| 630 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 631 new_contents, | |
| 632 "window.domAutomationController.send(postToFoo('msg2'));", | |
| 633 &success)); | |
| 634 EXPECT_TRUE(success); | |
| 635 ASSERT_EQ(expected_title, title_watcher2.WaitAndGetTitle()); | |
| 636 | |
| 637 // This postMessage should have created a swapped out RVH for the new | |
| 638 // SiteInstance in the target=_blank window. | |
| 639 EXPECT_TRUE( | |
| 640 new_manager->GetSwappedOutRenderViewHost(foo_site_instance.get())); | |
| 641 | |
| 642 // TODO(nasko): Test subframe targeting of postMessage once | |
| 643 // http://crbug.com/153701 is fixed. | |
| 644 } | |
| 645 | |
| 646 // Test for crbug.com/278336. MessagePorts should work cross-process. I.e., | |
| 647 // messages which contain Transferables and get intercepted by | |
| 648 // RenderViewImpl::willCheckAndDispatchMessageEvent (because the RenderView is | |
| 649 // swapped out) should work. | |
| 650 // Specifically: | |
| 651 // 1) Create 2 windows (opener and "foo") and send "foo" cross-process. | |
| 652 // 2) Post a message containing a message port from opener to "foo". | |
| 653 // 3) Post a message from "foo" back to opener via the passed message port. | |
| 654 // The test will be enabled when the feature implementation lands. | |
| 655 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 656 SupportCrossProcessPostMessageWithMessagePort) { | |
| 657 // Start two servers with different sites. | |
| 658 ASSERT_TRUE(test_server()->Start()); | |
| 659 net::SpawnedTestServer https_server( | |
| 660 net::SpawnedTestServer::TYPE_HTTPS, | |
| 661 net::SpawnedTestServer::kLocalhost, | |
| 662 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 663 ASSERT_TRUE(https_server.Start()); | |
| 664 | |
| 665 // Load a page with links that open in a new window. | |
| 666 std::string replacement_path; | |
| 667 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 668 "files/click-noreferrer-links.html", | |
| 669 https_server.host_port_pair(), | |
| 670 &replacement_path)); | |
| 671 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 672 | |
| 673 // Get the original SiteInstance and RVHM for later comparison. | |
| 674 WebContents* opener_contents = shell()->web_contents(); | |
| 675 scoped_refptr<SiteInstance> orig_site_instance( | |
| 676 opener_contents->GetSiteInstance()); | |
| 677 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 678 RenderViewHostManager* opener_manager = static_cast<WebContentsImpl*>( | |
| 679 opener_contents)->GetRenderManagerForTesting(); | |
| 680 | |
| 681 // 1) Open a named target=foo window. We will later post a message between the | |
| 682 // opener and the new window. | |
| 683 ShellAddedObserver new_shell_observer; | |
| 684 bool success = false; | |
| 685 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 686 opener_contents, | |
| 687 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 688 &success)); | |
| 689 EXPECT_TRUE(success); | |
| 690 Shell* new_shell = new_shell_observer.GetShell(); | |
| 691 | |
| 692 // Wait for the navigation in the new window to finish, if it hasn't, then | |
| 693 // send it to post_message.html on a different site. | |
| 694 WebContents* foo_contents = new_shell->web_contents(); | |
| 695 WaitForLoadStop(foo_contents); | |
| 696 EXPECT_EQ("/files/navigate_opener.html", | |
| 697 foo_contents->GetLastCommittedURL().path()); | |
| 698 NavigateToURL( | |
| 699 new_shell, | |
| 700 https_server.GetURL("files/post_message.html")); | |
| 701 scoped_refptr<SiteInstance> foo_site_instance( | |
| 702 foo_contents->GetSiteInstance()); | |
| 703 EXPECT_NE(orig_site_instance, foo_site_instance); | |
| 704 | |
| 705 // We now have two windows. The opener should have a swapped out RVH | |
| 706 // for the new SiteInstance. | |
| 707 EXPECT_EQ(2u, Shell::windows().size()); | |
| 708 EXPECT_TRUE( | |
| 709 opener_manager->GetSwappedOutRenderViewHost(foo_site_instance.get())); | |
| 710 | |
| 711 // 2) Post a message containing a MessagePort from opener to the the foo | |
| 712 // window. The foo window will reply via the passed port, causing the opener | |
| 713 // to update its own title. | |
| 714 WindowedNotificationObserver title_observer( | |
| 715 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, | |
| 716 Source<WebContents>(opener_contents)); | |
| 717 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 718 opener_contents, | |
| 719 "window.domAutomationController.send(postWithPortToFoo());", | |
| 720 &success)); | |
| 721 EXPECT_TRUE(success); | |
| 722 ASSERT_FALSE( | |
| 723 opener_manager->GetSwappedOutRenderViewHost(orig_site_instance.get())); | |
| 724 title_observer.Wait(); | |
| 725 | |
| 726 // Check message counts. | |
| 727 int opener_received_messages_via_port = 0; | |
| 728 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
| 729 opener_contents, | |
| 730 "window.domAutomationController.send(window.receivedMessagesViaPort);", | |
| 731 &opener_received_messages_via_port)); | |
| 732 int foo_received_messages = 0; | |
| 733 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
| 734 foo_contents, | |
| 735 "window.domAutomationController.send(window.receivedMessages);", | |
| 736 &foo_received_messages)); | |
| 737 int foo_received_messages_with_port = 0; | |
| 738 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
| 739 foo_contents, | |
| 740 "window.domAutomationController.send(window.receivedMessagesWithPort);", | |
| 741 &foo_received_messages_with_port)); | |
| 742 EXPECT_EQ(1, foo_received_messages); | |
| 743 EXPECT_EQ(1, foo_received_messages_with_port); | |
| 744 EXPECT_EQ(1, opener_received_messages_via_port); | |
| 745 EXPECT_EQ(ASCIIToUTF16("msg-with-port"), foo_contents->GetTitle()); | |
| 746 EXPECT_EQ(ASCIIToUTF16("msg-back-via-port"), opener_contents->GetTitle()); | |
| 747 } | |
| 748 | |
| 749 // Test for crbug.com/116192. Navigations to a window's opener should | |
| 750 // still work after a process swap. | |
| 751 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 752 AllowTargetedNavigationsInOpenerAfterSwap) { | |
| 753 // Start two servers with different sites. | |
| 754 ASSERT_TRUE(test_server()->Start()); | |
| 755 net::SpawnedTestServer https_server( | |
| 756 net::SpawnedTestServer::TYPE_HTTPS, | |
| 757 net::SpawnedTestServer::kLocalhost, | |
| 758 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 759 ASSERT_TRUE(https_server.Start()); | |
| 760 | |
| 761 // Load a page with links that open in a new window. | |
| 762 std::string replacement_path; | |
| 763 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 764 "files/click-noreferrer-links.html", | |
| 765 https_server.host_port_pair(), | |
| 766 &replacement_path)); | |
| 767 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 768 | |
| 769 // Get the original tab and SiteInstance for later comparison. | |
| 770 WebContents* orig_contents = shell()->web_contents(); | |
| 771 scoped_refptr<SiteInstance> orig_site_instance( | |
| 772 orig_contents->GetSiteInstance()); | |
| 773 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 774 | |
| 775 // Test clicking a target=foo link. | |
| 776 ShellAddedObserver new_shell_observer; | |
| 777 bool success = false; | |
| 778 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 779 orig_contents, | |
| 780 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 781 &success)); | |
| 782 EXPECT_TRUE(success); | |
| 783 Shell* new_shell = new_shell_observer.GetShell(); | |
| 784 | |
| 785 // Wait for the navigation in the new window to finish, if it hasn't. | |
| 786 WaitForLoadStop(new_shell->web_contents()); | |
| 787 EXPECT_EQ("/files/navigate_opener.html", | |
| 788 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 789 | |
| 790 // Should have the same SiteInstance. | |
| 791 scoped_refptr<SiteInstance> blank_site_instance( | |
| 792 new_shell->web_contents()->GetSiteInstance()); | |
| 793 EXPECT_EQ(orig_site_instance, blank_site_instance); | |
| 794 | |
| 795 // Now navigate the original (opener) tab to a different site. | |
| 796 NavigateToURL(shell(), https_server.GetURL("files/title1.html")); | |
| 797 scoped_refptr<SiteInstance> new_site_instance( | |
| 798 shell()->web_contents()->GetSiteInstance()); | |
| 799 EXPECT_NE(orig_site_instance, new_site_instance); | |
| 800 | |
| 801 // The opened tab should be able to navigate the opener back to its process. | |
| 802 TestNavigationObserver navigation_observer(orig_contents); | |
| 803 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 804 new_shell->web_contents(), | |
| 805 "window.domAutomationController.send(navigateOpener());", | |
| 806 &success)); | |
| 807 EXPECT_TRUE(success); | |
| 808 navigation_observer.Wait(); | |
| 809 | |
| 810 // Should have swapped back into this process. | |
| 811 scoped_refptr<SiteInstance> revisit_site_instance( | |
| 812 shell()->web_contents()->GetSiteInstance()); | |
| 813 EXPECT_EQ(orig_site_instance, revisit_site_instance); | |
| 814 } | |
| 815 | |
| 816 // Test that opening a new window in the same SiteInstance and then navigating | |
| 817 // both windows to a different SiteInstance allows the first process to exit. | |
| 818 // See http://crbug.com/126333. | |
| 819 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 820 ProcessExitWithSwappedOutViews) { | |
| 821 // Start two servers with different sites. | |
| 822 ASSERT_TRUE(test_server()->Start()); | |
| 823 net::SpawnedTestServer https_server( | |
| 824 net::SpawnedTestServer::TYPE_HTTPS, | |
| 825 net::SpawnedTestServer::kLocalhost, | |
| 826 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 827 ASSERT_TRUE(https_server.Start()); | |
| 828 | |
| 829 // Load a page with links that open in a new window. | |
| 830 std::string replacement_path; | |
| 831 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 832 "files/click-noreferrer-links.html", | |
| 833 https_server.host_port_pair(), | |
| 834 &replacement_path)); | |
| 835 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 836 | |
| 837 // Get the original SiteInstance for later comparison. | |
| 838 scoped_refptr<SiteInstance> orig_site_instance( | |
| 839 shell()->web_contents()->GetSiteInstance()); | |
| 840 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 841 | |
| 842 // Test clicking a target=foo link. | |
| 843 ShellAddedObserver new_shell_observer; | |
| 844 bool success = false; | |
| 845 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 846 shell()->web_contents(), | |
| 847 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 848 &success)); | |
| 849 EXPECT_TRUE(success); | |
| 850 Shell* new_shell = new_shell_observer.GetShell(); | |
| 851 | |
| 852 // Wait for the navigation in the new window to finish, if it hasn't. | |
| 853 WaitForLoadStop(new_shell->web_contents()); | |
| 854 EXPECT_EQ("/files/navigate_opener.html", | |
| 855 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 856 | |
| 857 // Should have the same SiteInstance. | |
| 858 scoped_refptr<SiteInstance> opened_site_instance( | |
| 859 new_shell->web_contents()->GetSiteInstance()); | |
| 860 EXPECT_EQ(orig_site_instance, opened_site_instance); | |
| 861 | |
| 862 // Now navigate the opened window to a different site. | |
| 863 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 864 scoped_refptr<SiteInstance> new_site_instance( | |
| 865 new_shell->web_contents()->GetSiteInstance()); | |
| 866 EXPECT_NE(orig_site_instance, new_site_instance); | |
| 867 | |
| 868 // The original process should still be alive, since it is still used in the | |
| 869 // first window. | |
| 870 RenderProcessHost* orig_process = orig_site_instance->GetProcess(); | |
| 871 EXPECT_TRUE(orig_process->HasConnection()); | |
| 872 | |
| 873 // Navigate the first window to a different site as well. The original | |
| 874 // process should exit, since all of its views are now swapped out. | |
| 875 WindowedNotificationObserver exit_observer( | |
| 876 NOTIFICATION_RENDERER_PROCESS_TERMINATED, | |
| 877 Source<RenderProcessHost>(orig_process)); | |
| 878 NavigateToURL(shell(), https_server.GetURL("files/title1.html")); | |
| 879 exit_observer.Wait(); | |
| 880 scoped_refptr<SiteInstance> new_site_instance2( | |
| 881 shell()->web_contents()->GetSiteInstance()); | |
| 882 EXPECT_EQ(new_site_instance, new_site_instance2); | |
| 883 } | |
| 884 | |
| 885 // Test for crbug.com/76666. A cross-site navigation that fails with a 204 | |
| 886 // error should not make us ignore future renderer-initiated navigations. | |
| 887 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) { | |
| 888 // Start two servers with different sites. | |
| 889 ASSERT_TRUE(test_server()->Start()); | |
| 890 net::SpawnedTestServer https_server( | |
| 891 net::SpawnedTestServer::TYPE_HTTPS, | |
| 892 net::SpawnedTestServer::kLocalhost, | |
| 893 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 894 ASSERT_TRUE(https_server.Start()); | |
| 895 | |
| 896 // Load a page with links that open in a new window. | |
| 897 // The links will point to the HTTPS server. | |
| 898 std::string replacement_path; | |
| 899 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 900 "files/click-noreferrer-links.html", | |
| 901 https_server.host_port_pair(), | |
| 902 &replacement_path)); | |
| 903 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 904 | |
| 905 // Get the original SiteInstance for later comparison. | |
| 906 scoped_refptr<SiteInstance> orig_site_instance( | |
| 907 shell()->web_contents()->GetSiteInstance()); | |
| 908 EXPECT_TRUE(orig_site_instance.get() != NULL); | |
| 909 | |
| 910 // Load a cross-site page that fails with a 204 error. | |
| 911 NavigateToURL(shell(), https_server.GetURL("nocontent")); | |
| 912 | |
| 913 // We should still be looking at the normal page. The typed URL will | |
| 914 // still be visible until the user clears it manually, but the last | |
| 915 // committed URL will be the previous page. | |
| 916 scoped_refptr<SiteInstance> post_nav_site_instance( | |
| 917 shell()->web_contents()->GetSiteInstance()); | |
| 918 EXPECT_EQ(orig_site_instance, post_nav_site_instance); | |
| 919 EXPECT_EQ("/nocontent", | |
| 920 shell()->web_contents()->GetVisibleURL().path()); | |
| 921 EXPECT_EQ("/files/click-noreferrer-links.html", | |
| 922 shell()->web_contents()->GetController(). | |
| 923 GetLastCommittedEntry()->GetVirtualURL().path()); | |
| 924 | |
| 925 // Renderer-initiated navigations should work. | |
| 926 bool success = false; | |
| 927 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 928 shell()->web_contents(), | |
| 929 "window.domAutomationController.send(clickNoRefLink());", | |
| 930 &success)); | |
| 931 EXPECT_TRUE(success); | |
| 932 | |
| 933 // Wait for the cross-site transition in the current tab to finish. | |
| 934 WaitForLoadStop(shell()->web_contents()); | |
| 935 | |
| 936 // Opens in same tab. | |
| 937 EXPECT_EQ(1u, Shell::windows().size()); | |
| 938 EXPECT_EQ("/files/title2.html", | |
| 939 shell()->web_contents()->GetLastCommittedURL().path()); | |
| 940 | |
| 941 // Should have the same SiteInstance. | |
| 942 scoped_refptr<SiteInstance> noref_site_instance( | |
| 943 shell()->web_contents()->GetSiteInstance()); | |
| 944 EXPECT_EQ(orig_site_instance, noref_site_instance); | |
| 945 } | |
| 946 | |
| 947 // Test for crbug.com/9682. We should show the URL for a pending renderer- | |
| 948 // initiated navigation in a new tab, until the content of the initial | |
| 949 // about:blank page is modified by another window. At that point, we should | |
| 950 // revert to showing about:blank to prevent a URL spoof. | |
| 951 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ShowLoadingURLUntilSpoof) { | |
| 952 ASSERT_TRUE(test_server()->Start()); | |
| 953 | |
| 954 // Load a page that can open a URL that won't commit in a new window. | |
| 955 NavigateToURL( | |
| 956 shell(), test_server()->GetURL("files/click-nocontent-link.html")); | |
| 957 WebContents* orig_contents = shell()->web_contents(); | |
| 958 | |
| 959 // Click a /nocontent link that opens in a new window but never commits. | |
| 960 ShellAddedObserver new_shell_observer; | |
| 961 bool success = false; | |
| 962 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 963 orig_contents, | |
| 964 "window.domAutomationController.send(clickNoContentTargetedLink());", | |
| 965 &success)); | |
| 966 EXPECT_TRUE(success); | |
| 967 | |
| 968 // Wait for the window to open. | |
| 969 Shell* new_shell = new_shell_observer.GetShell(); | |
| 970 | |
| 971 // Ensure the destination URL is visible, because it is considered the | |
| 972 // initial navigation. | |
| 973 WebContents* contents = new_shell->web_contents(); | |
| 974 EXPECT_TRUE(contents->GetController().IsInitialNavigation()); | |
| 975 EXPECT_EQ("/nocontent", | |
| 976 contents->GetController().GetVisibleEntry()->GetURL().path()); | |
| 977 | |
| 978 // Now modify the contents of the new window from the opener. This will also | |
| 979 // modify the title of the document to give us something to listen for. | |
| 980 base::string16 expected_title = ASCIIToUTF16("Modified Title"); | |
| 981 TitleWatcher title_watcher(contents, expected_title); | |
| 982 success = false; | |
| 983 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 984 orig_contents, | |
| 985 "window.domAutomationController.send(modifyNewWindow());", | |
| 986 &success)); | |
| 987 EXPECT_TRUE(success); | |
| 988 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); | |
| 989 | |
| 990 // At this point, we should no longer be showing the destination URL. | |
| 991 // The visible entry should be null, resulting in about:blank in the address | |
| 992 // bar. | |
| 993 EXPECT_FALSE(contents->GetController().GetVisibleEntry()); | |
| 994 } | |
| 995 | |
| 996 // Test for crbug.com/9682. We should not show the URL for a pending renderer- | |
| 997 // initiated navigation in a new tab if it is not the initial navigation. In | |
| 998 // this case, the renderer will not notify us of a modification, so we cannot | |
| 999 // show the pending URL without allowing a spoof. | |
| 1000 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 1001 DontShowLoadingURLIfNotInitialNav) { | |
| 1002 ASSERT_TRUE(test_server()->Start()); | |
| 1003 | |
| 1004 // Load a page that can open a URL that won't commit in a new window. | |
| 1005 NavigateToURL( | |
| 1006 shell(), test_server()->GetURL("files/click-nocontent-link.html")); | |
| 1007 WebContents* orig_contents = shell()->web_contents(); | |
| 1008 | |
| 1009 // Click a /nocontent link that opens in a new window but never commits. | |
| 1010 // By using an onclick handler that first creates the window, the slow | |
| 1011 // navigation is not considered an initial navigation. | |
| 1012 ShellAddedObserver new_shell_observer; | |
| 1013 bool success = false; | |
| 1014 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 1015 orig_contents, | |
| 1016 "window.domAutomationController.send(" | |
| 1017 "clickNoContentScriptedTargetedLink());", | |
| 1018 &success)); | |
| 1019 EXPECT_TRUE(success); | |
| 1020 | |
| 1021 // Wait for the window to open. | |
| 1022 Shell* new_shell = new_shell_observer.GetShell(); | |
| 1023 | |
| 1024 // Ensure the destination URL is not visible, because it is not the initial | |
| 1025 // navigation. | |
| 1026 WebContents* contents = new_shell->web_contents(); | |
| 1027 EXPECT_FALSE(contents->GetController().IsInitialNavigation()); | |
| 1028 EXPECT_FALSE(contents->GetController().GetVisibleEntry()); | |
| 1029 } | |
| 1030 | |
| 1031 // Test for http://crbug.com/93427. Ensure that cross-site navigations | |
| 1032 // do not cause back/forward navigations to be considered stale by the | |
| 1033 // renderer. | |
| 1034 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, BackForwardNotStale) { | |
| 1035 NavigateToURL(shell(), GURL(kAboutBlankURL)); | |
| 1036 | |
| 1037 // Start two servers with different sites. | |
| 1038 ASSERT_TRUE(test_server()->Start()); | |
| 1039 net::SpawnedTestServer https_server( | |
| 1040 net::SpawnedTestServer::TYPE_HTTPS, | |
| 1041 net::SpawnedTestServer::kLocalhost, | |
| 1042 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 1043 ASSERT_TRUE(https_server.Start()); | |
| 1044 | |
| 1045 // Visit a page on first site. | |
| 1046 std::string replacement_path_a1; | |
| 1047 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 1048 "files/title1.html", | |
| 1049 test_server()->host_port_pair(), | |
| 1050 &replacement_path_a1)); | |
| 1051 NavigateToURL(shell(), test_server()->GetURL(replacement_path_a1)); | |
| 1052 | |
| 1053 // Visit three pages on second site. | |
| 1054 std::string replacement_path_b1; | |
| 1055 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 1056 "files/title1.html", | |
| 1057 https_server.host_port_pair(), | |
| 1058 &replacement_path_b1)); | |
| 1059 NavigateToURL(shell(), https_server.GetURL(replacement_path_b1)); | |
| 1060 std::string replacement_path_b2; | |
| 1061 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 1062 "files/title2.html", | |
| 1063 https_server.host_port_pair(), | |
| 1064 &replacement_path_b2)); | |
| 1065 NavigateToURL(shell(), https_server.GetURL(replacement_path_b2)); | |
| 1066 std::string replacement_path_b3; | |
| 1067 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 1068 "files/title3.html", | |
| 1069 https_server.host_port_pair(), | |
| 1070 &replacement_path_b3)); | |
| 1071 NavigateToURL(shell(), https_server.GetURL(replacement_path_b3)); | |
| 1072 | |
| 1073 // History is now [blank, A1, B1, B2, *B3]. | |
| 1074 WebContents* contents = shell()->web_contents(); | |
| 1075 EXPECT_EQ(5, contents->GetController().GetEntryCount()); | |
| 1076 | |
| 1077 // Open another window in same process to keep this process alive. | |
| 1078 Shell* new_shell = CreateBrowser(); | |
| 1079 NavigateToURL(new_shell, https_server.GetURL(replacement_path_b1)); | |
| 1080 | |
| 1081 // Go back three times to first site. | |
| 1082 { | |
| 1083 TestNavigationObserver back_nav_load_observer(shell()->web_contents()); | |
| 1084 shell()->web_contents()->GetController().GoBack(); | |
| 1085 back_nav_load_observer.Wait(); | |
| 1086 } | |
| 1087 { | |
| 1088 TestNavigationObserver back_nav_load_observer(shell()->web_contents()); | |
| 1089 shell()->web_contents()->GetController().GoBack(); | |
| 1090 back_nav_load_observer.Wait(); | |
| 1091 } | |
| 1092 { | |
| 1093 TestNavigationObserver back_nav_load_observer(shell()->web_contents()); | |
| 1094 shell()->web_contents()->GetController().GoBack(); | |
| 1095 back_nav_load_observer.Wait(); | |
| 1096 } | |
| 1097 | |
| 1098 // Now go forward twice to B2. Shouldn't be left spinning. | |
| 1099 { | |
| 1100 TestNavigationObserver forward_nav_load_observer(shell()->web_contents()); | |
| 1101 shell()->web_contents()->GetController().GoForward(); | |
| 1102 forward_nav_load_observer.Wait(); | |
| 1103 } | |
| 1104 { | |
| 1105 TestNavigationObserver forward_nav_load_observer(shell()->web_contents()); | |
| 1106 shell()->web_contents()->GetController().GoForward(); | |
| 1107 forward_nav_load_observer.Wait(); | |
| 1108 } | |
| 1109 | |
| 1110 // Go back twice to first site. | |
| 1111 { | |
| 1112 TestNavigationObserver back_nav_load_observer(shell()->web_contents()); | |
| 1113 shell()->web_contents()->GetController().GoBack(); | |
| 1114 back_nav_load_observer.Wait(); | |
| 1115 } | |
| 1116 { | |
| 1117 TestNavigationObserver back_nav_load_observer(shell()->web_contents()); | |
| 1118 shell()->web_contents()->GetController().GoBack(); | |
| 1119 back_nav_load_observer.Wait(); | |
| 1120 } | |
| 1121 | |
| 1122 // Now go forward directly to B3. Shouldn't be left spinning. | |
| 1123 { | |
| 1124 TestNavigationObserver forward_nav_load_observer(shell()->web_contents()); | |
| 1125 shell()->web_contents()->GetController().GoToIndex(4); | |
| 1126 forward_nav_load_observer.Wait(); | |
| 1127 } | |
| 1128 } | |
| 1129 | |
| 1130 // Test for http://crbug.com/130016. | |
| 1131 // Swapping out a render view should update its visiblity state. | |
| 1132 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 1133 SwappedOutViewHasCorrectVisibilityState) { | |
| 1134 // Start two servers with different sites. | |
| 1135 ASSERT_TRUE(test_server()->Start()); | |
| 1136 net::SpawnedTestServer https_server( | |
| 1137 net::SpawnedTestServer::TYPE_HTTPS, | |
| 1138 net::SpawnedTestServer::kLocalhost, | |
| 1139 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 1140 ASSERT_TRUE(https_server.Start()); | |
| 1141 | |
| 1142 // Load a page with links that open in a new window. | |
| 1143 std::string replacement_path; | |
| 1144 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( | |
| 1145 "files/click-noreferrer-links.html", | |
| 1146 https_server.host_port_pair(), | |
| 1147 &replacement_path)); | |
| 1148 NavigateToURL(shell(), test_server()->GetURL(replacement_path)); | |
| 1149 | |
| 1150 // Open a same-site link in a new widnow. | |
| 1151 ShellAddedObserver new_shell_observer; | |
| 1152 bool success = false; | |
| 1153 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 1154 shell()->web_contents(), | |
| 1155 "window.domAutomationController.send(clickSameSiteTargetedLink());", | |
| 1156 &success)); | |
| 1157 EXPECT_TRUE(success); | |
| 1158 Shell* new_shell = new_shell_observer.GetShell(); | |
| 1159 | |
| 1160 // Wait for the navigation in the new tab to finish, if it hasn't. | |
| 1161 WaitForLoadStop(new_shell->web_contents()); | |
| 1162 EXPECT_EQ("/files/navigate_opener.html", | |
| 1163 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 1164 | |
| 1165 RenderViewHost* rvh = new_shell->web_contents()->GetRenderViewHost(); | |
| 1166 | |
| 1167 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 1168 rvh, | |
| 1169 "window.domAutomationController.send(" | |
| 1170 " document.visibilityState == 'visible');", | |
| 1171 &success)); | |
| 1172 EXPECT_TRUE(success); | |
| 1173 | |
| 1174 // Now navigate the new window to a different site. This should swap out the | |
| 1175 // tab's existing RenderView, causing it become hidden. | |
| 1176 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 1177 | |
| 1178 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 1179 rvh, | |
| 1180 "window.domAutomationController.send(" | |
| 1181 " document.visibilityState == 'hidden');", | |
| 1182 &success)); | |
| 1183 EXPECT_TRUE(success); | |
| 1184 | |
| 1185 // Going back should make the previously swapped-out view to become visible | |
| 1186 // again. | |
| 1187 { | |
| 1188 TestNavigationObserver back_nav_load_observer(new_shell->web_contents()); | |
| 1189 new_shell->web_contents()->GetController().GoBack(); | |
| 1190 back_nav_load_observer.Wait(); | |
| 1191 } | |
| 1192 | |
| 1193 EXPECT_EQ("/files/navigate_opener.html", | |
| 1194 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 1195 | |
| 1196 EXPECT_EQ(rvh, new_shell->web_contents()->GetRenderViewHost()); | |
| 1197 | |
| 1198 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 1199 rvh, | |
| 1200 "window.domAutomationController.send(" | |
| 1201 " document.visibilityState == 'visible');", | |
| 1202 &success)); | |
| 1203 EXPECT_TRUE(success); | |
| 1204 } | |
| 1205 | |
| 1206 // This class ensures that all the given RenderViewHosts have properly been | |
| 1207 // shutdown. | |
| 1208 class RenderViewHostDestructionObserver : public WebContentsObserver { | |
| 1209 public: | |
| 1210 explicit RenderViewHostDestructionObserver(WebContents* web_contents) | |
| 1211 : WebContentsObserver(web_contents) {} | |
| 1212 virtual ~RenderViewHostDestructionObserver() {} | |
| 1213 void EnsureRVHGetsDestructed(RenderViewHost* rvh) { | |
| 1214 watched_render_view_hosts_.insert(rvh); | |
| 1215 } | |
| 1216 size_t GetNumberOfWatchedRenderViewHosts() const { | |
| 1217 return watched_render_view_hosts_.size(); | |
| 1218 } | |
| 1219 | |
| 1220 private: | |
| 1221 // WebContentsObserver implementation: | |
| 1222 virtual void RenderViewDeleted(RenderViewHost* rvh) OVERRIDE { | |
| 1223 watched_render_view_hosts_.erase(rvh); | |
| 1224 } | |
| 1225 | |
| 1226 std::set<RenderViewHost*> watched_render_view_hosts_; | |
| 1227 }; | |
| 1228 | |
| 1229 // Test for crbug.com/90867. Make sure we don't leak render view hosts since | |
| 1230 // they may cause crashes or memory corruptions when trying to call dead | |
| 1231 // delegate_. This test also verifies crbug.com/117420 and crbug.com/143255 to | |
| 1232 // ensure that a separate SiteInstance is created when navigating to view-source | |
| 1233 // URLs, regardless of current URL. | |
| 1234 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, LeakingRenderViewHosts) { | |
| 1235 // Start two servers with different sites. | |
| 1236 ASSERT_TRUE(test_server()->Start()); | |
| 1237 net::SpawnedTestServer https_server( | |
| 1238 net::SpawnedTestServer::TYPE_HTTPS, | |
| 1239 net::SpawnedTestServer::kLocalhost, | |
| 1240 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 1241 ASSERT_TRUE(https_server.Start()); | |
| 1242 | |
| 1243 // Observe the created render_view_host's to make sure they will not leak. | |
| 1244 RenderViewHostDestructionObserver rvh_observers(shell()->web_contents()); | |
| 1245 | |
| 1246 GURL navigated_url(test_server()->GetURL("files/title2.html")); | |
| 1247 GURL view_source_url(kViewSourceScheme + std::string(":") + | |
| 1248 navigated_url.spec()); | |
| 1249 | |
| 1250 // Let's ensure that when we start with a blank window, navigating away to a | |
| 1251 // view-source URL, we create a new SiteInstance. | |
| 1252 RenderViewHost* blank_rvh = shell()->web_contents()->GetRenderViewHost(); | |
| 1253 SiteInstance* blank_site_instance = blank_rvh->GetSiteInstance(); | |
| 1254 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), GURL::EmptyGURL()); | |
| 1255 EXPECT_EQ(blank_site_instance->GetSiteURL(), GURL::EmptyGURL()); | |
| 1256 rvh_observers.EnsureRVHGetsDestructed(blank_rvh); | |
| 1257 | |
| 1258 // Now navigate to the view-source URL and ensure we got a different | |
| 1259 // SiteInstance and RenderViewHost. | |
| 1260 NavigateToURL(shell(), view_source_url); | |
| 1261 EXPECT_NE(blank_rvh, shell()->web_contents()->GetRenderViewHost()); | |
| 1262 EXPECT_NE(blank_site_instance, shell()->web_contents()-> | |
| 1263 GetRenderViewHost()->GetSiteInstance()); | |
| 1264 rvh_observers.EnsureRVHGetsDestructed( | |
| 1265 shell()->web_contents()->GetRenderViewHost()); | |
| 1266 | |
| 1267 // Load a random page and then navigate to view-source: of it. | |
| 1268 // This used to cause two RVH instances for the same SiteInstance, which | |
| 1269 // was a problem. This is no longer the case. | |
| 1270 NavigateToURL(shell(), navigated_url); | |
| 1271 SiteInstance* site_instance1 = shell()->web_contents()-> | |
| 1272 GetRenderViewHost()->GetSiteInstance(); | |
| 1273 rvh_observers.EnsureRVHGetsDestructed( | |
| 1274 shell()->web_contents()->GetRenderViewHost()); | |
| 1275 | |
| 1276 NavigateToURL(shell(), view_source_url); | |
| 1277 rvh_observers.EnsureRVHGetsDestructed( | |
| 1278 shell()->web_contents()->GetRenderViewHost()); | |
| 1279 SiteInstance* site_instance2 = shell()->web_contents()-> | |
| 1280 GetRenderViewHost()->GetSiteInstance(); | |
| 1281 | |
| 1282 // Ensure that view-source navigations force a new SiteInstance. | |
| 1283 EXPECT_NE(site_instance1, site_instance2); | |
| 1284 | |
| 1285 // Now navigate to a different instance so that we swap out again. | |
| 1286 NavigateToURL(shell(), https_server.GetURL("files/title2.html")); | |
| 1287 rvh_observers.EnsureRVHGetsDestructed( | |
| 1288 shell()->web_contents()->GetRenderViewHost()); | |
| 1289 | |
| 1290 // This used to leak a render view host. | |
| 1291 shell()->Close(); | |
| 1292 | |
| 1293 RunAllPendingInMessageLoop(); // Needed on ChromeOS. | |
| 1294 | |
| 1295 EXPECT_EQ(0U, rvh_observers.GetNumberOfWatchedRenderViewHosts()); | |
| 1296 } | |
| 1297 | |
| 1298 // Test for crbug.com/143155. Frame tree updates during unload should not | |
| 1299 // interrupt the intended navigation and show swappedout:// instead. | |
| 1300 // Specifically: | |
| 1301 // 1) Open 2 tabs in an HTTP SiteInstance, with a subframe in the opener. | |
| 1302 // 2) Send the second tab to a different HTTPS SiteInstance. | |
| 1303 // This creates a swapped out opener for the first tab in the HTTPS process. | |
| 1304 // 3) Navigate the first tab to the HTTPS SiteInstance, and have the first | |
| 1305 // tab's unload handler remove its frame. | |
| 1306 // This used to cause an update to the frame tree of the swapped out RV, | |
| 1307 // just as it was navigating to a real page. That pre-empted the real | |
| 1308 // navigation and visibly sent the tab to swappedout://. | |
| 1309 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, | |
| 1310 DontPreemptNavigationWithFrameTreeUpdate) { | |
| 1311 // Start two servers with different sites. | |
| 1312 ASSERT_TRUE(test_server()->Start()); | |
| 1313 net::SpawnedTestServer https_server( | |
| 1314 net::SpawnedTestServer::TYPE_HTTPS, | |
| 1315 net::SpawnedTestServer::kLocalhost, | |
| 1316 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
| 1317 ASSERT_TRUE(https_server.Start()); | |
| 1318 | |
| 1319 // 1. Load a page that deletes its iframe during unload. | |
| 1320 NavigateToURL(shell(), | |
| 1321 test_server()->GetURL("files/remove_frame_on_unload.html")); | |
| 1322 | |
| 1323 // Get the original SiteInstance for later comparison. | |
| 1324 scoped_refptr<SiteInstance> orig_site_instance( | |
| 1325 shell()->web_contents()->GetSiteInstance()); | |
| 1326 | |
| 1327 // Open a same-site page in a new window. | |
| 1328 ShellAddedObserver new_shell_observer; | |
| 1329 bool success = false; | |
| 1330 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
| 1331 shell()->web_contents(), | |
| 1332 "window.domAutomationController.send(openWindow());", | |
| 1333 &success)); | |
| 1334 EXPECT_TRUE(success); | |
| 1335 Shell* new_shell = new_shell_observer.GetShell(); | |
| 1336 | |
| 1337 // Wait for the navigation in the new window to finish, if it hasn't. | |
| 1338 WaitForLoadStop(new_shell->web_contents()); | |
| 1339 EXPECT_EQ("/files/title1.html", | |
| 1340 new_shell->web_contents()->GetLastCommittedURL().path()); | |
| 1341 | |
| 1342 // Should have the same SiteInstance. | |
| 1343 EXPECT_EQ(orig_site_instance, new_shell->web_contents()->GetSiteInstance()); | |
| 1344 | |
| 1345 // 2. Send the second tab to a different process. | |
| 1346 NavigateToURL(new_shell, https_server.GetURL("files/title1.html")); | |
| 1347 scoped_refptr<SiteInstance> new_site_instance( | |
| 1348 new_shell->web_contents()->GetSiteInstance()); | |
| 1349 EXPECT_NE(orig_site_instance, new_site_instance); | |
| 1350 | |
| 1351 // 3. Send the first tab to the second tab's process. | |
| 1352 NavigateToURL(shell(), https_server.GetURL("files/title1.html")); | |
| 1353 | |
| 1354 // Make sure it ends up at the right page. | |
| 1355 WaitForLoadStop(shell()->web_contents()); | |
| 1356 EXPECT_EQ(https_server.GetURL("files/title1.html"), | |
| 1357 shell()->web_contents()->GetLastCommittedURL()); | |
| 1358 EXPECT_EQ(new_site_instance, shell()->web_contents()->GetSiteInstance()); | |
| 1359 } | |
| 1360 | |
| 1361 } // namespace content | |
| OLD | NEW |