Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(372)

Side by Side Diff: content/browser/renderer_host/render_view_host_manager_browsertest.cc

Issue 92153003: Rename RenderViewHostManager to RenderFrameHostManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_view_host_delegate.h ('k') | content/browser/site_instance_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698