| 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 "base/time/time.h" | 6 #include "base/time/time.h" |
| 7 #include "content/common/frame_messages.h" | 7 #include "content/common/frame_messages.h" |
| 8 #include "content/common/view_message_enums.h" | 8 #include "content/common/view_message_enums.h" |
| 9 #include "content/public/test/render_view_test.h" | 9 #include "content/public/test/render_view_test.h" |
| 10 #include "content/renderer/accessibility/renderer_accessibility_complete.h" | 10 #include "content/renderer/accessibility/renderer_accessibility_complete.h" |
| 11 #include "content/renderer/render_frame_impl.h" |
| 11 #include "content/renderer/render_view_impl.h" | 12 #include "content/renderer/render_view_impl.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "third_party/WebKit/public/platform/WebSize.h" | 14 #include "third_party/WebKit/public/platform/WebSize.h" |
| 14 #include "third_party/WebKit/public/web/WebAXObject.h" | 15 #include "third_party/WebKit/public/web/WebAXObject.h" |
| 15 #include "third_party/WebKit/public/web/WebDocument.h" | 16 #include "third_party/WebKit/public/web/WebDocument.h" |
| 16 #include "third_party/WebKit/public/web/WebView.h" | 17 #include "third_party/WebKit/public/web/WebView.h" |
| 17 #include "ui/accessibility/ax_node_data.h" | 18 #include "ui/accessibility/ax_node_data.h" |
| 18 | 19 |
| 19 using blink::WebAXObject; | 20 using blink::WebAXObject; |
| 20 using blink::WebDocument; | 21 using blink::WebDocument; |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 | 24 |
| 24 class TestRendererAccessibilityComplete : public RendererAccessibilityComplete { | 25 class TestRendererAccessibilityComplete : public RendererAccessibilityComplete { |
| 25 public: | 26 public: |
| 26 explicit TestRendererAccessibilityComplete(RenderViewImpl* render_view) | 27 explicit TestRendererAccessibilityComplete(RenderFrameImpl* render_frame) |
| 27 : RendererAccessibilityComplete(render_view) { | 28 : RendererAccessibilityComplete(render_frame) { |
| 28 } | 29 } |
| 29 | 30 |
| 30 void SendPendingAccessibilityEvents() { | 31 void SendPendingAccessibilityEvents() { |
| 31 RendererAccessibilityComplete::SendPendingAccessibilityEvents(); | 32 RendererAccessibilityComplete::SendPendingAccessibilityEvents(); |
| 32 } | 33 } |
| 33 }; | 34 }; |
| 34 | 35 |
| 35 class RendererAccessibilityTest : public RenderViewTest { | 36 class RendererAccessibilityTest : public RenderViewTest { |
| 36 public: | 37 public: |
| 37 RendererAccessibilityTest() {} | 38 RendererAccessibilityTest() {} |
| 38 | 39 |
| 39 RenderViewImpl* view() { | 40 RenderViewImpl* view() { |
| 40 return static_cast<RenderViewImpl*>(view_); | 41 return static_cast<RenderViewImpl*>(view_); |
| 41 } | 42 } |
| 42 | 43 |
| 43 RenderFrameImpl* frame() { | 44 RenderFrameImpl* frame() { |
| 44 return static_cast<RenderFrameImpl*>(view()->GetMainRenderFrame()); | 45 return static_cast<RenderFrameImpl*>(view()->GetMainRenderFrame()); |
| 45 } | 46 } |
| 46 | 47 |
| 47 virtual void SetUp() { | 48 virtual void SetUp() { |
| 48 RenderViewTest::SetUp(); | 49 RenderViewTest::SetUp(); |
| 49 sink_ = &render_thread_->sink(); | 50 sink_ = &render_thread_->sink(); |
| 50 } | 51 } |
| 51 | 52 |
| 52 void SetMode(AccessibilityMode mode) { | 53 void SetMode(AccessibilityMode mode) { |
| 53 view()->OnSetAccessibilityMode(mode); | 54 frame()->OnSetAccessibilityMode(mode); |
| 54 } | 55 } |
| 55 | 56 |
| 56 void GetLastAccEvent( | 57 void GetLastAccEvent( |
| 57 AccessibilityHostMsg_EventParams* params) { | 58 AccessibilityHostMsg_EventParams* params) { |
| 58 const IPC::Message* message = | 59 const IPC::Message* message = |
| 59 sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID); | 60 sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID); |
| 60 ASSERT_TRUE(message); | 61 ASSERT_TRUE(message); |
| 61 Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param; | 62 Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param; |
| 62 AccessibilityHostMsg_Events::Read(message, ¶m); | 63 AccessibilityHostMsg_Events::Read(message, ¶m); |
| 63 ASSERT_GE(param.a.size(), 1U); | 64 ASSERT_GE(param.a.size(), 1U); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 " <div role='group' id='A'>" | 234 " <div role='group' id='A'>" |
| 234 " <div role='group' id='A1'></div>" | 235 " <div role='group' id='A1'></div>" |
| 235 " <div role='group' id='A2'></div>" | 236 " <div role='group' id='A2'></div>" |
| 236 " </div>" | 237 " </div>" |
| 237 "</body>"; | 238 "</body>"; |
| 238 LoadHTML(html.c_str()); | 239 LoadHTML(html.c_str()); |
| 239 | 240 |
| 240 // Creating a RendererAccessibilityComplete should sent the tree | 241 // Creating a RendererAccessibilityComplete should sent the tree |
| 241 // to the browser. | 242 // to the browser. |
| 242 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 243 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 243 new TestRendererAccessibilityComplete(view())); | 244 new TestRendererAccessibilityComplete(frame())); |
| 244 accessibility->SendPendingAccessibilityEvents(); | 245 accessibility->SendPendingAccessibilityEvents(); |
| 245 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 246 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
| 246 | 247 |
| 247 // If we post another event but the tree doesn't change, | 248 // If we post another event but the tree doesn't change, |
| 248 // we should only send 1 node to the browser. | 249 // we should only send 1 node to the browser. |
| 249 sink_->ClearMessages(); | 250 sink_->ClearMessages(); |
| 250 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 251 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 251 WebAXObject root_obj = document.accessibilityObject(); | 252 WebAXObject root_obj = document.accessibilityObject(); |
| 252 accessibility->HandleAXEvent( | 253 accessibility->HandleAXEvent( |
| 253 root_obj, | 254 root_obj, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 std::string html = | 304 std::string html = |
| 304 "<body>" | 305 "<body>" |
| 305 " <p>Hello, world.</p>" | 306 " <p>Hello, world.</p>" |
| 306 "</body>"; | 307 "</body>"; |
| 307 LoadHTML(html.c_str()); | 308 LoadHTML(html.c_str()); |
| 308 static const int kProxyRoutingId = 13; | 309 static const int kProxyRoutingId = 13; |
| 309 | 310 |
| 310 // Creating a RendererAccessibilityComplete should send the tree | 311 // Creating a RendererAccessibilityComplete should send the tree |
| 311 // to the browser. | 312 // to the browser. |
| 312 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 313 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 313 new TestRendererAccessibilityComplete(view())); | 314 new TestRendererAccessibilityComplete(frame())); |
| 314 accessibility->SendPendingAccessibilityEvents(); | 315 accessibility->SendPendingAccessibilityEvents(); |
| 315 EXPECT_EQ(5, CountAccessibilityNodesSentToBrowser()); | 316 EXPECT_EQ(5, CountAccessibilityNodesSentToBrowser()); |
| 316 | 317 |
| 317 // Post a "value changed" event, but then swap out | 318 // Post a "value changed" event, but then swap out |
| 318 // before sending it. It shouldn't send the event while | 319 // before sending it. It shouldn't send the event while |
| 319 // swapped out. | 320 // swapped out. |
| 320 sink_->ClearMessages(); | 321 sink_->ClearMessages(); |
| 321 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 322 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 322 WebAXObject root_obj = document.accessibilityObject(); | 323 WebAXObject root_obj = document.accessibilityObject(); |
| 323 accessibility->HandleAXEvent( | 324 accessibility->HandleAXEvent( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 " <div role='group' id='A'>" | 358 " <div role='group' id='A'>" |
| 358 " <div role='group' id='B'>" | 359 " <div role='group' id='B'>" |
| 359 " <div role='group' id='C' style='visibility:visible'>" | 360 " <div role='group' id='C' style='visibility:visible'>" |
| 360 " </div>" | 361 " </div>" |
| 361 " </div>" | 362 " </div>" |
| 362 " </div>" | 363 " </div>" |
| 363 "</body>"; | 364 "</body>"; |
| 364 LoadHTML(html.c_str()); | 365 LoadHTML(html.c_str()); |
| 365 | 366 |
| 366 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 367 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 367 new TestRendererAccessibilityComplete(view())); | 368 new TestRendererAccessibilityComplete(frame())); |
| 368 accessibility->SendPendingAccessibilityEvents(); | 369 accessibility->SendPendingAccessibilityEvents(); |
| 369 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); | 370 EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser()); |
| 370 | 371 |
| 371 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 372 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 372 WebAXObject root_obj = document.accessibilityObject(); | 373 WebAXObject root_obj = document.accessibilityObject(); |
| 373 WebAXObject node_a = root_obj.childAt(0); | 374 WebAXObject node_a = root_obj.childAt(0); |
| 374 WebAXObject node_b = node_a.childAt(0); | 375 WebAXObject node_b = node_a.childAt(0); |
| 375 WebAXObject node_c = node_b.childAt(0); | 376 WebAXObject node_c = node_b.childAt(0); |
| 376 | 377 |
| 377 // Hide node 'B' ('C' stays visible). | 378 // Hide node 'B' ('C' stays visible). |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 " <div role='group' id='A'>" | 410 " <div role='group' id='A'>" |
| 410 " <div role='group' id='B' style='visibility:hidden'>" | 411 " <div role='group' id='B' style='visibility:hidden'>" |
| 411 " <div role='group' id='C' style='visibility:visible'>" | 412 " <div role='group' id='C' style='visibility:visible'>" |
| 412 " </div>" | 413 " </div>" |
| 413 " </div>" | 414 " </div>" |
| 414 " </div>" | 415 " </div>" |
| 415 "</body>"; | 416 "</body>"; |
| 416 LoadHTML(html.c_str()); | 417 LoadHTML(html.c_str()); |
| 417 | 418 |
| 418 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 419 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 419 new TestRendererAccessibilityComplete(view())); | 420 new TestRendererAccessibilityComplete(frame())); |
| 420 accessibility->SendPendingAccessibilityEvents(); | 421 accessibility->SendPendingAccessibilityEvents(); |
| 421 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 422 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
| 422 | 423 |
| 423 // Show node 'B', then send a childrenChanged on 'A'. | 424 // Show node 'B', then send a childrenChanged on 'A'. |
| 424 ExecuteJavaScript( | 425 ExecuteJavaScript( |
| 425 "document.getElementById('B').style.visibility = 'visible';"); | 426 "document.getElementById('B').style.visibility = 'visible';"); |
| 426 ExecuteJavaScript("document.getElementById('B').offsetLeft;"); | 427 ExecuteJavaScript("document.getElementById('B').offsetLeft;"); |
| 427 | 428 |
| 428 sink_->ClearMessages(); | 429 sink_->ClearMessages(); |
| 429 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 430 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 453 // proper event to the browser when an object in the tree | 454 // proper event to the browser when an object in the tree |
| 454 // is detached, but its children are not. This can happen when | 455 // is detached, but its children are not. This can happen when |
| 455 // a layout occurs and an anonymous render block is no longer needed. | 456 // a layout occurs and an anonymous render block is no longer needed. |
| 456 std::string html = | 457 std::string html = |
| 457 "<body aria-label='Body'>" | 458 "<body aria-label='Body'>" |
| 458 "<span>1</span><span style='display:block'>2</span>" | 459 "<span>1</span><span style='display:block'>2</span>" |
| 459 "</body>"; | 460 "</body>"; |
| 460 LoadHTML(html.c_str()); | 461 LoadHTML(html.c_str()); |
| 461 | 462 |
| 462 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 463 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 463 new TestRendererAccessibilityComplete(view())); | 464 new TestRendererAccessibilityComplete(frame())); |
| 464 accessibility->SendPendingAccessibilityEvents(); | 465 accessibility->SendPendingAccessibilityEvents(); |
| 465 EXPECT_EQ(7, CountAccessibilityNodesSentToBrowser()); | 466 EXPECT_EQ(7, CountAccessibilityNodesSentToBrowser()); |
| 466 | 467 |
| 467 // Initially, the accessibility tree looks like this: | 468 // Initially, the accessibility tree looks like this: |
| 468 // | 469 // |
| 469 // Document | 470 // Document |
| 470 // +--Body | 471 // +--Body |
| 471 // +--Anonymous Block | 472 // +--Anonymous Block |
| 472 // +--Static Text "1" | 473 // +--Static Text "1" |
| 473 // +--Inline Text Box "1" | 474 // +--Inline Text Box "1" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 | 522 |
| 522 TEST_F(RendererAccessibilityTest, EventOnObjectNotInTree) { | 523 TEST_F(RendererAccessibilityTest, EventOnObjectNotInTree) { |
| 523 // Test RendererAccessibilityComplete and make sure it doesn't send anything | 524 // Test RendererAccessibilityComplete and make sure it doesn't send anything |
| 524 // if we get a notification from Blink for an object that isn't in the | 525 // if we get a notification from Blink for an object that isn't in the |
| 525 // tree, like the scroll area that's the parent of the main document, | 526 // tree, like the scroll area that's the parent of the main document, |
| 526 // which we don't expose. | 527 // which we don't expose. |
| 527 std::string html = "<body><input></body>"; | 528 std::string html = "<body><input></body>"; |
| 528 LoadHTML(html.c_str()); | 529 LoadHTML(html.c_str()); |
| 529 | 530 |
| 530 scoped_ptr<TestRendererAccessibilityComplete> accessibility( | 531 scoped_ptr<TestRendererAccessibilityComplete> accessibility( |
| 531 new TestRendererAccessibilityComplete(view())); | 532 new TestRendererAccessibilityComplete(frame())); |
| 532 accessibility->SendPendingAccessibilityEvents(); | 533 accessibility->SendPendingAccessibilityEvents(); |
| 533 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); | 534 EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); |
| 534 | 535 |
| 535 WebDocument document = view()->GetWebView()->mainFrame()->document(); | 536 WebDocument document = view()->GetWebView()->mainFrame()->document(); |
| 536 WebAXObject root_obj = document.accessibilityObject(); | 537 WebAXObject root_obj = document.accessibilityObject(); |
| 537 WebAXObject scroll_area = root_obj.parentObject(); | 538 WebAXObject scroll_area = root_obj.parentObject(); |
| 538 EXPECT_EQ(blink::WebAXRoleScrollArea, scroll_area.role()); | 539 EXPECT_EQ(blink::WebAXRoleScrollArea, scroll_area.role()); |
| 539 | 540 |
| 540 // Try to fire a message on the scroll area, and assert that we just | 541 // Try to fire a message on the scroll area, and assert that we just |
| 541 // ignore it. | 542 // ignore it. |
| 542 sink_->ClearMessages(); | 543 sink_->ClearMessages(); |
| 543 accessibility->HandleAXEvent(scroll_area, | 544 accessibility->HandleAXEvent(scroll_area, |
| 544 ui::AX_EVENT_VALUE_CHANGED); | 545 ui::AX_EVENT_VALUE_CHANGED); |
| 545 | 546 |
| 546 accessibility->SendPendingAccessibilityEvents(); | 547 accessibility->SendPendingAccessibilityEvents(); |
| 547 | 548 |
| 548 const IPC::Message* message = | 549 const IPC::Message* message = |
| 549 sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID); | 550 sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID); |
| 550 ASSERT_TRUE(message); | 551 ASSERT_TRUE(message); |
| 551 Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param; | 552 Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param; |
| 552 AccessibilityHostMsg_Events::Read(message, ¶m); | 553 AccessibilityHostMsg_Events::Read(message, ¶m); |
| 553 ASSERT_EQ(0U, param.a.size()); | 554 ASSERT_EQ(0U, param.a.size()); |
| 554 } | 555 } |
| 555 | 556 |
| 556 } // namespace content | 557 } // namespace content |
| OLD | NEW |