OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 return filesystem_url; | 81 return filesystem_url; |
82 } | 82 } |
83 | 83 |
84 std::string GetTextContent(content::RenderFrameHost* frame) { | 84 std::string GetTextContent(content::RenderFrameHost* frame) { |
85 std::string result; | 85 std::string result; |
86 EXPECT_TRUE(ExecuteScriptAndExtractString( | 86 EXPECT_TRUE(ExecuteScriptAndExtractString( |
87 frame, "domAutomationController.send(document.body.innerText)", &result)); | 87 frame, "domAutomationController.send(document.body.innerText)", &result)); |
88 return result; | 88 return result; |
89 } | 89 } |
90 | 90 |
| 91 // Helper to send a postMessage from |sender| to |opener| via window.opener, |
| 92 // wait for a reply, and verify the response. Defines its own message event |
| 93 // handlers. |
| 94 void VerifyPostMessageToOpener(content::RenderFrameHost* sender, |
| 95 content::RenderFrameHost* opener) { |
| 96 EXPECT_TRUE( |
| 97 ExecuteScript(opener, |
| 98 "window.addEventListener('message', function(event) {\n" |
| 99 " event.source.postMessage(event.data, '*');\n" |
| 100 "});")); |
| 101 |
| 102 EXPECT_TRUE( |
| 103 ExecuteScript(sender, |
| 104 "window.addEventListener('message', function(event) {\n" |
| 105 " window.domAutomationController.send(event.data);\n" |
| 106 "});")); |
| 107 |
| 108 std::string result; |
| 109 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 110 sender, "opener.postMessage('foo', '*');", &result)); |
| 111 EXPECT_EQ("foo", result); |
| 112 } |
| 113 |
91 } // namespace | 114 } // namespace |
92 | 115 |
93 // Takes a snapshot of all frames upon construction. When Wait() is called, a | 116 // Takes a snapshot of all frames upon construction. When Wait() is called, a |
94 // MessageLoop is created and Quit when all previously recorded frames are | 117 // MessageLoop is created and Quit when all previously recorded frames are |
95 // either present in the tab, or deleted. If a navigation happens between the | 118 // either present in the tab, or deleted. If a navigation happens between the |
96 // construction and the Wait() call, then this logic ensures that all obsolete | 119 // construction and the Wait() call, then this logic ensures that all obsolete |
97 // RenderFrameHosts have been destructed when Wait() returns. | 120 // RenderFrameHosts have been destructed when Wait() returns. |
98 // See also the comment at ProcessManagerBrowserTest::NavigateToURL. | 121 // See also the comment at ProcessManagerBrowserTest::NavigateToURL. |
99 class NavigationCompletedObserver : public content::WebContentsObserver { | 122 class NavigationCompletedObserver : public content::WebContentsObserver { |
100 public: | 123 public: |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 EXPECT_EQ(extension_origin, | 812 EXPECT_EQ(extension_origin, |
790 popup->GetMainFrame()->GetLastCommittedOrigin()); | 813 popup->GetMainFrame()->GetLastCommittedOrigin()); |
791 EXPECT_EQ("foo", GetTextContent(popup->GetMainFrame())); | 814 EXPECT_EQ("foo", GetTextContent(popup->GetMainFrame())); |
792 | 815 |
793 EXPECT_EQ(3 + i, | 816 EXPECT_EQ(3 + i, |
794 pm->GetRenderFrameHostsForExtension(extension->id()).size()); | 817 pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
795 EXPECT_EQ(3 + i, pm->GetAllFrames().size()); | 818 EXPECT_EQ(3 + i, pm->GetAllFrames().size()); |
796 } | 819 } |
797 } | 820 } |
798 | 821 |
| 822 // Verify that a web popup created via window.open from an extension page can |
| 823 // communicate with the extension page via window.opener. See |
| 824 // https://crbug.com/590068. |
| 825 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, |
| 826 WebPopupFromExtensionMainFrameHasValidOpener) { |
| 827 // Create a simple extension without a background page. |
| 828 const Extension* extension = CreateExtension("Extension", false); |
| 829 embedded_test_server()->ServeFilesFromDirectory(extension->path()); |
| 830 ASSERT_TRUE(embedded_test_server()->Start()); |
| 831 |
| 832 // Navigate main tab to an extension page. |
| 833 NavigateToURL(extension->GetResourceURL("empty.html")); |
| 834 ProcessManager* pm = ProcessManager::Get(profile()); |
| 835 EXPECT_EQ(1u, pm->GetAllFrames().size()); |
| 836 EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
| 837 |
| 838 content::WebContents* tab = |
| 839 browser()->tab_strip_model()->GetActiveWebContents(); |
| 840 |
| 841 content::RenderFrameHost* main_frame = tab->GetMainFrame(); |
| 842 |
| 843 // Open a new web popup from the extension tab. The popup should go into a |
| 844 // new process. |
| 845 GURL popup_url(embedded_test_server()->GetURL("/empty.html")); |
| 846 content::WebContents* popup = OpenPopup(main_frame, popup_url); |
| 847 EXPECT_NE(popup, tab); |
| 848 ASSERT_EQ(2, browser()->tab_strip_model()->count()); |
| 849 EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
| 850 EXPECT_EQ(1u, pm->GetAllFrames().size()); |
| 851 EXPECT_NE(popup->GetRenderProcessHost(), main_frame->GetProcess()); |
| 852 |
| 853 // Ensure the popup's window.opener is defined. |
| 854 bool is_opener_defined = false; |
| 855 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
| 856 popup, "window.domAutomationController.send(!!window.opener)", |
| 857 &is_opener_defined)); |
| 858 EXPECT_TRUE(is_opener_defined); |
| 859 |
| 860 // Verify that postMessage to window.opener works. |
| 861 VerifyPostMessageToOpener(popup->GetMainFrame(), main_frame); |
| 862 } |
| 863 |
| 864 // Verify that a web popup created via window.open from an extension subframe |
| 865 // can communicate with the extension page via window.opener. Similar to the |
| 866 // test above, but for subframes. See https://crbug.com/590068. |
| 867 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, |
| 868 WebPopupFromExtensionSubframeHasValidOpener) { |
| 869 // This test only makes sense if OOPIFs are enabled for extension subframes. |
| 870 if (!IsIsolateExtensionsEnabled()) |
| 871 return; |
| 872 |
| 873 // Create a simple extension without a background page. |
| 874 const Extension* extension = CreateExtension("Extension", false); |
| 875 embedded_test_server()->ServeFilesFromDirectory(extension->path()); |
| 876 ASSERT_TRUE(embedded_test_server()->Start()); |
| 877 |
| 878 // Navigate main tab to a web page with a blank iframe. There should be no |
| 879 // extension frames yet. |
| 880 NavigateToURL(embedded_test_server()->GetURL("/blank_iframe.html")); |
| 881 ProcessManager* pm = ProcessManager::Get(profile()); |
| 882 EXPECT_EQ(0u, pm->GetAllFrames().size()); |
| 883 EXPECT_EQ(0u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
| 884 |
| 885 content::WebContents* tab = |
| 886 browser()->tab_strip_model()->GetActiveWebContents(); |
| 887 |
| 888 // Navigate first subframe to an extension URL. |
| 889 const GURL extension_url(extension->GetResourceURL("empty.html")); |
| 890 EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame0", extension_url)); |
| 891 EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
| 892 EXPECT_EQ(1u, pm->GetAllFrames().size()); |
| 893 |
| 894 content::RenderFrameHost* main_frame = tab->GetMainFrame(); |
| 895 content::RenderFrameHost* extension_frame = ChildFrameAt(main_frame, 0); |
| 896 |
| 897 // Open a new web popup from extension frame. The popup should go into main |
| 898 // frame's web process. |
| 899 GURL popup_url(embedded_test_server()->GetURL("/empty.html")); |
| 900 content::WebContents* popup = OpenPopup(extension_frame, popup_url); |
| 901 EXPECT_NE(popup, tab); |
| 902 ASSERT_EQ(2, browser()->tab_strip_model()->count()); |
| 903 EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
| 904 EXPECT_EQ(1u, pm->GetAllFrames().size()); |
| 905 EXPECT_NE(popup->GetRenderProcessHost(), extension_frame->GetProcess()); |
| 906 EXPECT_EQ(popup->GetRenderProcessHost(), main_frame->GetProcess()); |
| 907 |
| 908 // Ensure the popup's window.opener is defined. |
| 909 bool is_opener_defined = false; |
| 910 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
| 911 popup, "window.domAutomationController.send(!!window.opener)", |
| 912 &is_opener_defined)); |
| 913 EXPECT_TRUE(is_opener_defined); |
| 914 |
| 915 // Verify that postMessage to window.opener works. |
| 916 VerifyPostMessageToOpener(popup->GetMainFrame(), extension_frame); |
| 917 } |
| 918 |
799 } // namespace extensions | 919 } // namespace extensions |
OLD | NEW |