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
3 // found in the LICENSE file.
5 #include "base/utf_string_conversions.h"
6 #include "content/common/accessibility_messages.h"
7 #include "content/common/accessibility_node_data.h"
8 #include "content/common/view_messages.h"
9 #include "content/renderer/render_view_impl.h"
10 #include "content/public/test/render_view_test.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
17 class RendererAccessibilityTest
: public RenderViewTest
{
19 RendererAccessibilityTest() {}
21 RenderViewImpl
* view() {
22 return static_cast<RenderViewImpl
*>(view_
);
25 virtual void SetUp() {
26 RenderViewTest::SetUp();
27 sink_
= &render_thread_
->sink();
30 void SetMode(AccessibilityMode mode
) {
31 view()->OnSetAccessibilityMode(mode
);
34 void GetLastAccNotification(
35 AccessibilityHostMsg_NotificationParams
* params
) {
36 const IPC::Message
* message
=
37 sink_
->GetUniqueMessageMatching(AccessibilityHostMsg_Notifications::ID
);
39 Tuple1
<std::vector
<AccessibilityHostMsg_NotificationParams
> > param
;
40 AccessibilityHostMsg_Notifications::Read(message
, ¶m
);
41 ASSERT_EQ(param
.a
.size(), 1U);
48 DISALLOW_COPY_AND_ASSIGN(RendererAccessibilityTest
);
51 TEST_F(RendererAccessibilityTest
, EditableTextModeFocusNotifications
) {
52 SetMode(AccessibilityModeEditableTextOnly
);
54 // Set a minimum size and give focus so simulated events work.
55 view()->webwidget()->resize(WebKit::WebSize(500, 500));
56 view()->webwidget()->setFocus(true);
61 " <textarea></textarea>"
62 " <p contentEditable>Editable</p>"
63 " <div tabindex=0 role=textbox>Textbox</div>"
64 " <button>Button</button>"
68 // Load the test page.
69 LoadHTML(html
.c_str());
71 // We should have sent a message to the browser with the initial focus
74 SCOPED_TRACE("Initial focus on document");
75 AccessibilityHostMsg_NotificationParams notification
;
76 GetLastAccNotification(¬ification
);
77 EXPECT_EQ(notification
.notification_type
,
78 AccessibilityNotificationLayoutComplete
);
79 EXPECT_EQ(notification
.includes_children
, true);
80 EXPECT_EQ(notification
.id
, 1);
81 EXPECT_EQ(notification
.acc_tree
.id
, 1);
82 EXPECT_EQ(notification
.acc_tree
.role
,
83 AccessibilityNodeData::ROLE_ROOT_WEB_AREA
);
84 EXPECT_EQ(notification
.acc_tree
.state
,
85 (1U << AccessibilityNodeData::STATE_READONLY
) |
86 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
87 (1U << AccessibilityNodeData::STATE_FOCUSED
));
88 EXPECT_EQ(notification
.acc_tree
.children
.size(), 1U);
91 // Now focus the input element, and check everything again.
93 SCOPED_TRACE("input");
94 sink_
->ClearMessages();
95 ExecuteJavaScript("document.querySelector('input').focus();");
96 AccessibilityHostMsg_NotificationParams notification
;
97 GetLastAccNotification(¬ification
);
98 EXPECT_EQ(notification
.notification_type
,
99 AccessibilityNotificationFocusChanged
);
100 EXPECT_EQ(notification
.includes_children
, true);
101 EXPECT_EQ(notification
.id
, 3);
102 EXPECT_EQ(notification
.acc_tree
.id
, 1);
103 EXPECT_EQ(notification
.acc_tree
.role
,
104 AccessibilityNodeData::ROLE_ROOT_WEB_AREA
);
105 EXPECT_EQ(notification
.acc_tree
.state
,
106 (1U << AccessibilityNodeData::STATE_READONLY
) |
107 (1U << AccessibilityNodeData::STATE_FOCUSABLE
));
108 EXPECT_EQ(notification
.acc_tree
.children
.size(), 1U);
109 EXPECT_EQ(notification
.acc_tree
.children
[0].id
, 3);
110 EXPECT_EQ(notification
.acc_tree
.children
[0].role
,
111 AccessibilityNodeData::ROLE_GROUP
);
112 EXPECT_EQ(notification
.acc_tree
.children
[0].state
,
113 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
114 (1U << AccessibilityNodeData::STATE_FOCUSED
));
117 // Check other editable text nodes.
119 SCOPED_TRACE("textarea");
120 sink_
->ClearMessages();
121 ExecuteJavaScript("document.querySelector('textarea').focus();");
122 AccessibilityHostMsg_NotificationParams notification
;
123 GetLastAccNotification(¬ification
);
124 EXPECT_EQ(notification
.id
, 4);
125 EXPECT_EQ(notification
.acc_tree
.children
[0].state
,
126 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
127 (1U << AccessibilityNodeData::STATE_FOCUSED
));
131 SCOPED_TRACE("contentEditable");
132 sink_
->ClearMessages();
133 ExecuteJavaScript("document.querySelector('p').focus();");
134 AccessibilityHostMsg_NotificationParams notification
;
135 GetLastAccNotification(¬ification
);
136 EXPECT_EQ(notification
.id
, 5);
137 EXPECT_EQ(notification
.acc_tree
.children
[0].state
,
138 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
139 (1U << AccessibilityNodeData::STATE_FOCUSED
));
143 SCOPED_TRACE("role=textarea");
144 sink_
->ClearMessages();
145 ExecuteJavaScript("document.querySelector('div').focus();");
146 AccessibilityHostMsg_NotificationParams notification
;
147 GetLastAccNotification(¬ification
);
148 EXPECT_EQ(notification
.id
, 6);
149 EXPECT_EQ(notification
.acc_tree
.children
[0].state
,
150 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
151 (1U << AccessibilityNodeData::STATE_FOCUSED
));
154 // Try focusing things that aren't editable text.
156 SCOPED_TRACE("button");
157 sink_
->ClearMessages();
158 ExecuteJavaScript("document.querySelector('button').focus();");
159 AccessibilityHostMsg_NotificationParams notification
;
160 GetLastAccNotification(¬ification
);
161 EXPECT_EQ(notification
.id
, 7);
162 EXPECT_EQ(notification
.acc_tree
.children
[0].state
,
163 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
164 (1U << AccessibilityNodeData::STATE_FOCUSED
) |
165 (1U << AccessibilityNodeData::STATE_READONLY
));
169 SCOPED_TRACE("link");
170 sink_
->ClearMessages();
171 ExecuteJavaScript("document.querySelector('a').focus();");
172 AccessibilityHostMsg_NotificationParams notification
;
173 GetLastAccNotification(¬ification
);
174 EXPECT_EQ(notification
.id
, 8);
175 EXPECT_EQ(notification
.acc_tree
.children
[0].state
,
176 (1U << AccessibilityNodeData::STATE_FOCUSABLE
) |
177 (1U << AccessibilityNodeData::STATE_FOCUSED
) |
178 (1U << AccessibilityNodeData::STATE_READONLY
));
183 SCOPED_TRACE("Back to document.");
184 sink_
->ClearMessages();
185 ExecuteJavaScript("document.activeElement.blur()");
186 AccessibilityHostMsg_NotificationParams notification
;
187 GetLastAccNotification(¬ification
);
188 EXPECT_EQ(notification
.id
, 1);
192 } // namespace content