Chromium Code Reviews| 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 "base/strings/utf_string_conversions.h" | 5 #include "base/strings/utf_string_conversions.h" |
| 6 #include "content/common/frame_messages.h" | 6 #include "content/common/frame_messages.h" |
| 7 #include "content/public/test/render_view_test.h" | 7 #include "content/public/test/render_view_test.h" |
| 8 #include "content/renderer/accessibility/renderer_accessibility_complete.h" | 8 #include "content/renderer/accessibility/renderer_accessibility_complete.h" |
| 9 #include "content/renderer/render_view_impl.h" | 9 #include "content/renderer/render_view_impl.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include "third_party/WebKit/public/platform/WebSize.h" | 11 #include "third_party/WebKit/public/platform/WebSize.h" |
| 12 #include "third_party/WebKit/public/web/WebAXObject.h" | 12 #include "third_party/WebKit/public/web/WebAXObject.h" |
| 13 #include "third_party/WebKit/public/web/WebDocument.h" | 13 #include "third_party/WebKit/public/web/WebDocument.h" |
| 14 #include "third_party/WebKit/public/web/WebView.h" | 14 #include "third_party/WebKit/public/web/WebView.h" |
| 15 #include "ui/accessibility/ax_node_data.h" | 15 #include "ui/accessibility/ax_node_data.h" |
| 16 | 16 |
| 17 using blink::WebAXObject; | 17 using blink::WebAXObject; |
| 18 using blink::WebDocument; | 18 using blink::WebDocument; |
| 19 | 19 |
| 20 namespace content { | 20 namespace content { |
| 21 | 21 |
| 22 class TestRendererAccessibilityComplete : public RendererAccessibilityComplete { | 22 class TestRendererAccessibilityComplete : public RendererAccessibilityComplete { |
| 23 public: | 23 public: |
| 24 explicit TestRendererAccessibilityComplete(RenderViewImpl* render_view) | 24 explicit TestRendererAccessibilityComplete(RenderViewImpl* render_view) |
| 25 : RendererAccessibilityComplete(render_view), | 25 : RendererAccessibilityComplete(render_view) { |
| 26 browser_tree_node_count_(0) { | |
| 27 } | |
| 28 | |
| 29 int browser_tree_node_count() { return browser_tree_node_count_; } | |
| 30 | |
| 31 struct TestBrowserTreeNode : public BrowserTreeNode { | |
| 32 TestBrowserTreeNode(TestRendererAccessibilityComplete* owner) | |
| 33 : owner_(owner) { | |
| 34 owner_->browser_tree_node_count_++; | |
| 35 } | |
| 36 | |
| 37 virtual ~TestBrowserTreeNode() { | |
| 38 owner_->browser_tree_node_count_--; | |
| 39 } | |
| 40 | |
| 41 private: | |
| 42 TestRendererAccessibilityComplete* owner_; | |
| 43 }; | |
| 44 | |
| 45 virtual BrowserTreeNode* CreateBrowserTreeNode() OVERRIDE { | |
| 46 return new TestBrowserTreeNode(this); | |
| 47 } | 26 } |
| 48 | 27 |
| 49 void SendPendingAccessibilityEvents() { | 28 void SendPendingAccessibilityEvents() { |
| 50 RendererAccessibilityComplete::SendPendingAccessibilityEvents(); | 29 RendererAccessibilityComplete::SendPendingAccessibilityEvents(); |
| 51 } | 30 } |
| 52 | |
| 53 private: | |
| 54 int browser_tree_node_count_; | |
| 55 }; | 31 }; |
| 56 | 32 |
| 57 class RendererAccessibilityTest : public RenderViewTest { | 33 class RendererAccessibilityTest : public RenderViewTest { |
| 58 public: | 34 public: |
| 59 RendererAccessibilityTest() {} | 35 RendererAccessibilityTest() {} |
| 60 | 36 |
| 61 RenderViewImpl* view() { | 37 RenderViewImpl* view() { |
| 62 return static_cast<RenderViewImpl*>(view_); | 38 return static_cast<RenderViewImpl*>(view_); |
| 63 } | 39 } |
| 64 | 40 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 82 ASSERT_TRUE(message); | 58 ASSERT_TRUE(message); |
| 83 Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param; | 59 Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param; |
| 84 AccessibilityHostMsg_Events::Read(message, ¶m); | 60 AccessibilityHostMsg_Events::Read(message, ¶m); |
| 85 ASSERT_GE(param.a.size(), 1U); | 61 ASSERT_GE(param.a.size(), 1U); |
| 86 *params = param.a[0]; | 62 *params = param.a[0]; |
| 87 } | 63 } |
| 88 | 64 |
| 89 int CountAccessibilityNodesSentToBrowser() { | 65 int CountAccessibilityNodesSentToBrowser() { |
| 90 AccessibilityHostMsg_EventParams event; | 66 AccessibilityHostMsg_EventParams event; |
| 91 GetLastAccEvent(&event); | 67 GetLastAccEvent(&event); |
| 92 return event.nodes.size(); | 68 return event.update.nodes.size(); |
| 93 } | 69 } |
| 94 | 70 |
| 95 protected: | 71 protected: |
| 96 IPC::TestSink* sink_; | 72 IPC::TestSink* sink_; |
| 97 | 73 |
| 98 DISALLOW_COPY_AND_ASSIGN(RendererAccessibilityTest); | 74 DISALLOW_COPY_AND_ASSIGN(RendererAccessibilityTest); |
| 99 | 75 |
| 100 }; | 76 }; |
| 101 | 77 |
| 102 TEST_F(RendererAccessibilityTest, EditableTextModeFocusEvents) { | 78 TEST_F(RendererAccessibilityTest, EditableTextModeFocusEvents) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 125 | 101 |
| 126 // We should have sent a message to the browser with the initial focus | 102 // We should have sent a message to the browser with the initial focus |
| 127 // on the document. | 103 // on the document. |
| 128 { | 104 { |
| 129 SCOPED_TRACE("Initial focus on document"); | 105 SCOPED_TRACE("Initial focus on document"); |
| 130 AccessibilityHostMsg_EventParams event; | 106 AccessibilityHostMsg_EventParams event; |
| 131 GetLastAccEvent(&event); | 107 GetLastAccEvent(&event); |
| 132 EXPECT_EQ(event.event_type, | 108 EXPECT_EQ(event.event_type, |
| 133 ui::AX_EVENT_LAYOUT_COMPLETE); | 109 ui::AX_EVENT_LAYOUT_COMPLETE); |
| 134 EXPECT_EQ(event.id, 1); | 110 EXPECT_EQ(event.id, 1); |
| 135 EXPECT_EQ(event.nodes.size(), 2U); | 111 EXPECT_EQ(event.update.nodes.size(), 2U); |
| 136 EXPECT_EQ(event.nodes[0].id, 1); | 112 EXPECT_EQ(event.update.nodes[0].id, 1); |
| 137 EXPECT_EQ(event.nodes[0].role, | 113 EXPECT_EQ(event.update.nodes[0].role, |
| 138 ui::AX_ROLE_ROOT_WEB_AREA); | 114 ui::AX_ROLE_ROOT_WEB_AREA); |
| 139 EXPECT_EQ(event.nodes[0].state, | 115 EXPECT_EQ(event.update.nodes[0].state, |
| 140 (1U << ui::AX_STATE_READ_ONLY) | | 116 (1U << ui::AX_STATE_READ_ONLY) | |
| 141 (1U << ui::AX_STATE_FOCUSABLE) | | 117 (1U << ui::AX_STATE_FOCUSABLE) | |
| 142 (1U << ui::AX_STATE_FOCUSED)); | 118 (1U << ui::AX_STATE_FOCUSED)); |
| 143 EXPECT_EQ(event.nodes[0].child_ids.size(), 1U); | 119 EXPECT_EQ(event.update.nodes[0].child_ids.size(), 1U); |
| 144 } | 120 } |
| 145 | 121 |
| 146 // Now focus the input element, and check everything again. | 122 // Now focus the input element, and check everything again. |
| 147 { | 123 { |
| 148 SCOPED_TRACE("input"); | 124 SCOPED_TRACE("input"); |
| 149 sink_->ClearMessages(); | 125 sink_->ClearMessages(); |
| 150 ExecuteJavaScript("document.querySelector('input').focus();"); | 126 ExecuteJavaScript("document.querySelector('input').focus();"); |
| 151 AccessibilityHostMsg_EventParams event; | 127 AccessibilityHostMsg_EventParams event; |
| 152 GetLastAccEvent(&event); | 128 GetLastAccEvent(&event); |
| 153 EXPECT_EQ(event.event_type, | 129 EXPECT_EQ(event.event_type, |
| 154 ui::AX_EVENT_FOCUS); | 130 ui::AX_EVENT_FOCUS); |
| 155 EXPECT_EQ(event.id, 3); | 131 EXPECT_EQ(event.id, 3); |
| 156 EXPECT_EQ(event.nodes[0].id, 1); | 132 EXPECT_EQ(event.update.nodes[0].id, 1); |
| 157 EXPECT_EQ(event.nodes[0].role, | 133 EXPECT_EQ(event.update.nodes[0].role, |
| 158 ui::AX_ROLE_ROOT_WEB_AREA); | 134 ui::AX_ROLE_ROOT_WEB_AREA); |
| 159 EXPECT_EQ(event.nodes[0].state, | 135 EXPECT_EQ(event.update.nodes[0].state, |
| 160 (1U << ui::AX_STATE_READ_ONLY) | | 136 (1U << ui::AX_STATE_READ_ONLY) | |
| 161 (1U << ui::AX_STATE_FOCUSABLE)); | 137 (1U << ui::AX_STATE_FOCUSABLE)); |
| 162 EXPECT_EQ(event.nodes[0].child_ids.size(), 1U); | 138 EXPECT_EQ(event.update.nodes[0].child_ids.size(), 1U); |
| 163 EXPECT_EQ(event.nodes[1].id, 3); | 139 EXPECT_EQ(event.update.nodes[1].id, 3); |
| 164 EXPECT_EQ(event.nodes[1].role, | 140 EXPECT_EQ(event.update.nodes[1].role, |
| 165 ui::AX_ROLE_GROUP); | 141 ui::AX_ROLE_GROUP); |
| 166 EXPECT_EQ(event.nodes[1].state, | 142 EXPECT_EQ(event.update.nodes[1].state, |
| 167 (1U << ui::AX_STATE_FOCUSABLE) | | 143 (1U << ui::AX_STATE_FOCUSABLE) | |
| 168 (1U << ui::AX_STATE_FOCUSED)); | 144 (1U << ui::AX_STATE_FOCUSED)); |
| 169 } | 145 } |
| 170 | 146 |
| 171 // Check other editable text nodes. | 147 // Check other editable text nodes. |
| 172 { | 148 { |
| 173 SCOPED_TRACE("textarea"); | 149 SCOPED_TRACE("textarea"); |
| 174 sink_->ClearMessages(); | 150 sink_->ClearMessages(); |
| 175 ExecuteJavaScript("document.querySelector('textarea').focus();"); | 151 ExecuteJavaScript("document.querySelector('textarea').focus();"); |
| 176 AccessibilityHostMsg_EventParams event; | 152 AccessibilityHostMsg_EventParams event; |
| 177 GetLastAccEvent(&event); | 153 GetLastAccEvent(&event); |
| 178 EXPECT_EQ(event.id, 4); | 154 EXPECT_EQ(event.id, 4); |
| 179 EXPECT_EQ(event.nodes[1].state, | 155 EXPECT_EQ(event.update.nodes[1].state, |
| 180 (1U << ui::AX_STATE_FOCUSABLE) | | 156 (1U << ui::AX_STATE_FOCUSABLE) | |
| 181 (1U << ui::AX_STATE_FOCUSED)); | 157 (1U << ui::AX_STATE_FOCUSED)); |
| 182 } | 158 } |
| 183 | 159 |
| 184 { | 160 { |
| 185 SCOPED_TRACE("contentEditable"); | 161 SCOPED_TRACE("contentEditable"); |
| 186 sink_->ClearMessages(); | 162 sink_->ClearMessages(); |
| 187 ExecuteJavaScript("document.querySelector('p').focus();"); | 163 ExecuteJavaScript("document.querySelector('p').focus();"); |
| 188 AccessibilityHostMsg_EventParams event; | 164 AccessibilityHostMsg_EventParams event; |
| 189 GetLastAccEvent(&event); | 165 GetLastAccEvent(&event); |
| 190 EXPECT_EQ(event.id, 5); | 166 EXPECT_EQ(event.id, 5); |
| 191 EXPECT_EQ(event.nodes[1].state, | 167 EXPECT_EQ(event.update.nodes[1].state, |
| 192 (1U << ui::AX_STATE_FOCUSABLE) | | 168 (1U << ui::AX_STATE_FOCUSABLE) | |
| 193 (1U << ui::AX_STATE_FOCUSED)); | 169 (1U << ui::AX_STATE_FOCUSED)); |
| 194 } | 170 } |
| 195 | 171 |
| 196 { | 172 { |
| 197 SCOPED_TRACE("role=textarea"); | 173 SCOPED_TRACE("role=textarea"); |
| 198 sink_->ClearMessages(); | 174 sink_->ClearMessages(); |
| 199 ExecuteJavaScript("document.querySelector('div').focus();"); | 175 ExecuteJavaScript("document.querySelector('div').focus();"); |
| 200 AccessibilityHostMsg_EventParams event; | 176 AccessibilityHostMsg_EventParams event; |
| 201 GetLastAccEvent(&event); | 177 GetLastAccEvent(&event); |
| 202 EXPECT_EQ(event.id, 6); | 178 EXPECT_EQ(event.id, 6); |
| 203 EXPECT_EQ(event.nodes[1].state, | 179 EXPECT_EQ(event.update.nodes[1].state, |
| 204 (1U << ui::AX_STATE_FOCUSABLE) | | 180 (1U << ui::AX_STATE_FOCUSABLE) | |
| 205 (1U << ui::AX_STATE_FOCUSED)); | 181 (1U << ui::AX_STATE_FOCUSED)); |
| 206 } | 182 } |
| 207 | 183 |
| 208 // Try focusing things that aren't editable text. | 184 // Try focusing things that aren't editable text. |
| 209 { | 185 { |
| 210 SCOPED_TRACE("button"); | 186 SCOPED_TRACE("button"); |
| 211 sink_->ClearMessages(); | 187 sink_->ClearMessages(); |
| 212 ExecuteJavaScript("document.querySelector('button').focus();"); | 188 ExecuteJavaScript("document.querySelector('button').focus();"); |
| 213 AccessibilityHostMsg_EventParams event; | 189 AccessibilityHostMsg_EventParams event; |
| 214 GetLastAccEvent(&event); | 190 GetLastAccEvent(&event); |
| 215 EXPECT_EQ(event.id, 7); | 191 EXPECT_EQ(event.id, 7); |
| 216 EXPECT_EQ(event.nodes[1].state, | 192 EXPECT_EQ(event.update.nodes[1].state, |
| 217 (1U << ui::AX_STATE_FOCUSABLE) | | 193 (1U << ui::AX_STATE_FOCUSABLE) | |
| 218 (1U << ui::AX_STATE_FOCUSED) | | 194 (1U << ui::AX_STATE_FOCUSED) | |
| 219 (1U << ui::AX_STATE_READ_ONLY)); | 195 (1U << ui::AX_STATE_READ_ONLY)); |
| 220 } | 196 } |
| 221 | 197 |
| 222 { | 198 { |
| 223 SCOPED_TRACE("link"); | 199 SCOPED_TRACE("link"); |
| 224 sink_->ClearMessages(); | 200 sink_->ClearMessages(); |
| 225 ExecuteJavaScript("document.querySelector('a').focus();"); | 201 ExecuteJavaScript("document.querySelector('a').focus();"); |
| 226 AccessibilityHostMsg_EventParams event; | 202 AccessibilityHostMsg_EventParams event; |
| 227 GetLastAccEvent(&event); | 203 GetLastAccEvent(&event); |
| 228 EXPECT_EQ(event.id, 8); | 204 EXPECT_EQ(event.id, 8); |
| 229 EXPECT_EQ(event.nodes[1].state, | 205 EXPECT_EQ(event.update.nodes[1].state, |
| 230 (1U << ui::AX_STATE_FOCUSABLE) | | 206 (1U << ui::AX_STATE_FOCUSABLE) | |
| 231 (1U << ui::AX_STATE_FOCUSED) | | 207 (1U << ui::AX_STATE_FOCUSED) | |
| 232 (1U << ui::AX_STATE_READ_ONLY)); | 208 (1U << ui::AX_STATE_READ_ONLY)); |
| 233 } | 209 } |
| 234 | 210 |
| 235 // Clear focus. | 211 // Clear focus. |
| 236 { | 212 { |
| 237 SCOPED_TRACE("Back to document."); | 213 SCOPED_TRACE("Back to document."); |
| 238 sink_->ClearMessages(); | 214 sink_->ClearMessages(); |
| 239 ExecuteJavaScript("document.activeElement.blur()"); | 215 ExecuteJavaScript("document.activeElement.blur()"); |
| 240 AccessibilityHostMsg_EventParams event; | 216 AccessibilityHostMsg_EventParams event; |
| 241 GetLastAccEvent(&event); | 217 GetLastAccEvent(&event); |
| 242 EXPECT_EQ(event.id, 1); | 218 EXPECT_EQ(event.id, 1); |
| 243 } | 219 } |
| 244 } | 220 } |
| 245 | 221 |
| 246 TEST_F(RendererAccessibilityTest, SendFullAccessibilityTreeOnReload) { | 222 TEST_F(RendererAccessibilityTest, SendFullAccessibilityTreeOnReload) { |
| 247 // The job of RendererAccessibilityComplete is to serialize the | 223 // The job of TestRendererAccessibilityComplete is to serialize the |
|
aboxhall
2014/02/25 17:45:35
What happened here?
dmazzoni
2014/02/27 20:51:44
Oops, I got too aggressive with search-and-replace
| |
| 248 // accessibility tree built by WebKit and send it to the browser. | 224 // accessibility tree built by WebKit and send it to the browser. |
| 249 // When the accessibility tree changes, it tries to send only | 225 // When the accessibility tree changes, it tries to send only |
| 250 // the nodes that actually changed or were reparented. This test | 226 // the nodes that actually changed or were reparented. This test |
| 251 // ensures that the messages sent are correct in cases when a page | 227 // ensures that the messages sent are correct in cases when a page |
| 252 // reloads, and that internal state is properly garbage-collected. | 228 // reloads, and that internal state is properly garbage-collected. |
| 253 std::string html = | 229 std::string html = |
| 254 "<body>" | 230 "<body>" |
| 255 " <div role='group' id='A'>" | 231 " <div role='group' id='A'>" |
| 256 " <div role='group' id='A1'></div>" | 232 " <div role='group' id='A1'></div>" |
| 257 " <div role='group' id='A2'></div>" | 233 " <div role='group' id='A2'></div>" |
| 258 " </div>" | 234 " </div>" |
| 259 "</body>"; | 235 "</body>"; |
| 260 LoadHTML(html.c_str()); | 236 LoadHTML(html.c_str()); |
| 261 | 237 |
| 262 // Creating a RendererAccessibilityComplete should sent the tree | 238 // Creating a TestRendererAccessibilityComplete should sent the tree |
| 263 // to the browser. | 239 // to the browser. |
| 264 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 240 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 265 new TestRendererAccessibilityComplete(view())); | 241 new TestRendererAccessibilityComplete(view())); |
| 266 accessibility->SendPendingAccessibilityEvents(); | 242 accessibility->SendPendingAccessibilityEvents(); |
| 267 EXPECT_EQ(4, accessibility->browser_tree_node_count()); | |
| 268 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 243 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
| 269 | 244 |
| 270 // If we post another event but the tree doesn't change, | 245 // If we post another event but the tree doesn't change, |
| 271 // we should only send 1 node to the browser. | 246 // we should only send 1 node to the browser. |
| 272 sink_->ClearMessages(); | 247 sink_->ClearMessages(); |
| 273 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 248 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 274 WebAXObject root_obj = document.accessibilityObject(); | 249 WebAXObject root_obj = document.accessibilityObject(); |
| 275 accessibility->HandleAXEvent( | 250 accessibility->HandleAXEvent( |
| 276 root_obj, | 251 root_obj, |
| 277 ui::AX_EVENT_LAYOUT_COMPLETE); | 252 ui::AX_EVENT_LAYOUT_COMPLETE); |
| 278 accessibility->SendPendingAccessibilityEvents(); | 253 accessibility->SendPendingAccessibilityEvents(); |
| 279 EXPECT_EQ(4, accessibility->browser_tree_node_count()); | |
| 280 EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser()); | 254 EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser()); |
| 281 { | 255 { |
| 282 // Make sure it's the root object that was updated. | 256 // Make sure it's the root object that was updated. |
| 283 AccessibilityHostMsg_EventParams event; | 257 AccessibilityHostMsg_EventParams event; |
| 284 GetLastAccEvent(&event); | 258 GetLastAccEvent(&event); |
| 285 EXPECT_EQ(root_obj.axID(), event.nodes[0].id); | 259 EXPECT_EQ(root_obj.axID(), event.update.nodes[0].id); |
| 286 } | 260 } |
| 287 | 261 |
| 288 // If we reload the page and send a event, we should send | 262 // If we reload the page and send a event, we should send |
| 289 // all 4 nodes to the browser. Also double-check that we didn't | 263 // all 4 nodes to the browser. Also double-check that we didn't |
| 290 // leak any of the old BrowserTreeNodes. | 264 // leak any of the old BrowserTreeNodes. |
| 291 LoadHTML(html.c_str()); | 265 LoadHTML(html.c_str()); |
| 292 document = view()->GetWebView()->mainFrame()->document(); | 266 document = view()->GetWebView()->mainFrame()->document(); |
| 293 root_obj = document.accessibilityObject(); | 267 root_obj = document.accessibilityObject(); |
| 294 sink_->ClearMessages(); | 268 sink_->ClearMessages(); |
| 295 accessibility->HandleAXEvent( | 269 accessibility->HandleAXEvent( |
| 296 root_obj, | 270 root_obj, |
| 297 ui::AX_EVENT_LAYOUT_COMPLETE); | 271 ui::AX_EVENT_LAYOUT_COMPLETE); |
| 298 accessibility->SendPendingAccessibilityEvents(); | 272 accessibility->SendPendingAccessibilityEvents(); |
| 299 EXPECT_EQ(4, accessibility->browser_tree_node_count()); | |
| 300 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 273 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
| 301 | 274 |
| 302 // Even if the first event is sent on an element other than | 275 // Even if the first event is sent on an element other than |
| 303 // the root, the whole tree should be updated because we know | 276 // the root, the whole tree should be updated because we know |
| 304 // the browser doesn't have the root element. | 277 // the browser doesn't have the root element. |
| 305 LoadHTML(html.c_str()); | 278 LoadHTML(html.c_str()); |
| 306 document = view()->GetWebView()->mainFrame()->document(); | 279 document = view()->GetWebView()->mainFrame()->document(); |
| 307 root_obj = document.accessibilityObject(); | 280 root_obj = document.accessibilityObject(); |
| 308 sink_->ClearMessages(); | 281 sink_->ClearMessages(); |
| 309 const WebAXObject& first_child = root_obj.childAt(0); | 282 const WebAXObject& first_child = root_obj.childAt(0); |
| 310 accessibility->HandleAXEvent( | 283 accessibility->HandleAXEvent( |
| 311 first_child, | 284 first_child, |
| 312 ui::AX_EVENT_LIVE_REGION_CHANGED); | 285 ui::AX_EVENT_LIVE_REGION_CHANGED); |
| 313 accessibility->SendPendingAccessibilityEvents(); | 286 accessibility->SendPendingAccessibilityEvents(); |
| 314 EXPECT_EQ(4, accessibility->browser_tree_node_count()); | |
| 315 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 287 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
| 316 } | 288 } |
| 317 | 289 |
| 318 // http://crbug.com/253537 | 290 // http://crbug.com/253537 |
| 319 #if defined(OS_ANDROID) | 291 #if defined(OS_ANDROID) |
| 320 #define MAYBE_AccessibilityMessagesQueueWhileSwappedOut \ | 292 #define MAYBE_AccessibilityMessagesQueueWhileSwappedOut \ |
| 321 DISABLED_AccessibilityMessagesQueueWhileSwappedOut | 293 DISABLED_AccessibilityMessagesQueueWhileSwappedOut |
| 322 #else | 294 #else |
| 323 #define MAYBE_AccessibilityMessagesQueueWhileSwappedOut \ | 295 #define MAYBE_AccessibilityMessagesQueueWhileSwappedOut \ |
| 324 AccessibilityMessagesQueueWhileSwappedOut | 296 AccessibilityMessagesQueueWhileSwappedOut |
| 325 #endif | 297 #endif |
| 326 | 298 |
| 327 TEST_F(RendererAccessibilityTest, | 299 TEST_F(RendererAccessibilityTest, |
| 328 MAYBE_AccessibilityMessagesQueueWhileSwappedOut) { | 300 MAYBE_AccessibilityMessagesQueueWhileSwappedOut) { |
| 329 std::string html = | 301 std::string html = |
| 330 "<body>" | 302 "<body>" |
| 331 " <p>Hello, world.</p>" | 303 " <p>Hello, world.</p>" |
| 332 "</body>"; | 304 "</body>"; |
| 333 LoadHTML(html.c_str()); | 305 LoadHTML(html.c_str()); |
| 334 | 306 |
| 335 // Creating a RendererAccessibilityComplete should send the tree | 307 // Creating a TestRendererAccessibilityComplete should send the tree |
| 336 // to the browser. | 308 // to the browser. |
| 337 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 309 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 338 new TestRendererAccessibilityComplete(view())); | 310 new TestRendererAccessibilityComplete(view())); |
| 339 accessibility->SendPendingAccessibilityEvents(); | 311 accessibility->SendPendingAccessibilityEvents(); |
| 340 EXPECT_EQ(5, accessibility->browser_tree_node_count()); | |
| 341 EXPECT_EQ(5, CountAccessibilityNodesSentToBrowser()); | 312 EXPECT_EQ(5, CountAccessibilityNodesSentToBrowser()); |
| 342 | 313 |
| 343 // Post a "value changed" event, but then swap out | 314 // Post a "value changed" event, but then swap out |
| 344 // before sending it. It shouldn't send the event while | 315 // before sending it. It shouldn't send the event while |
| 345 // swapped out. | 316 // swapped out. |
| 346 sink_->ClearMessages(); | 317 sink_->ClearMessages(); |
| 347 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 318 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 348 WebAXObject root_obj = document.accessibilityObject(); | 319 WebAXObject root_obj = document.accessibilityObject(); |
| 349 accessibility->HandleAXEvent( | 320 accessibility->HandleAXEvent( |
| 350 root_obj, | 321 root_obj, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 " <div role='group' id='C' style='visibility:visible'>" | 355 " <div role='group' id='C' style='visibility:visible'>" |
| 385 " </div>" | 356 " </div>" |
| 386 " </div>" | 357 " </div>" |
| 387 " </div>" | 358 " </div>" |
| 388 "</body>"; | 359 "</body>"; |
| 389 LoadHTML(html.c_str()); | 360 LoadHTML(html.c_str()); |
| 390 | 361 |
| 391 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 362 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 392 new TestRendererAccessibilityComplete(view())); | 363 new TestRendererAccessibilityComplete(view())); |
| 393 accessibility->SendPendingAccessibilityEvents(); | 364 accessibility->SendPendingAccessibilityEvents(); |
| 394 EXPECT_EQ(4, accessibility->browser_tree_node_count()); | |
| 395 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 365 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
| 396 | 366 |
| 397 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 367 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 398 WebAXObject root_obj = document.accessibilityObject(); | 368 WebAXObject root_obj = document.accessibilityObject(); |
| 399 WebAXObject node_a = root_obj.childAt(0); | 369 WebAXObject node_a = root_obj.childAt(0); |
| 400 WebAXObject node_b = node_a.childAt(0); | 370 WebAXObject node_b = node_a.childAt(0); |
| 401 WebAXObject node_c = node_b.childAt(0); | 371 WebAXObject node_c = node_b.childAt(0); |
| 402 | 372 |
| 403 // Hide node 'B' ('C' stays visible). | 373 // Hide node 'B' ('C' stays visible). |
| 404 ExecuteJavaScript( | 374 ExecuteJavaScript( |
| 405 "document.getElementById('B').style.visibility = 'hidden';"); | 375 "document.getElementById('B').style.visibility = 'hidden';"); |
| 406 // Force layout now. | 376 // Force layout now. |
| 407 ExecuteJavaScript("document.getElementById('B').offsetLeft;"); | 377 ExecuteJavaScript("document.getElementById('B').offsetLeft;"); |
| 408 | 378 |
| 409 // Send a childrenChanged on 'A'. | 379 // Send a childrenChanged on 'A'. |
| 410 sink_->ClearMessages(); | 380 sink_->ClearMessages(); |
| 411 accessibility->HandleAXEvent( | 381 accessibility->HandleAXEvent( |
| 412 node_a, | 382 node_a, |
| 413 ui::AX_EVENT_CHILDREN_CHANGED); | 383 ui::AX_EVENT_CHILDREN_CHANGED); |
| 414 | 384 |
| 415 accessibility->SendPendingAccessibilityEvents(); | 385 accessibility->SendPendingAccessibilityEvents(); |
| 416 EXPECT_EQ(3, accessibility->browser_tree_node_count()); | |
| 417 AccessibilityHostMsg_EventParams event; | 386 AccessibilityHostMsg_EventParams event; |
| 418 GetLastAccEvent(&event); | 387 GetLastAccEvent(&event); |
| 419 ASSERT_EQ(3U, event.nodes.size()); | 388 ASSERT_EQ(3U, event.update.nodes.size()); |
| 420 | 389 |
| 421 // RendererAccessibilityComplete notices that 'C' is being reparented, | 390 // TestRendererAccessibilityComplete notices that 'C' is being reparented, |
| 422 // so it updates 'B' first to remove 'C' as a child, then 'A' to add it, | 391 // so it updates 'B' first to remove 'C' as a child, then 'A' to add it, |
| 423 // and finally it updates 'C'. | 392 // and finally it updates 'C'. |
| 424 EXPECT_EQ(node_b.axID(), event.nodes[0].id); | 393 EXPECT_EQ(node_b.axID(), event.update.nodes[0].id); |
| 425 EXPECT_EQ(node_a.axID(), event.nodes[1].id); | 394 EXPECT_EQ(node_a.axID(), event.update.nodes[1].id); |
| 426 EXPECT_EQ(node_c.axID(), event.nodes[2].id); | 395 EXPECT_EQ(node_c.axID(), event.update.nodes[2].id); |
| 427 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 396 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
| 428 } | 397 } |
| 429 | 398 |
| 430 TEST_F(RendererAccessibilityTest, ShowAccessibilityObject) { | 399 TEST_F(RendererAccessibilityTest, ShowAccessibilityObject) { |
| 431 // Test RendererAccessibilityComplete and make sure it sends the | 400 // Test RendererAccessibilityComplete and make sure it sends the |
| 432 // proper event to the browser when an object in the tree | 401 // proper event to the browser when an object in the tree |
| 433 // is shown, causing its own already-visible children to be | 402 // is shown, causing its own already-visible children to be |
| 434 // reparented to it. | 403 // reparented to it. |
| 435 std::string html = | 404 std::string html = |
| 436 "<body>" | 405 "<body>" |
| 437 " <div role='group' id='A'>" | 406 " <div role='group' id='A'>" |
| 438 " <div role='group' id='B' style='visibility:hidden'>" | 407 " <div role='group' id='B' style='visibility:hidden'>" |
| 439 " <div role='group' id='C' style='visibility:visible'>" | 408 " <div role='group' id='C' style='visibility:visible'>" |
| 440 " </div>" | 409 " </div>" |
| 441 " </div>" | 410 " </div>" |
| 442 " </div>" | 411 " </div>" |
| 443 "</body>"; | 412 "</body>"; |
| 444 LoadHTML(html.c_str()); | 413 LoadHTML(html.c_str()); |
| 445 | 414 |
| 446 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 415 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 447 new TestRendererAccessibilityComplete(view())); | 416 new TestRendererAccessibilityComplete(view())); |
| 448 accessibility->SendPendingAccessibilityEvents(); | 417 accessibility->SendPendingAccessibilityEvents(); |
| 449 EXPECT_EQ(3, accessibility->browser_tree_node_count()); | |
| 450 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 418 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
| 451 | 419 |
| 452 // Show node 'B', then send a childrenChanged on 'A'. | 420 // Show node 'B', then send a childrenChanged on 'A'. |
| 453 ExecuteJavaScript( | 421 ExecuteJavaScript( |
| 454 "document.getElementById('B').style.visibility = 'visible';"); | 422 "document.getElementById('B').style.visibility = 'visible';"); |
| 455 ExecuteJavaScript("document.getElementById('B').offsetLeft;"); | 423 ExecuteJavaScript("document.getElementById('B').offsetLeft;"); |
| 456 | 424 |
| 457 sink_->ClearMessages(); | 425 sink_->ClearMessages(); |
| 458 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 426 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 459 WebAXObject root_obj = document.accessibilityObject(); | 427 WebAXObject root_obj = document.accessibilityObject(); |
| 460 WebAXObject node_a = root_obj.childAt(0); | 428 WebAXObject node_a = root_obj.childAt(0); |
| 461 accessibility->HandleAXEvent( | 429 accessibility->HandleAXEvent( |
| 462 node_a, | 430 node_a, |
| 463 ui::AX_EVENT_CHILDREN_CHANGED); | 431 ui::AX_EVENT_CHILDREN_CHANGED); |
| 464 | 432 |
| 465 accessibility->SendPendingAccessibilityEvents(); | 433 accessibility->SendPendingAccessibilityEvents(); |
| 466 EXPECT_EQ(4, accessibility->browser_tree_node_count()); | |
| 467 AccessibilityHostMsg_EventParams event; | 434 AccessibilityHostMsg_EventParams event; |
| 468 GetLastAccEvent(&event); | 435 GetLastAccEvent(&event); |
| 469 ASSERT_EQ(3U, event.nodes.size()); | 436 ASSERT_EQ(3U, event.update.nodes.size()); |
| 470 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 437 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
| 471 } | 438 } |
| 472 | 439 |
| 473 TEST_F(RendererAccessibilityTest, DetachAccessibilityObject) { | 440 TEST_F(RendererAccessibilityTest, DetachAccessibilityObject) { |
| 474 // Test RendererAccessibilityComplete and make sure it sends the | 441 // Test RendererAccessibilityComplete and make sure it sends the |
| 475 // proper event to the browser when an object in the tree | 442 // proper event to the browser when an object in the tree |
| 476 // is detached, but its children are not. This can happen when | 443 // is detached, but its children are not. This can happen when |
| 477 // a layout occurs and an anonymous render block is no longer needed. | 444 // a layout occurs and an anonymous render block is no longer needed. |
| 478 std::string html = | 445 std::string html = |
| 479 "<body aria-label='Body'>" | 446 "<body aria-label='Body'>" |
| 480 "<span>1</span><span style='display:block'>2</span>" | 447 "<span>1</span><span style='display:block'>2</span>" |
| 481 "</body>"; | 448 "</body>"; |
| 482 LoadHTML(html.c_str()); | 449 LoadHTML(html.c_str()); |
| 483 | 450 |
| 484 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 451 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 485 new TestRendererAccessibilityComplete(view())); | 452 new TestRendererAccessibilityComplete(view())); |
| 486 accessibility->SendPendingAccessibilityEvents(); | 453 accessibility->SendPendingAccessibilityEvents(); |
| 487 EXPECT_EQ(7, accessibility->browser_tree_node_count()); | |
| 488 EXPECT_EQ(7, CountAccessibilityNodesSentToBrowser()); | 454 EXPECT_EQ(7, CountAccessibilityNodesSentToBrowser()); |
| 489 | 455 |
| 490 // Initially, the accessibility tree looks like this: | 456 // Initially, the accessibility tree looks like this: |
| 491 // | 457 // |
| 492 // Document | 458 // Document |
| 493 // +--Body | 459 // +--Body |
| 494 // +--Anonymous Block | 460 // +--Anonymous Block |
| 495 // +--Static Text "1" | 461 // +--Static Text "1" |
| 496 // +--Inline Text Box "1" | 462 // +--Inline Text Box "1" |
| 497 // +--Static Text "2" | 463 // +--Static Text "2" |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 524 // +--Body | 490 // +--Body |
| 525 // +--Static Text "1" | 491 // +--Static Text "1" |
| 526 // +--Inline Text Box "1" | 492 // +--Inline Text Box "1" |
| 527 // +--Static Text "2" | 493 // +--Static Text "2" |
| 528 // +--Inline Text Box "2" | 494 // +--Inline Text Box "2" |
| 529 // | 495 // |
| 530 // We just assert that there are now four nodes in the | 496 // We just assert that there are now four nodes in the |
| 531 // accessibility tree and that only three nodes needed | 497 // accessibility tree and that only three nodes needed |
| 532 // to be updated (the body, the static text 1, and | 498 // to be updated (the body, the static text 1, and |
| 533 // the static text 2). | 499 // the static text 2). |
| 534 EXPECT_EQ(6, accessibility->browser_tree_node_count()); | |
| 535 | 500 |
| 536 AccessibilityHostMsg_EventParams event; | 501 AccessibilityHostMsg_EventParams event; |
| 537 GetLastAccEvent(&event); | 502 GetLastAccEvent(&event); |
| 538 ASSERT_EQ(5U, event.nodes.size()); | 503 ASSERT_EQ(5U, event.update.nodes.size()); |
| 539 | 504 |
| 540 EXPECT_EQ(body.axID(), event.nodes[0].id); | 505 EXPECT_EQ(body.axID(), event.update.nodes[0].id); |
| 541 EXPECT_EQ(text_1.axID(), event.nodes[1].id); | 506 EXPECT_EQ(text_1.axID(), event.update.nodes[1].id); |
| 542 // The third event is to update text_2, but its id changes | 507 // The third event is to update text_2, but its id changes |
| 543 // so we don't have a test expectation for it. | 508 // so we don't have a test expectation for it. |
| 544 } | 509 } |
| 545 | 510 |
| 546 } // namespace content | 511 } // namespace content |
| OLD | NEW |