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

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

Issue 10827078: Support frame tree propagation between renderers in the same browsing instance. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes based on more comments from Albert. Created 8 years, 4 months 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/json/json_reader.h"
6 #include "base/memory/ref_counted.h" 7 #include "base/memory/ref_counted.h"
7 #include "base/path_service.h" 8 #include "base/path_service.h"
8 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "content/common/renderer_constants.h"
9 #include "content/browser/renderer_host/render_view_host_impl.h" 11 #include "content/browser/renderer_host/render_view_host_impl.h"
10 #include "content/browser/site_instance_impl.h" 12 #include "content/browser/site_instance_impl.h"
11 #include "content/browser/web_contents/web_contents_impl.h" 13 #include "content/browser/web_contents/web_contents_impl.h"
12 #include "content/public/browser/navigation_controller.h" 14 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/navigation_entry.h" 15 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/notification_details.h" 16 #include "content/public/browser/notification_details.h"
15 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_observer.h"
16 #include "content/public/browser/notification_registrar.h" 18 #include "content/public/browser/notification_registrar.h"
17 #include "content/public/browser/notification_types.h" 19 #include "content/public/browser/notification_types.h"
18 #include "content/public/browser/render_process_host.h" 20 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/render_view_host_observer.h" 21 #include "content/public/browser/render_view_host_observer.h"
20 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
21 #include "content/public/common/url_constants.h" 23 #include "content/public/common/url_constants.h"
22 #include "content/public/test/browser_test_utils.h" 24 #include "content/public/test/browser_test_utils.h"
23 #include "content/public/test/test_utils.h" 25 #include "content/public/test/test_utils.h"
24 #include "content/shell/shell.h" 26 #include "content/shell/shell.h"
25 #include "content/test/content_browser_test.h" 27 #include "content/test/content_browser_test.h"
26 #include "content/test/content_browser_test_utils.h" 28 #include "content/test/content_browser_test_utils.h"
27 #include "net/base/net_util.h" 29 #include "net/base/net_util.h"
28 #include "net/test/test_server.h" 30 #include "net/test/test_server.h"
29 31
32 namespace {
33
34 bool CompareTrees(base::DictionaryValue* first, base::DictionaryValue* second) {
35 string16 name1;
36 string16 name2;
37 if (!first->GetString(content::kFrameTreeNodeNameKey, &name1) ||
38 !second->GetString(content::kFrameTreeNodeNameKey, &name2))
39 return false;
Charlie Reis 2012/08/22 22:08:34 Should this be return false, or a failed EXPECT?
nasko 2012/08/23 21:55:53 No. The semantics of this function is just to retu
Charlie Reis 2012/08/24 23:26:07 I just meant that we always expect the GetString (
40 if (name1 != name2)
41 return false;
42
43 int id1 = 0;
44 int id2 = 0;
45 if (!first->GetInteger(content::kFrameTreeNodeIdKey, &id1) ||
46 !second->GetInteger(content::kFrameTreeNodeIdKey, &id2))
47 return false;
48 if (id1 != id2)
49 return false;
50
51 ListValue* subtree1 = NULL;
52 ListValue* subtree2 = NULL;
53 bool result1 = first->GetList(content::kFrameTreeNodeSubtreeKey, &subtree1);
54 bool result2 = second->GetList(content::kFrameTreeNodeSubtreeKey, &subtree2);
55 if (!result1 && !result2)
56 return true;
57 if (!result1 || !result2)
58 return false;
59
60 if (subtree1->GetSize() != subtree2->GetSize())
61 return false;
62
63 base::DictionaryValue* child1 = NULL;
64 base::DictionaryValue* child2 = NULL;
65 for (size_t i = 0; i < subtree1->GetSize(); ++i) {
66 if (!subtree1->GetDictionary(i, &child1) ||
67 !subtree2->GetDictionary(i, &child2))
Charlie Reis 2012/08/22 22:08:34 nit: Needs braces, since condition doesn't fit on
nasko 2012/08/23 21:55:53 Done.
68 return false;
69 if (!CompareTrees(child1, child2))
70 return false;
71 }
72
73 return true;
74 }
75
76 base::DictionaryValue* GetTree(content::RenderViewHostImpl* rvh) {
77 std::string frame_tree = rvh->frame_tree();
78 EXPECT_FALSE(frame_tree.empty());
79 base::Value* v = base::JSONReader::Read(frame_tree);
80 base::DictionaryValue* tree = NULL;
81 EXPECT_TRUE(v->IsType(base::Value::TYPE_DICTIONARY));
82 EXPECT_TRUE(v->GetAsDictionary(&tree));
83 return tree;
84 }
85
86 } // namespace
87
30 namespace content { 88 namespace content {
31 89
32 class RenderViewHostManagerTest : public ContentBrowserTest { 90 class RenderViewHostManagerTest : public ContentBrowserTest {
33 public: 91 public:
34 RenderViewHostManagerTest() {} 92 RenderViewHostManagerTest() {}
35 93
36 static bool GetFilePathWithHostAndPortReplacement( 94 static bool GetFilePathWithHostAndPortReplacement(
37 const std::string& original_file_path, 95 const std::string& original_file_path,
38 const net::HostPortPair& host_port_pair, 96 const net::HostPortPair& host_port_pair,
39 std::string* replacement_path) { 97 std::string* replacement_path) {
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 EXPECT_TRUE(success); 452 EXPECT_TRUE(success);
395 close_observer.Wait(); 453 close_observer.Wait();
396 } 454 }
397 455
398 // Test for crbug.com/99202. PostMessage calls should still work after 456 // Test for crbug.com/99202. PostMessage calls should still work after
399 // navigating the source and target windows to different sites. 457 // navigating the source and target windows to different sites.
400 // Specifically: 458 // Specifically:
401 // 1) Create 3 windows (opener, "foo", and _blank) and send "foo" cross-process. 459 // 1) Create 3 windows (opener, "foo", and _blank) and send "foo" cross-process.
402 // 2) Fail to post a message from "foo" to opener with the wrong target origin. 460 // 2) Fail to post a message from "foo" to opener with the wrong target origin.
403 // 3) Post a message from "foo" to opener, which replies back to "foo". 461 // 3) Post a message from "foo" to opener, which replies back to "foo".
404 // 4) Post a message from _blank to "foo". 462 // 4) Post a message from _blank to "foo".
Charlie Reis 2012/08/22 22:08:34 Please briefly describe steps 5 and 6 as well.
nasko 2012/08/23 21:55:53 Done.
405 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, 463 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
406 SupportCrossProcessPostMessage) { 464 SupportCrossProcessPostMessage) {
407 // Start two servers with different sites. 465 // Start two servers with different sites.
408 ASSERT_TRUE(test_server()->Start()); 466 ASSERT_TRUE(test_server()->Start());
409 net::TestServer https_server( 467 net::TestServer https_server(
410 net::TestServer::TYPE_HTTPS, 468 net::TestServer::TYPE_HTTPS,
411 net::TestServer::kLocalhost, 469 net::TestServer::kLocalhost,
412 FilePath(FILE_PATH_LITERAL("content/test/data"))); 470 FilePath(FILE_PATH_LITERAL("content/test/data")));
413 ASSERT_TRUE(https_server.Start()); 471 ASSERT_TRUE(https_server.Start());
414 472
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 537
480 // 2) Fail to post a message from the foo window to the opener if the target 538 // 2) Fail to post a message from the foo window to the opener if the target
481 // origin is wrong. We won't see an error, but we can check for the right 539 // origin is wrong. We won't see an error, but we can check for the right
482 // number of received messages below. 540 // number of received messages below.
483 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( 541 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
484 foo_contents->GetRenderViewHost(), L"", 542 foo_contents->GetRenderViewHost(), L"",
485 L"window.domAutomationController.send(postToOpener('msg'," 543 L"window.domAutomationController.send(postToOpener('msg',"
486 L"'http://google.com'));", 544 L"'http://google.com'));",
487 &success)); 545 &success));
488 EXPECT_TRUE(success); 546 EXPECT_TRUE(success);
547 ASSERT_FALSE(opener_manager->GetSwappedOutRenderViewHost(orig_site_instance));
489 548
490 // 3) Post a message from the foo window to the opener. The opener will 549 // 3) Post a message from the foo window to the opener. The opener will
491 // reply, causing the foo window to update its own title. 550 // reply, causing the foo window to update its own title.
492 WindowedNotificationObserver title_observer( 551 WindowedNotificationObserver title_observer(
493 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, 552 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
494 Source<WebContents>(foo_contents)); 553 Source<WebContents>(foo_contents));
495 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( 554 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
496 foo_contents->GetRenderViewHost(), L"", 555 foo_contents->GetRenderViewHost(), L"",
497 L"window.domAutomationController.send(postToOpener('msg','*'));", 556 L"window.domAutomationController.send(postToOpener('msg','*'));",
498 &success)); 557 &success));
499 EXPECT_TRUE(success); 558 EXPECT_TRUE(success);
559 ASSERT_FALSE(opener_manager->GetSwappedOutRenderViewHost(orig_site_instance));
500 title_observer.Wait(); 560 title_observer.Wait();
501 561
502 // We should have received only 1 message in the opener and "foo" tabs, 562 // We should have received only 1 message in the opener and "foo" tabs,
503 // and updated the title. 563 // and updated the title.
504 int opener_received_messages = 0; 564 int opener_received_messages = 0;
505 EXPECT_TRUE(ExecuteJavaScriptAndExtractInt( 565 EXPECT_TRUE(ExecuteJavaScriptAndExtractInt(
506 opener_contents->GetRenderViewHost(), L"", 566 opener_contents->GetRenderViewHost(), L"",
507 L"window.domAutomationController.send(window.receivedMessages);", 567 L"window.domAutomationController.send(window.receivedMessages);",
508 &opener_received_messages)); 568 &opener_received_messages));
509 int foo_received_messages = 0; 569 int foo_received_messages = 0;
(...skipping 14 matching lines...) Expand all
524 new_contents->GetRenderViewHost(), L"", 584 new_contents->GetRenderViewHost(), L"",
525 L"window.domAutomationController.send(postToFoo('msg2'));", 585 L"window.domAutomationController.send(postToFoo('msg2'));",
526 &success)); 586 &success));
527 EXPECT_TRUE(success); 587 EXPECT_TRUE(success);
528 title_observer2.Wait(); 588 title_observer2.Wait();
529 EXPECT_EQ(ASCIIToUTF16("msg2"), foo_contents->GetTitle()); 589 EXPECT_EQ(ASCIIToUTF16("msg2"), foo_contents->GetTitle());
530 590
531 // This postMessage should have created a swapped out RVH for the new 591 // This postMessage should have created a swapped out RVH for the new
532 // SiteInstance in the target=_blank window. 592 // SiteInstance in the target=_blank window.
533 EXPECT_TRUE(new_manager->GetSwappedOutRenderViewHost(foo_site_instance)); 593 EXPECT_TRUE(new_manager->GetSwappedOutRenderViewHost(foo_site_instance));
594
595 NavigateToURL(new_shell, https_server.GetURL("files/post_message2.html"));
596
597 // 5) Now verify that posting a message from the foo window to a subframe of
598 // the opener window works fine. The opener subframe will reply, causing the
599 // foo window to update its own title.
600 WindowedNotificationObserver title_observer3(
601 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
602 Source<WebContents>(new_shell->web_contents()));
603 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
604 foo_contents->GetRenderViewHost(), L"",
605 L"window.domAutomationController.send(postToOpenerFrame('msg3','*'));",
606 &success));
607 EXPECT_TRUE(success);
608 title_observer3.Wait();
609 EXPECT_EQ(ASCIIToUTF16("msg3"), new_shell->web_contents()->GetTitle());
610
611 // 5) Lastly, verify that the _blank window can post a message to subframe
Charlie Reis 2012/08/22 22:08:34 nit: This should be 6. Also, "to a subframe"
nasko 2012/08/23 21:55:53 Done.
612 // of the foo window. The subframe of foo will set the foo window title and
613 // will reply, setting the _blank window title.
614 WindowedNotificationObserver title_observer4(
615 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
616 Source<WebContents>(new_shell2->web_contents()));
617 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
618 new_contents->GetRenderViewHost(), L"",
619 L"window.domAutomationController.send(postToFooFrame('msg4'));",
620 &success));
621 EXPECT_TRUE(success);
622 title_observer4.Wait();
623 EXPECT_EQ(ASCIIToUTF16("msg4"), new_shell2->web_contents()->GetTitle());
534 } 624 }
535 625
536 // Test for crbug.com/116192. Navigations to a window's opener should 626 // Test for crbug.com/116192. Navigations to a window's opener should
537 // still work after a process swap. 627 // still work after a process swap.
538 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, 628 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
539 AllowTargetedNavigationsInOpenerAfterSwap) { 629 AllowTargetedNavigationsInOpenerAfterSwap) {
540 // Start two servers with different sites. 630 // Start two servers with different sites.
541 ASSERT_TRUE(test_server()->Start()); 631 ASSERT_TRUE(test_server()->Start());
542 net::TestServer https_server( 632 net::TestServer https_server(
543 net::TestServer::TYPE_HTTPS, 633 net::TestServer::TYPE_HTTPS,
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 rvh_observers.AddObserverToRVH(shell()->web_contents()->GetRenderViewHost()); 1122 rvh_observers.AddObserverToRVH(shell()->web_contents()->GetRenderViewHost());
1033 1123
1034 // This used to leak a render view host. 1124 // This used to leak a render view host.
1035 shell()->Close(); 1125 shell()->Close();
1036 1126
1037 RunAllPendingInMessageLoop(); // Needed on ChromeOS. 1127 RunAllPendingInMessageLoop(); // Needed on ChromeOS.
1038 1128
1039 EXPECT_EQ(0U, rvh_observers.GetNumObservers()); 1129 EXPECT_EQ(0U, rvh_observers.GetNumObservers());
1040 } 1130 }
1041 1131
1132 // Test for correct propagation of frames hierarchy across processes in the
Charlie Reis 2012/08/22 22:08:34 nit: frames -> the frame
nasko 2012/08/23 21:55:53 Done.
1133 // same browsing context. The test starts by navigating to a page that has
Charlie Reis 2012/08/22 22:08:34 nit: browsing context -> BrowsingInstance
nasko 2012/08/23 21:55:53 Done.
1134 // multiple nested frames. It then opens two windows and navigates each one
1135 // to a separate site, so at the end we have 3 site instances. It checks
Charlie Reis 2012/08/22 22:08:34 nit: site instances -> SiteInstances.
nasko 2012/08/23 21:55:53 Done.
1136 // that frame trees are kept in sync through navigations, reloading, and
1137 // JavaScript manipulation of the frame tree.
1138 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, FrameTreeUpdates) {
1139 // Start two servers to allow using different sites.
1140 EXPECT_TRUE(test_server()->Start());
1141 net::TestServer https_server(
1142 net::TestServer::TYPE_HTTPS,
1143 net::TestServer::kLocalhost,
1144 FilePath(FILE_PATH_LITERAL("content/test/data")));
1145 EXPECT_TRUE(https_server.Start());
1146
1147 GURL frame_tree_url(test_server()->GetURL("files/frame_tree/top.html"));
1148
1149 // Replace the 127.0.0.1 with localhost, which will give us a different
1150 // site instance.
1151 GURL::Replacements replacements;
1152 std::string new_host("localhost");
1153 replacements.SetHostStr(new_host);
1154 GURL remote_frame = test_server()->GetURL(
1155 "files/frame_tree/1-1.html").ReplaceComponents(replacements);
1156
1157 bool success = false;
1158 base::DictionaryValue* frames = NULL;
1159 base::ListValue* subtree = NULL;
1160
1161 NavigateToURL(shell(), test_server()->GetURL("files/simple_page.html"));
1162 WebContents* opener_contents = shell()->web_contents();
1163 RenderViewHostManager* opener_rvhm = static_cast<WebContentsImpl*>(
1164 opener_contents)->GetRenderManagerForTesting();
1165 frames = GetTree(opener_rvhm->current_host());
1166 EXPECT_FALSE(frames->GetList(content::kFrameTreeNodeSubtreeKey, &subtree));
1167
1168 NavigateToURL(shell(), frame_tree_url);
1169 frames = GetTree(opener_rvhm->current_host());
1170 EXPECT_TRUE(frames->GetList(content::kFrameTreeNodeSubtreeKey, &subtree));
1171 EXPECT_TRUE(subtree->GetSize() == 3);
1172
1173 scoped_refptr<SiteInstance> orig_site_instance(
1174 opener_contents->GetSiteInstance());
1175 EXPECT_TRUE(orig_site_instance != NULL);
1176
1177 ShellAddedObserver shell_observer1;
1178 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
1179 opener_contents->GetRenderViewHost(), L"",
1180 L"window.domAutomationController.send(openWindow('1-3.html'));",
1181 &success));
1182 EXPECT_TRUE(success);
1183
1184 Shell* shell1 = shell_observer1.GetShell();
1185 WebContents* contents1 = shell1->web_contents();
1186 WaitForLoadStop(contents1);
1187 RenderViewHostManager* rvhm1 = static_cast<WebContentsImpl*>(
1188 contents1)->GetRenderManagerForTesting();
1189 EXPECT_EQ("/files/frame_tree/1-3.html", contents1->GetURL().path());
1190
1191 NavigateToURL(shell1, https_server.GetURL("files/title1.html"));
1192 EXPECT_EQ("/files/title1.html", contents1->GetURL().path());
1193 scoped_refptr<SiteInstance> site_instance1(
1194 contents1->GetSiteInstance());
1195 EXPECT_NE(orig_site_instance, site_instance1);
1196
1197 ShellAddedObserver shell_observer2;
1198 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
1199 opener_contents->GetRenderViewHost(), L"",
1200 L"window.domAutomationController.send(openWindow('../title2.html'));",
1201 &success));
1202 EXPECT_TRUE(success);
1203
1204 Shell* shell2 = shell_observer2.GetShell();
1205 WebContents* contents2 = shell2->web_contents();
1206 WaitForLoadStop(contents2);
1207 EXPECT_EQ("/files/title2.html", contents2->GetURL().path());
1208
1209 NavigateToURL(shell2, remote_frame);
1210 EXPECT_EQ("/files/frame_tree/1-1.html", contents2->GetURL().path());
1211 scoped_refptr<SiteInstance> site_instance2(
1212 contents2->GetSiteInstance());
1213 EXPECT_NE(orig_site_instance, site_instance2);
1214 EXPECT_NE(site_instance1, site_instance2);
1215
1216 RenderViewHostManager* rvhm2 = static_cast<WebContentsImpl*>(
1217 contents2)->GetRenderManagerForTesting();
1218
1219 EXPECT_TRUE(CompareTrees(
1220 GetTree(opener_rvhm->current_host()),
1221 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1222 rvhm1->current_host()->GetSiteInstance()))));
Charlie Reis 2012/08/22 22:08:34 Maybe grab a reference to this SiteInstance to mak
nasko 2012/08/23 21:55:53 Done.
1223 EXPECT_TRUE(CompareTrees(
1224 GetTree(opener_rvhm->current_host()),
1225 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1226 rvhm2->current_host()->GetSiteInstance()))));
1227
1228 EXPECT_TRUE(CompareTrees(
1229 GetTree(rvhm1->current_host()),
1230 GetTree(rvhm1->GetSwappedOutRenderViewHost(
1231 opener_rvhm->current_host()->GetSiteInstance()))));
1232 EXPECT_TRUE(CompareTrees(
1233 GetTree(rvhm2->current_host()),
1234 GetTree(rvhm2->GetSwappedOutRenderViewHost(
1235 opener_rvhm->current_host()->GetSiteInstance()))));
1236
1237 EXPECT_FALSE(CompareTrees(
1238 GetTree(opener_rvhm->current_host()), GetTree(rvhm1->current_host())));
1239 EXPECT_FALSE(CompareTrees(
1240 GetTree(opener_rvhm->current_host()), GetTree(rvhm2->current_host())));
1241
1242 // Reload the original page, which will cause subframe ids to change. This
1243 // will ensure that the ids are properly replicated across reload.
1244 NavigateToURL(shell(), frame_tree_url);
1245
1246 EXPECT_TRUE(CompareTrees(
1247 GetTree(opener_rvhm->current_host()),
1248 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1249 rvhm1->current_host()->GetSiteInstance()))));
1250 EXPECT_TRUE(CompareTrees(
1251 GetTree(opener_rvhm->current_host()),
1252 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1253 rvhm2->current_host()->GetSiteInstance()))));
1254
1255 EXPECT_FALSE(CompareTrees(
1256 GetTree(opener_rvhm->current_host()), GetTree(rvhm1->current_host())));
1257 EXPECT_FALSE(CompareTrees(
1258 GetTree(opener_rvhm->current_host()), GetTree(rvhm2->current_host())));
1259
1260 // Now let's ensure that using JS to add/remove frames results in proper
1261 // updates.
1262 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
1263 opener_contents->GetRenderViewHost(), L"",
1264 L"window.domAutomationController.send(removeFrame());",
1265 &success));
1266 EXPECT_TRUE(success);
1267 frames = GetTree(opener_rvhm->current_host());
1268 EXPECT_TRUE(frames->GetList(content::kFrameTreeNodeSubtreeKey, &subtree));
1269 EXPECT_TRUE(subtree->GetSize() == 2);
1270
1271 WindowedNotificationObserver title_observer(
1272 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
1273 Source<WebContents>(opener_contents));
1274 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
1275 opener_contents->GetRenderViewHost(), L"",
1276 L"window.domAutomationController.send(addFrame());",
1277 &success));
1278 EXPECT_TRUE(success);
1279 title_observer.Wait();
1280
1281 frames = GetTree(opener_rvhm->current_host());
1282 EXPECT_TRUE(frames->GetList(content::kFrameTreeNodeSubtreeKey, &subtree));
1283 EXPECT_TRUE(subtree->GetSize() == 3);
1284
1285 EXPECT_TRUE(CompareTrees(
1286 GetTree(opener_rvhm->current_host()),
1287 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1288 rvhm1->current_host()->GetSiteInstance()))));
1289 EXPECT_TRUE(CompareTrees(
1290 GetTree(opener_rvhm->current_host()),
1291 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1292 rvhm2->current_host()->GetSiteInstance()))));
1293 }
1294
1042 } // namespace content 1295 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698