Chromium Code Reviews| Index: content/browser/renderer_host/render_view_host_manager_browsertest.cc |
| diff --git a/content/browser/renderer_host/render_view_host_manager_browsertest.cc b/content/browser/renderer_host/render_view_host_manager_browsertest.cc |
| index 657f005895c460dc09a3acecd147c765d303c1fb..7b511673e081f22d1cc2da435af677ee01424b2d 100644 |
| --- a/content/browser/renderer_host/render_view_host_manager_browsertest.cc |
| +++ b/content/browser/renderer_host/render_view_host_manager_browsertest.cc |
| @@ -3,6 +3,7 @@ |
| // found in the LICENSE file. |
| #include "base/file_util.h" |
| +#include "base/json/json_reader.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/path_service.h" |
| #include "base/utf_string_conversions.h" |
| @@ -486,6 +487,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, |
| L"'http://google.com'));", |
| &success)); |
| EXPECT_TRUE(success); |
| + ASSERT_FALSE(opener_manager->GetSwappedOutRenderViewHost(orig_site_instance)); |
| // 3) Post a message from the foo window to the opener. The opener will |
| // reply, causing the foo window to update its own title. |
| @@ -497,6 +499,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, |
| L"window.domAutomationController.send(postToOpener('msg','*'));", |
| &success)); |
| EXPECT_TRUE(success); |
| + ASSERT_FALSE(opener_manager->GetSwappedOutRenderViewHost(orig_site_instance)); |
| title_observer.Wait(); |
| // We should have received only 1 message in the opener and "foo" tabs, |
| @@ -531,6 +534,36 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, |
| // This postMessage should have created a swapped out RVH for the new |
| // SiteInstance in the target=_blank window. |
| EXPECT_TRUE(new_manager->GetSwappedOutRenderViewHost(foo_site_instance)); |
| + |
| + NavigateToURL(new_shell, https_server.GetURL("files/post_message2.html")); |
| + |
| + // 5) Now verify that posting a message from the foo window to a subframe of |
| + // the opener window works fine. The opener subframe will reply, causing the |
| + // foo window to update its own title. |
| + WindowedNotificationObserver title_observer3( |
| + NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, |
| + Source<WebContents>(new_shell->web_contents())); |
| + EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( |
| + foo_contents->GetRenderViewHost(), L"", |
| + L"window.domAutomationController.send(postToOpenerFrame('msg3','*'));", |
| + &success)); |
| + EXPECT_TRUE(success); |
| + title_observer3.Wait(); |
| + EXPECT_EQ(ASCIIToUTF16("msg3"), new_shell->web_contents()->GetTitle()); |
| + |
| + // 5) Lastly, verify that the _blank window can post a message to subframe |
| + // of the foo window. The subframe of foo will set the foo window title and |
| + // will reply, setting the _blank window title. |
| + WindowedNotificationObserver title_observer4( |
| + NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, |
| + Source<WebContents>(new_shell2->web_contents())); |
| + EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( |
| + new_contents->GetRenderViewHost(), L"", |
| + L"window.domAutomationController.send(postToFooFrame('msg4'));", |
| + &success)); |
| + EXPECT_TRUE(success); |
| + title_observer4.Wait(); |
| + EXPECT_EQ(ASCIIToUTF16("msg4"), new_shell2->web_contents()->GetTitle()); |
| } |
| // Test for crbug.com/116192. Navigations to a window's opener should |
| @@ -1039,4 +1072,186 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, LeakingRenderViewHosts) { |
| EXPECT_EQ(0U, rvh_observers.GetNumObservers()); |
| } |
| +namespace { |
| + |
| +bool CompareTrees(base::DictionaryValue* first, base::DictionaryValue* second) { |
| + string16 name1; |
| + string16 name2; |
| + if (!first->GetString("name", &name1) || !second->GetString("name", &name2)) |
| + return false; |
| + if (name1 != name2) |
| + return false; |
| + |
| + int id1; |
| + int id2; |
| + if (!first->GetInteger("id", &id1) || !second->GetInteger("id", &id2)) |
| + return false; |
| + if (id1 != id2) |
| + return false; |
| + |
| + ListValue* subtree1; |
|
awong
2012/08/20 21:56:31
Pointer OCDness...can we initialize these things t
nasko
2012/08/21 00:34:45
Done.
|
| + ListValue* subtree2; |
| + bool result1 = first->GetList("subtree", &subtree1); |
| + bool result2 = second->GetList("subtree", &subtree2); |
| + if (!result1 && !result2) |
| + return true; |
| + if (!result1 || !result2) |
| + return false; |
| + |
| + if (subtree1->GetSize() != subtree2->GetSize()) |
| + return false; |
| + |
| + base::DictionaryValue* child1; |
| + base::DictionaryValue* child2; |
| + for (size_t i = 0; i < subtree1->GetSize(); ++i) { |
| + if (!subtree1->GetDictionary(i, &child1) || |
| + !subtree2->GetDictionary(i, &child2)) |
| + return false; |
| + if (!CompareTrees(child1, child2)) |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +base::DictionaryValue* GetTree(std::string frame_tree) { |
| + EXPECT_FALSE(frame_tree.empty()); |
| + base::Value* v = base::JSONReader::Read(frame_tree); |
| + base::DictionaryValue* tree; |
| + EXPECT_TRUE(v->IsType(base::Value::TYPE_DICTIONARY)); |
| + EXPECT_TRUE(v->GetAsDictionary(&tree)); |
| + return tree; |
| +} |
| + |
| +} // namespace |
| + |
| +// Test for correct propagation of frames hierarchy across processes in the |
| +// same browsing context. |
| +IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, FrameTreeUpdates) { |
| + // Start two servers to allow using different sites. |
| + EXPECT_TRUE(test_server()->Start()); |
| + net::TestServer https_server( |
| + net::TestServer::TYPE_HTTPS, |
| + net::TestServer::kLocalhost, |
| + FilePath(FILE_PATH_LITERAL("content/test/data"))); |
| + EXPECT_TRUE(https_server.Start()); |
| + |
| + GURL frame_tree_url(test_server()->GetURL("files/frame_tree/top.html")); |
| + |
| + // Replace the 127.0.0.1 with localhost, which will give us a different |
| + // site instance. |
| + GURL::Replacements replacements; |
| + std::string new_host("localhost"); |
| + replacements.SetHostStr(new_host); |
| + GURL remote_frame = test_server()->GetURL( |
| + "files/frame_tree/1-1.html").ReplaceComponents(replacements); |
| + |
| + bool success = false; |
| + base::DictionaryValue* frames = NULL; |
| + base::ListValue* subtree = NULL; |
| + |
| + NavigateToURL(shell(), test_server()->GetURL("files/simple_page.html")); |
| + WebContents* opener_contents = shell()->web_contents(); |
| + RenderViewHostManager* opener_rvhm = static_cast<WebContentsImpl*>( |
| + opener_contents)->GetRenderManagerForTesting(); |
| + frames = GetTree(opener_contents->GetRenderViewHost()->GetFrameTree()); |
| + EXPECT_FALSE(frames->GetList("subtree", &subtree)); |
| + |
| + NavigateToURL(shell(), frame_tree_url); |
| + frames = GetTree(opener_contents->GetRenderViewHost()->GetFrameTree()); |
| + EXPECT_TRUE(frames->GetList("subtree", &subtree)); |
| + EXPECT_TRUE(subtree->GetSize() == 3); |
| + |
| + scoped_refptr<SiteInstance> orig_site_instance( |
| + opener_contents->GetSiteInstance()); |
| + EXPECT_TRUE(orig_site_instance != NULL); |
| + |
| + ShellAddedObserver shell_observer1; |
| + EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( |
| + opener_contents->GetRenderViewHost(), |
| + L"", L"window.domAutomationController.send(openWindow('1-3.html'));", |
| + &success)); |
| + EXPECT_TRUE(success); |
| + |
| + Shell* shell1 = shell_observer1.GetShell(); |
| + WebContents* contents1 = shell1->web_contents(); |
| + WaitForLoadStop(contents1); |
| + RenderViewHostManager* rvhm1 = static_cast<WebContentsImpl*>( |
| + contents1)->GetRenderManagerForTesting(); |
| + EXPECT_EQ("/files/frame_tree/1-3.html", contents1->GetURL().path()); |
| + |
| + NavigateToURL(shell1, https_server.GetURL("files/title1.html")); |
| + EXPECT_EQ("/files/title1.html", contents1->GetURL().path()); |
| + scoped_refptr<SiteInstance> site_instance1( |
| + contents1->GetSiteInstance()); |
| + EXPECT_NE(orig_site_instance, site_instance1); |
| + |
| + ShellAddedObserver shell_observer2; |
| + EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( |
| + opener_contents->GetRenderViewHost(), L"", |
| + L"window.domAutomationController.send(openWindow('../title2.html'));", |
| + &success)); |
| + EXPECT_TRUE(success); |
| + |
| + Shell* shell2 = shell_observer2.GetShell(); |
| + WebContents* contents2 = shell2->web_contents(); |
| + WaitForLoadStop(contents2); |
| + EXPECT_EQ("/files/title2.html", contents2->GetURL().path()); |
| + |
| + NavigateToURL(shell2, remote_frame); |
| + EXPECT_EQ("/files/frame_tree/1-1.html", contents2->GetURL().path()); |
| + scoped_refptr<SiteInstance> site_instance2( |
| + contents2->GetSiteInstance()); |
| + EXPECT_NE(orig_site_instance, site_instance2); |
| + EXPECT_NE(site_instance1, site_instance2); |
| + |
| + RenderViewHostManager* rvhm2 = static_cast<WebContentsImpl*>( |
| + contents2)->GetRenderManagerForTesting(); |
| + |
| + EXPECT_TRUE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(opener_rvhm->GetSwappedOutRenderViewHost( |
| + rvhm1->current_host()->GetSiteInstance())->GetFrameTree()))); |
| + EXPECT_TRUE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(opener_rvhm->GetSwappedOutRenderViewHost( |
| + rvhm2->current_host()->GetSiteInstance())->GetFrameTree()))); |
| + |
| + EXPECT_TRUE(CompareTrees( |
| + GetTree(rvhm1->current_host()->GetFrameTree()), |
| + GetTree(rvhm1->GetSwappedOutRenderViewHost( |
| + opener_rvhm->current_host()->GetSiteInstance())->GetFrameTree()))); |
| + EXPECT_TRUE(CompareTrees( |
| + GetTree(rvhm2->current_host()->GetFrameTree()), |
| + GetTree(rvhm2->GetSwappedOutRenderViewHost( |
| + opener_rvhm->current_host()->GetSiteInstance())->GetFrameTree()))); |
| + |
| + EXPECT_FALSE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(rvhm1->current_host()->GetFrameTree()))); |
| + EXPECT_FALSE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(rvhm2->current_host()->GetFrameTree()))); |
| + |
| + // Reload the original page, which will cause subframe ids to change. This |
| + // will ensure that the ids are properly replicated across reload. |
| + NavigateToURL(shell(), frame_tree_url); |
| + |
| + EXPECT_TRUE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(opener_rvhm->GetSwappedOutRenderViewHost( |
| + rvhm1->current_host()->GetSiteInstance())->GetFrameTree()))); |
| + EXPECT_TRUE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(opener_rvhm->GetSwappedOutRenderViewHost( |
| + rvhm2->current_host()->GetSiteInstance())->GetFrameTree()))); |
| + |
| + EXPECT_FALSE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(rvhm1->current_host()->GetFrameTree()))); |
| + EXPECT_FALSE(CompareTrees( |
| + GetTree(opener_rvhm->current_host()->GetFrameTree()), |
| + GetTree(rvhm2->current_host()->GetFrameTree()))); |
| +} |
| + |
| } // namespace content |