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 |