OLD | NEW |
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 <tuple> | 5 #include <tuple> |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
11 #include "content/common/accessibility_messages.h" | 11 #include "content/common/accessibility_messages.h" |
12 #include "content/common/frame_messages.h" | 12 #include "content/common/frame_messages.h" |
13 #include "content/common/site_isolation_policy.h" | 13 #include "content/common/site_isolation_policy.h" |
14 #include "content/common/view_message_enums.h" | 14 #include "content/common/view_message_enums.h" |
15 #include "content/public/common/content_switches.h" | 15 #include "content/public/common/content_switches.h" |
16 #include "content/public/test/render_view_test.h" | 16 #include "content/public/test/render_view_test.h" |
17 #include "content/renderer/accessibility/render_accessibility_impl.h" | 17 #include "content/renderer/accessibility/render_accessibility_impl.h" |
18 #include "content/renderer/render_frame_impl.h" | 18 #include "content/renderer/render_frame_impl.h" |
19 #include "content/renderer/render_view_impl.h" | 19 #include "content/renderer/render_view_impl.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
21 #include "third_party/WebKit/public/platform/WebSize.h" | 21 #include "third_party/WebKit/public/platform/WebSize.h" |
22 #include "third_party/WebKit/public/web/WebAXObject.h" | 22 #include "third_party/WebKit/public/web/WebAXObject.h" |
23 #include "third_party/WebKit/public/web/WebDocument.h" | 23 #include "third_party/WebKit/public/web/WebDocument.h" |
| 24 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
24 #include "third_party/WebKit/public/web/WebView.h" | 25 #include "third_party/WebKit/public/web/WebView.h" |
25 #include "ui/accessibility/ax_node_data.h" | 26 #include "ui/accessibility/ax_node_data.h" |
26 | 27 |
27 using blink::WebAXObject; | 28 using blink::WebAXObject; |
28 using blink::WebDocument; | 29 using blink::WebDocument; |
29 | 30 |
30 namespace content { | 31 namespace content { |
31 | 32 |
32 class TestRenderAccessibilityImpl : public RenderAccessibilityImpl { | 33 class TestRenderAccessibilityImpl : public RenderAccessibilityImpl { |
33 public: | 34 public: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 90 |
90 int CountAccessibilityNodesSentToBrowser() { | 91 int CountAccessibilityNodesSentToBrowser() { |
91 AccessibilityHostMsg_EventParams event; | 92 AccessibilityHostMsg_EventParams event; |
92 GetLastAccEvent(&event); | 93 GetLastAccEvent(&event); |
93 return event.update.nodes.size(); | 94 return event.update.nodes.size(); |
94 } | 95 } |
95 | 96 |
96 protected: | 97 protected: |
97 IPC::TestSink* sink_; | 98 IPC::TestSink* sink_; |
98 | 99 |
| 100 private: |
99 DISALLOW_COPY_AND_ASSIGN(RenderAccessibilityImplTest); | 101 DISALLOW_COPY_AND_ASSIGN(RenderAccessibilityImplTest); |
100 | |
101 }; | 102 }; |
102 | 103 |
103 TEST_F(RenderAccessibilityImplTest, SendFullAccessibilityTreeOnReload) { | 104 TEST_F(RenderAccessibilityImplTest, SendFullAccessibilityTreeOnReload) { |
104 // The job of RenderAccessibilityImpl is to serialize the | 105 // The job of RenderAccessibilityImpl is to serialize the |
105 // accessibility tree built by WebKit and send it to the browser. | 106 // accessibility tree built by WebKit and send it to the browser. |
106 // When the accessibility tree changes, it tries to send only | 107 // When the accessibility tree changes, it tries to send only |
107 // the nodes that actually changed or were reparented. This test | 108 // the nodes that actually changed or were reparented. This test |
108 // ensures that the messages sent are correct in cases when a page | 109 // ensures that the messages sent are correct in cases when a page |
109 // reloads, and that internal state is properly garbage-collected. | 110 // reloads, and that internal state is properly garbage-collected. |
110 std::string html = | 111 std::string html = |
111 "<body>" | 112 "<body>" |
112 " <div role='group' id='A'>" | 113 " <div role='group' id='A'>" |
113 " <div role='group' id='A1'></div>" | 114 " <div role='group' id='A1'></div>" |
114 " <div role='group' id='A2'></div>" | 115 " <div role='group' id='A2'></div>" |
115 " </div>" | 116 " </div>" |
116 "</body>"; | 117 "</body>"; |
117 LoadHTML(html.c_str()); | 118 LoadHTML(html.c_str()); |
118 | 119 |
119 // Creating a RenderAccessibilityImpl should sent the tree to the browser. | 120 // Creating a RenderAccessibilityImpl should sent the tree to the browser. |
120 std::unique_ptr<TestRenderAccessibilityImpl> accessibility( | 121 std::unique_ptr<TestRenderAccessibilityImpl> accessibility( |
121 new TestRenderAccessibilityImpl(frame())); | 122 new TestRenderAccessibilityImpl(frame())); |
122 accessibility->SendPendingAccessibilityEvents(); | 123 accessibility->SendPendingAccessibilityEvents(); |
123 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 124 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
124 | 125 |
125 // If we post another event but the tree doesn't change, | 126 // If we post another event but the tree doesn't change, |
126 // we should only send 1 node to the browser. | 127 // we should only send 1 node to the browser. |
127 sink_->ClearMessages(); | 128 sink_->ClearMessages(); |
128 WebDocument document = view()->GetWebView()->MainFrame()->GetDocument(); | 129 WebDocument document = GetMainFrame()->GetDocument(); |
129 WebAXObject root_obj = WebAXObject::FromWebDocument(document); | 130 WebAXObject root_obj = WebAXObject::FromWebDocument(document); |
130 accessibility->HandleAXEvent( | 131 accessibility->HandleAXEvent( |
131 root_obj, | 132 root_obj, |
132 ui::AX_EVENT_LAYOUT_COMPLETE); | 133 ui::AX_EVENT_LAYOUT_COMPLETE); |
133 accessibility->SendPendingAccessibilityEvents(); | 134 accessibility->SendPendingAccessibilityEvents(); |
134 EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser()); | 135 EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser()); |
135 { | 136 { |
136 // Make sure it's the root object that was updated. | 137 // Make sure it's the root object that was updated. |
137 AccessibilityHostMsg_EventParams event; | 138 AccessibilityHostMsg_EventParams event; |
138 GetLastAccEvent(&event); | 139 GetLastAccEvent(&event); |
139 EXPECT_EQ(root_obj.AxID(), event.update.nodes[0].id); | 140 EXPECT_EQ(root_obj.AxID(), event.update.nodes[0].id); |
140 } | 141 } |
141 | 142 |
142 // If we reload the page and send a event, we should send | 143 // If we reload the page and send a event, we should send |
143 // all 4 nodes to the browser. Also double-check that we didn't | 144 // all 4 nodes to the browser. Also double-check that we didn't |
144 // leak any of the old BrowserTreeNodes. | 145 // leak any of the old BrowserTreeNodes. |
145 LoadHTML(html.c_str()); | 146 LoadHTML(html.c_str()); |
146 document = view()->GetWebView()->MainFrame()->GetDocument(); | 147 document = GetMainFrame()->GetDocument(); |
147 root_obj = WebAXObject::FromWebDocument(document); | 148 root_obj = WebAXObject::FromWebDocument(document); |
148 sink_->ClearMessages(); | 149 sink_->ClearMessages(); |
149 accessibility->HandleAXEvent( | 150 accessibility->HandleAXEvent( |
150 root_obj, | 151 root_obj, |
151 ui::AX_EVENT_LAYOUT_COMPLETE); | 152 ui::AX_EVENT_LAYOUT_COMPLETE); |
152 accessibility->SendPendingAccessibilityEvents(); | 153 accessibility->SendPendingAccessibilityEvents(); |
153 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 154 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
154 | 155 |
155 // Even if the first event is sent on an element other than | 156 // Even if the first event is sent on an element other than |
156 // the root, the whole tree should be updated because we know | 157 // the root, the whole tree should be updated because we know |
157 // the browser doesn't have the root element. | 158 // the browser doesn't have the root element. |
158 LoadHTML(html.c_str()); | 159 LoadHTML(html.c_str()); |
159 document = view()->GetWebView()->MainFrame()->GetDocument(); | 160 document = GetMainFrame()->GetDocument(); |
160 root_obj = WebAXObject::FromWebDocument(document); | 161 root_obj = WebAXObject::FromWebDocument(document); |
161 sink_->ClearMessages(); | 162 sink_->ClearMessages(); |
162 const WebAXObject& first_child = root_obj.ChildAt(0); | 163 const WebAXObject& first_child = root_obj.ChildAt(0); |
163 accessibility->HandleAXEvent( | 164 accessibility->HandleAXEvent( |
164 first_child, | 165 first_child, |
165 ui::AX_EVENT_LIVE_REGION_CHANGED); | 166 ui::AX_EVENT_LIVE_REGION_CHANGED); |
166 accessibility->SendPendingAccessibilityEvents(); | 167 accessibility->SendPendingAccessibilityEvents(); |
167 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 168 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
168 } | 169 } |
169 | 170 |
(...skipping 10 matching lines...) Expand all Loading... |
180 " </div>" | 181 " </div>" |
181 " </div>" | 182 " </div>" |
182 "</body>"; | 183 "</body>"; |
183 LoadHTML(html.c_str()); | 184 LoadHTML(html.c_str()); |
184 | 185 |
185 std::unique_ptr<TestRenderAccessibilityImpl> accessibility( | 186 std::unique_ptr<TestRenderAccessibilityImpl> accessibility( |
186 new TestRenderAccessibilityImpl(frame())); | 187 new TestRenderAccessibilityImpl(frame())); |
187 accessibility->SendPendingAccessibilityEvents(); | 188 accessibility->SendPendingAccessibilityEvents(); |
188 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 189 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
189 | 190 |
190 WebDocument document = view()->GetWebView()->MainFrame()->GetDocument(); | 191 WebDocument document = GetMainFrame()->GetDocument(); |
191 WebAXObject root_obj = WebAXObject::FromWebDocument(document); | 192 WebAXObject root_obj = WebAXObject::FromWebDocument(document); |
192 WebAXObject node_a = root_obj.ChildAt(0); | 193 WebAXObject node_a = root_obj.ChildAt(0); |
193 WebAXObject node_b = node_a.ChildAt(0); | 194 WebAXObject node_b = node_a.ChildAt(0); |
194 WebAXObject node_c = node_b.ChildAt(0); | 195 WebAXObject node_c = node_b.ChildAt(0); |
195 | 196 |
196 // Hide node 'B' ('C' stays visible). | 197 // Hide node 'B' ('C' stays visible). |
197 ExecuteJavaScriptForTests( | 198 ExecuteJavaScriptForTests( |
198 "document.getElementById('B').style.visibility = 'hidden';"); | 199 "document.getElementById('B').style.visibility = 'hidden';"); |
199 // Force layout now. | 200 // Force layout now. |
200 ExecuteJavaScriptForTests("document.getElementById('B').offsetLeft;"); | 201 ExecuteJavaScriptForTests("document.getElementById('B').offsetLeft;"); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 new TestRenderAccessibilityImpl(frame())); | 239 new TestRenderAccessibilityImpl(frame())); |
239 accessibility->SendPendingAccessibilityEvents(); | 240 accessibility->SendPendingAccessibilityEvents(); |
240 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 241 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
241 | 242 |
242 // Show node 'B', then send a childrenChanged on 'A'. | 243 // Show node 'B', then send a childrenChanged on 'A'. |
243 ExecuteJavaScriptForTests( | 244 ExecuteJavaScriptForTests( |
244 "document.getElementById('B').style.visibility = 'visible';"); | 245 "document.getElementById('B').style.visibility = 'visible';"); |
245 ExecuteJavaScriptForTests("document.getElementById('B').offsetLeft;"); | 246 ExecuteJavaScriptForTests("document.getElementById('B').offsetLeft;"); |
246 | 247 |
247 sink_->ClearMessages(); | 248 sink_->ClearMessages(); |
248 WebDocument document = view()->GetWebView()->MainFrame()->GetDocument(); | 249 WebDocument document = GetMainFrame()->GetDocument(); |
249 WebAXObject root_obj = WebAXObject::FromWebDocument(document); | 250 WebAXObject root_obj = WebAXObject::FromWebDocument(document); |
250 WebAXObject node_a = root_obj.ChildAt(0); | 251 WebAXObject node_a = root_obj.ChildAt(0); |
251 WebAXObject node_b = node_a.ChildAt(0); | 252 WebAXObject node_b = node_a.ChildAt(0); |
252 WebAXObject node_c = node_b.ChildAt(0); | 253 WebAXObject node_c = node_b.ChildAt(0); |
253 | 254 |
254 accessibility->HandleAXEvent( | 255 accessibility->HandleAXEvent( |
255 node_a, | 256 node_a, |
256 ui::AX_EVENT_CHILDREN_CHANGED); | 257 ui::AX_EVENT_CHILDREN_CHANGED); |
257 | 258 |
258 accessibility->SendPendingAccessibilityEvents(); | 259 accessibility->SendPendingAccessibilityEvents(); |
259 AccessibilityHostMsg_EventParams event; | 260 AccessibilityHostMsg_EventParams event; |
260 GetLastAccEvent(&event); | 261 GetLastAccEvent(&event); |
261 | 262 |
262 ASSERT_EQ(3U, event.update.nodes.size()); | 263 ASSERT_EQ(3U, event.update.nodes.size()); |
263 EXPECT_EQ(node_a.AxID(), event.update.node_id_to_clear); | 264 EXPECT_EQ(node_a.AxID(), event.update.node_id_to_clear); |
264 EXPECT_EQ(node_a.AxID(), event.update.nodes[0].id); | 265 EXPECT_EQ(node_a.AxID(), event.update.nodes[0].id); |
265 EXPECT_EQ(node_b.AxID(), event.update.nodes[1].id); | 266 EXPECT_EQ(node_b.AxID(), event.update.nodes[1].id); |
266 EXPECT_EQ(node_c.AxID(), event.update.nodes[2].id); | 267 EXPECT_EQ(node_c.AxID(), event.update.nodes[2].id); |
267 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 268 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
268 } | 269 } |
269 | 270 |
270 } // namespace content | 271 } // namespace content |
OLD | NEW |