Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2014 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 "base/command_line.h" | |
| 6 #include "base/strings/stringprintf.h" | |
| 7 #include "content/browser/accessibility/browser_accessibility.h" | |
| 8 #include "content/browser/accessibility/browser_accessibility_manager.h" | |
| 9 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | |
| 10 #include "content/browser/frame_host/cross_process_frame_connector.h" | |
| 11 #include "content/browser/frame_host/frame_tree.h" | |
| 12 #include "content/browser/frame_host/render_frame_proxy_host.h" | |
| 13 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" | |
| 14 #include "content/browser/renderer_host/render_view_host_impl.h" | |
| 15 #include "content/browser/web_contents/web_contents_impl.h" | |
| 16 #include "content/public/browser/notification_observer.h" | |
| 17 #include "content/public/browser/notification_service.h" | |
| 18 #include "content/public/browser/notification_types.h" | |
| 19 #include "content/public/browser/web_contents_observer.h" | |
| 20 #include "content/public/common/content_switches.h" | |
| 21 #include "content/public/test/browser_test_utils.h" | |
| 22 #include "content/public/test/content_browser_test.h" | |
| 23 #include "content/public/test/content_browser_test_utils.h" | |
| 24 #include "content/public/test/test_utils.h" | |
| 25 #include "content/shell/browser/shell.h" | |
| 26 #include "content/test/accessibility_browser_test_utils.h" | |
| 27 #include "content/test/content_browser_test_utils_internal.h" | |
| 28 #include "net/dns/mock_host_resolver.h" | |
| 29 #include "url/gurl.h" | |
| 30 | |
| 31 namespace content { | |
| 32 | |
| 33 // TODO(dmazzoni): share this with site_per_process_browsertest.cc | |
|
Charlie Reis
2014/08/21 19:23:27
Can you subclass SitePerProcessBrowserTest, or is
dmazzoni
2014/08/25 06:49:36
Done.
| |
| 34 class SitePerProcessAccessibilityBrowserTest : public ContentBrowserTest { | |
| 35 public: | |
| 36 SitePerProcessAccessibilityBrowserTest() {} | |
| 37 | |
| 38 protected: | |
| 39 // Start at a data URL so each extra navigation creates a navigation entry. | |
| 40 // (The first navigation will silently be classified as AUTO_SUBFRAME.) | |
| 41 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP. | |
| 42 void StartFrameAtDataURL() { | |
| 43 std::string data_url_script = | |
| 44 "var iframes = document.getElementById('test');iframes.src=" | |
| 45 "'data:text/html,dataurl';"; | |
| 46 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script)); | |
| 47 } | |
| 48 | |
| 49 bool NavigateIframeToURL(Shell* window, | |
| 50 const GURL& url, | |
| 51 std::string iframe_id) { | |
| 52 // TODO(creis): This should wait for LOAD_STOP, but cross-site subframe | |
| 53 // navigations generate extra DidStartLoading and DidStopLoading messages. | |
| 54 // Until we replace swappedout:// with frame proxies, we need to listen for | |
| 55 // something else. For now, we trigger NEW_SUBFRAME navigations and listen | |
| 56 // for commit. | |
| 57 std::string script = base::StringPrintf( | |
| 58 "setTimeout(\"" | |
| 59 "var iframes = document.getElementById('%s');iframes.src='%s';" | |
| 60 "\",0)", | |
| 61 iframe_id.c_str(), url.spec().c_str()); | |
| 62 WindowedNotificationObserver load_observer( | |
| 63 NOTIFICATION_NAV_ENTRY_COMMITTED, | |
| 64 Source<NavigationController>( | |
| 65 &window->web_contents()->GetController())); | |
| 66 bool result = ExecuteScript(window->web_contents(), script); | |
| 67 load_observer.Wait(); | |
| 68 return result; | |
| 69 } | |
| 70 | |
| 71 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | |
| 72 command_line->AppendSwitch(switches::kSitePerProcess); | |
| 73 } | |
| 74 }; | |
| 75 | |
| 76 IN_PROC_BROWSER_TEST_F(SitePerProcessAccessibilityBrowserTest, | |
| 77 CrossSiteIframeAccessibility) { | |
| 78 // Enable full accessibility for all current and future WebContents. | |
| 79 BrowserAccessibilityState::GetInstance()->EnableAccessibility(); | |
| 80 | |
| 81 AccessibilityNotificationWaiter main_frame_accessibility_waiter( | |
| 82 shell(), AccessibilityModeComplete, | |
| 83 ui::AX_EVENT_LOAD_COMPLETE); | |
| 84 | |
| 85 host_resolver()->AddRule("*", "127.0.0.1"); | |
| 86 ASSERT_TRUE(test_server()->Start()); | |
| 87 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); | |
| 88 NavigateToURL(shell(), main_url); | |
| 89 | |
| 90 // It is safe to obtain the root frame tree node here, as it doesn't change. | |
| 91 FrameTreeNode* root = | |
| 92 static_cast<WebContentsImpl*>(shell()->web_contents())-> | |
| 93 GetFrameTree()->root(); | |
| 94 | |
| 95 // Load same-site page into iframe. | |
| 96 FrameTreeNode* child = root->child_at(0); | |
| 97 GURL http_url(test_server()->GetURL("files/title1.html")); | |
| 98 NavigateFrameToURL(child, http_url); | |
| 99 RenderFrameProxyHost* proxy_to_parent = | |
| 100 child->render_manager()->GetRenderFrameProxyHost( | |
| 101 shell()->web_contents()->GetSiteInstance()); | |
| 102 EXPECT_FALSE(proxy_to_parent); | |
| 103 | |
| 104 // These must stay in scope with replace_host. | |
| 105 GURL::Replacements replace_host; | |
| 106 std::string foo_com("foo.com"); | |
| 107 | |
| 108 // Load cross-site page into iframe. | |
| 109 GURL cross_site_url(test_server()->GetURL("files/title2.html")); | |
| 110 replace_host.SetHostStr(foo_com); | |
| 111 cross_site_url = cross_site_url.ReplaceComponents(replace_host); | |
| 112 NavigateFrameToURL(root->child_at(0), cross_site_url); | |
| 113 | |
| 114 // Ensure that we have created a new process for the subframe. | |
| 115 ASSERT_EQ(1U, root->child_count()); | |
| 116 SiteInstance* site_instance = child->current_frame_host()->GetSiteInstance(); | |
| 117 RenderViewHost* rvh = child->current_frame_host()->render_view_host(); | |
| 118 RenderProcessHost* rph = child->current_frame_host()->GetProcess(); | |
| 119 EXPECT_NE(shell()->web_contents()->GetRenderViewHost(), rvh); | |
|
Charlie Reis
2014/08/21 19:23:27
Many of these checks are redundant with the CrossS
dmazzoni
2014/08/25 06:49:36
Sounds good.
I deleted the ones that seemed the m
Charlie Reis
2014/08/25 20:58:43
Looks good now, thanks.
| |
| 120 EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance); | |
| 121 EXPECT_NE(shell()->web_contents()->GetRenderProcessHost(), rph); | |
| 122 proxy_to_parent = child->render_manager()->GetProxyToParent(); | |
| 123 EXPECT_TRUE(proxy_to_parent); | |
| 124 EXPECT_TRUE(proxy_to_parent->cross_process_frame_connector()); | |
| 125 EXPECT_EQ( | |
| 126 rvh->GetView(), | |
| 127 proxy_to_parent->cross_process_frame_connector()->get_view_for_testing()); | |
| 128 | |
| 129 // Wait until the accessibility tree from both the main frame and | |
| 130 // cross-process iframe load. | |
| 131 RenderFrameHostImpl* child_frame = static_cast<RenderFrameHostImpl*>( | |
| 132 child->current_frame_host()); | |
| 133 AccessibilityNotificationWaiter child_frame_accessibility_waiter( | |
| 134 child_frame, ui::AX_EVENT_NONE); | |
| 135 main_frame_accessibility_waiter.WaitForNotification(); | |
| 136 child_frame_accessibility_waiter.WaitForNotification(); | |
| 137 | |
| 138 RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>( | |
| 139 shell()->web_contents()->GetMainFrame()); | |
| 140 BrowserAccessibilityManager* main_frame_manager = | |
| 141 main_frame->browser_accessibility_manager(); | |
| 142 VLOG(1) << "Main frame accessibility tree:\n" | |
| 143 << main_frame_manager->SnapshotAXTreeForTesting().ToString(); | |
| 144 | |
| 145 BrowserAccessibilityManager* child_frame_manager = | |
| 146 child_frame->browser_accessibility_manager(); | |
| 147 VLOG(1) << "Child frame accessibility tree:\n" | |
| 148 << child_frame_manager->SnapshotAXTreeForTesting().ToString(); | |
| 149 | |
| 150 // Assert that we can walk from the main frame down into the child frame | |
| 151 // directly, getting correct roles and data along the way. | |
| 152 BrowserAccessibility* ax_root = main_frame_manager->GetRoot(); | |
| 153 ASSERT_EQ(ui::AX_ROLE_ROOT_WEB_AREA, ax_root->GetRole()); | |
| 154 ASSERT_EQ(1U, ax_root->PlatformChildCount()); | |
| 155 | |
| 156 BrowserAccessibility* ax_group = ax_root->PlatformGetChild(0); | |
| 157 ASSERT_EQ(ui::AX_ROLE_GROUP, ax_group->GetRole()); | |
| 158 ASSERT_EQ(1U, ax_group->PlatformChildCount()); | |
| 159 | |
| 160 BrowserAccessibility* ax_iframe = ax_group->PlatformGetChild(0); | |
| 161 ASSERT_EQ(ui::AX_ROLE_IFRAME, ax_iframe->GetRole()); | |
| 162 ASSERT_EQ(1U, ax_iframe->PlatformChildCount()); | |
| 163 | |
| 164 BrowserAccessibility* ax_scroll_area = ax_iframe->PlatformGetChild(0); | |
| 165 ASSERT_EQ(ui::AX_ROLE_SCROLL_AREA, ax_scroll_area->GetRole()); | |
| 166 ASSERT_EQ(1U, ax_scroll_area->PlatformChildCount()); | |
| 167 | |
| 168 BrowserAccessibility* ax_child_frame_root = | |
| 169 ax_scroll_area->PlatformGetChild(0); | |
| 170 ASSERT_EQ(ui::AX_ROLE_ROOT_WEB_AREA, ax_child_frame_root->GetRole()); | |
| 171 ASSERT_EQ(1U, ax_child_frame_root->PlatformChildCount()); | |
| 172 ASSERT_EQ("Title Of Awesomeness", ax_child_frame_root->name()); | |
| 173 | |
| 174 BrowserAccessibility* ax_child_frame_group = | |
| 175 ax_child_frame_root->PlatformGetChild(0); | |
| 176 ASSERT_EQ(ui::AX_ROLE_GROUP, ax_child_frame_group->GetRole()); | |
| 177 ASSERT_EQ(1U, ax_child_frame_group->PlatformChildCount()); | |
| 178 | |
| 179 BrowserAccessibility* ax_child_frame_static_text = | |
| 180 ax_child_frame_group->PlatformGetChild(0); | |
| 181 ASSERT_EQ(ui::AX_ROLE_STATIC_TEXT, ax_child_frame_static_text->GetRole()); | |
| 182 ASSERT_EQ(0U, ax_child_frame_static_text->PlatformChildCount()); | |
| 183 | |
| 184 // Last, check that the parent of the child frame root is correct. | |
| 185 ASSERT_EQ(ax_child_frame_root->GetParent(), ax_scroll_area); | |
| 186 } | |
| 187 | |
| 188 } // namespace content | |
| OLD | NEW |