Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: chrome/browser/accessibility_win_browsertest.cc

Issue 3117036: Update browser cache of accessibility tree on renderer sub-tree changes.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Updating from comments. Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/browser_accessibility_manager_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 <atlbase.h> 5 #include <atlbase.h>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/scoped_comptr_win.h" 8 #include "base/scoped_comptr_win.h"
9 #include "chrome/browser/browser.h" 9 #include "chrome/browser/browser.h"
10 #include "chrome/browser/browser_window.h" 10 #include "chrome/browser/browser_window.h"
11 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" 11 #include "chrome/browser/renderer_host/render_widget_host_view_win.h"
12 #include "chrome/browser/tab_contents/tab_contents.h" 12 #include "chrome/browser/tab_contents/tab_contents.h"
13 #include "chrome/common/chrome_switches.h" 13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/notification_type.h" 14 #include "chrome/common/notification_type.h"
15 #include "chrome/test/in_process_browser_test.h" 15 #include "chrome/test/in_process_browser_test.h"
16 #include "chrome/test/ui_test_utils.h" 16 #include "chrome/test/ui_test_utils.h"
17 17
18 using std::auto_ptr;
19 using std::vector;
20 using std::wstring;
21
18 namespace { 22 namespace {
19 23
20 class AccessibilityWinBrowserTest : public InProcessBrowserTest { 24 class AccessibilityWinBrowserTest : public InProcessBrowserTest {
21 public: 25 public:
22 AccessibilityWinBrowserTest() : screenreader_running_(FALSE) {} 26 AccessibilityWinBrowserTest() : screenreader_running_(FALSE) {}
23 27
24 // InProcessBrowserTest 28 // InProcessBrowserTest
25 void SetUpInProcessBrowserTestFixture(); 29 void SetUpInProcessBrowserTestFixture();
26 void TearDownInProcessBrowserTestFixture(); 30 void TearDownInProcessBrowserTestFixture();
27 31
(...skipping 22 matching lines...) Expand all
50 // Restore the SPI_SETSCREENREADER flag and notify active applications about 54 // Restore the SPI_SETSCREENREADER flag and notify active applications about
51 // the setting change. 55 // the setting change.
52 ::SystemParametersInfo(SPI_SETSCREENREADER, TRUE, NULL, 0); 56 ::SystemParametersInfo(SPI_SETSCREENREADER, TRUE, NULL, 0);
53 ::SendNotifyMessage( 57 ::SendNotifyMessage(
54 HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0); 58 HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
55 } 59 }
56 } 60 }
57 61
58 class AccessibleChecker { 62 class AccessibleChecker {
59 public: 63 public:
60 AccessibleChecker(std::wstring expected_name, int32 expected_role); 64 AccessibleChecker(
61 AccessibleChecker(std::wstring expected_name, std::wstring expected_role); 65 wstring expected_name,
66 int32 expected_role,
67 wstring expected_value);
68 AccessibleChecker(
69 wstring expected_name,
70 wstring expected_role,
71 wstring expected_value);
62 72
63 // Append an AccessibleChecker that verifies accessibility information for 73 // Append an AccessibleChecker that verifies accessibility information for
64 // a child IAccessible. Order is important. 74 // a child IAccessible. Order is important.
65 void AppendExpectedChild(AccessibleChecker* expected_child); 75 void AppendExpectedChild(AccessibleChecker* expected_child);
66 76
67 // Check that the name and role of the given IAccessible instance and its 77 // Check that the name and role of the given IAccessible instance and its
68 // descendants match the expected names and roles that this object was 78 // descendants match the expected names and roles that this object was
69 // initialized with. 79 // initialized with.
70 void CheckAccessible(IAccessible* accessible); 80 void CheckAccessible(IAccessible* accessible);
71 81
72 typedef std::vector<AccessibleChecker*> AccessibleCheckerVector; 82 // Set the expected value for this AccessibleChecker.
83 void SetExpectedValue(wstring expected_value);
73 84
74 private: 85 private:
75 void CheckAccessibleName(IAccessible* accessible); 86 void CheckAccessibleName(IAccessible* accessible);
76 void CheckAccessibleRole(IAccessible* accessible); 87 void CheckAccessibleRole(IAccessible* accessible);
88 void CheckAccessibleValue(IAccessible* accessible);
77 void CheckAccessibleChildren(IAccessible* accessible); 89 void CheckAccessibleChildren(IAccessible* accessible);
78 90
79 private: 91 private:
92 typedef vector<AccessibleChecker*> AccessibleCheckerVector;
93
80 // Expected accessible name. Checked against IAccessible::get_accName. 94 // Expected accessible name. Checked against IAccessible::get_accName.
81 std::wstring name_; 95 wstring name_;
82 96
83 // Expected accessible role. Checked against IAccessible::get_accRole. 97 // Expected accessible role. Checked against IAccessible::get_accRole.
84 CComVariant role_; 98 CComVariant role_;
85 99
100 // Expected accessible value. Checked against IAccessible::get_accValue.
101 wstring value_;
102
86 // Expected accessible children. Checked using IAccessible::get_accChildCount 103 // Expected accessible children. Checked using IAccessible::get_accChildCount
87 // and ::AccessibleChildren. 104 // and ::AccessibleChildren.
88 AccessibleCheckerVector children_; 105 AccessibleCheckerVector children_;
89 }; 106 };
90 107
91 VARIANT CreateI4Variant(LONG value) { 108 VARIANT CreateI4Variant(LONG value) {
92 VARIANT variant = {0}; 109 VARIANT variant = {0};
93 110
94 V_VT(&variant) = VT_I4; 111 V_VT(&variant) = VT_I4;
95 V_I4(&variant) = value; 112 V_I4(&variant) = value;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 HRESULT hr = AccessibleObjectFromWindow( 144 HRESULT hr = AccessibleObjectFromWindow(
128 hwnd_render_widget_host_view, OBJID_CLIENT, 145 hwnd_render_widget_host_view, OBJID_CLIENT,
129 IID_IAccessible, reinterpret_cast<void**>(&accessible)); 146 IID_IAccessible, reinterpret_cast<void**>(&accessible));
130 EXPECT_EQ(S_OK, hr); 147 EXPECT_EQ(S_OK, hr);
131 EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL)); 148 EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));
132 149
133 return accessible; 150 return accessible;
134 } 151 }
135 152
136 AccessibleChecker::AccessibleChecker( 153 AccessibleChecker::AccessibleChecker(
137 std::wstring expected_name, int32 expected_role) : 154 wstring expected_name, int32 expected_role, wstring expected_value) :
138 name_(expected_name), 155 name_(expected_name),
139 role_(expected_role) { 156 role_(expected_role),
157 value_(expected_value) {
140 } 158 }
141 159
142 AccessibleChecker::AccessibleChecker( 160 AccessibleChecker::AccessibleChecker(
143 std::wstring expected_name, std::wstring expected_role) : 161 wstring expected_name, wstring expected_role, wstring expected_value) :
144 name_(expected_name), 162 name_(expected_name),
145 role_(expected_role.c_str()) { 163 role_(expected_role.c_str()),
164 value_(expected_value) {
146 } 165 }
147 166
148 void AccessibleChecker::AppendExpectedChild( 167 void AccessibleChecker::AppendExpectedChild(
149 AccessibleChecker* expected_child) { 168 AccessibleChecker* expected_child) {
150 children_.push_back(expected_child); 169 children_.push_back(expected_child);
151 } 170 }
152 171
153 void AccessibleChecker::CheckAccessible(IAccessible* accessible) { 172 void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
154 CheckAccessibleName(accessible); 173 CheckAccessibleName(accessible);
155 CheckAccessibleRole(accessible); 174 CheckAccessibleRole(accessible);
175 CheckAccessibleValue(accessible);
156 CheckAccessibleChildren(accessible); 176 CheckAccessibleChildren(accessible);
157 } 177 }
158 178
179 void AccessibleChecker::SetExpectedValue(wstring expected_value) {
180 value_ = expected_value;
181 }
182
159 void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) { 183 void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
160 CComBSTR name; 184 CComBSTR name;
161 HRESULT hr = 185 HRESULT hr =
162 accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name); 186 accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
163 187
164 if (name_.empty()) { 188 if (name_.empty()) {
165 // If the object doesn't have name S_FALSE should be returned. 189 // If the object doesn't have name S_FALSE should be returned.
166 EXPECT_EQ(hr, S_FALSE); 190 EXPECT_EQ(hr, S_FALSE);
167 } else { 191 } else {
168 // Test that the correct string was returned. 192 // Test that the correct string was returned.
169 EXPECT_EQ(hr, S_OK); 193 EXPECT_EQ(hr, S_OK);
170 EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name), 194 EXPECT_STREQ(name_.c_str(),
171 name_.c_str(), name_.length()), 195 wstring(name.m_str, SysStringLen(name)).c_str());
172 CSTR_EQUAL);
173 } 196 }
174 } 197 }
175 198
176 void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) { 199 void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
177 VARIANT var_role = {0}; 200 VARIANT var_role = {0};
178 HRESULT hr = 201 HRESULT hr =
179 accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role); 202 accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
180 EXPECT_EQ(hr, S_OK); 203 EXPECT_EQ(hr, S_OK);
181 ASSERT_TRUE(role_ == var_role); 204 ASSERT_TRUE(role_ == var_role);
182 } 205 }
183 206
207 void AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) {
208 CComBSTR value;
209 HRESULT hr =
210 accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value);
211 EXPECT_EQ(hr, S_OK);
212
213 // Test that the correct string was returned.
214 EXPECT_STREQ(value_.c_str(),
215 wstring(value.m_str, SysStringLen(value)).c_str());
216 }
217
184 void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) { 218 void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
185 LONG child_count = 0; 219 LONG child_count = 0;
186 HRESULT hr = parent->get_accChildCount(&child_count); 220 HRESULT hr = parent->get_accChildCount(&child_count);
187 EXPECT_EQ(hr, S_OK); 221 EXPECT_EQ(hr, S_OK);
188 ASSERT_EQ(child_count, children_.size()); 222 ASSERT_EQ(child_count, children_.size());
189 223
190 std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]); 224 auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
191 LONG obtained_count = 0; 225 LONG obtained_count = 0;
192 hr = AccessibleChildren(parent, 0, child_count, 226 hr = AccessibleChildren(parent, 0, child_count,
193 child_array.get(), &obtained_count); 227 child_array.get(), &obtained_count);
194 ASSERT_EQ(hr, S_OK); 228 ASSERT_EQ(hr, S_OK);
195 ASSERT_EQ(child_count, obtained_count); 229 ASSERT_EQ(child_count, obtained_count);
196 230
197 VARIANT* child = child_array.get(); 231 VARIANT* child = child_array.get();
198 for (AccessibleCheckerVector::iterator child_checker = children_.begin(); 232 for (AccessibleCheckerVector::iterator child_checker = children_.begin();
199 child_checker != children_.end(); 233 child_checker != children_.end();
200 ++child_checker, ++child) { 234 ++child_checker, ++child) {
(...skipping 27 matching lines...) Expand all
228 "data:text/html,<html><head><title>Accessibility Win Test</title></head>" 262 "data:text/html,<html><head><title>Accessibility Win Test</title></head>"
229 "<body><input type='button' value='push' /><input type='checkbox' />" 263 "<body><input type='button' value='push' /><input type='checkbox' />"
230 "</body></html>"); 264 "</body></html>");
231 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 265 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
232 ui_test_utils::WaitForNotification( 266 ui_test_utils::WaitForNotification(
233 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED); 267 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
234 268
235 document_accessible = GetRenderWidgetHostViewClientAccessible(); 269 document_accessible = GetRenderWidgetHostViewClientAccessible();
236 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL)); 270 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
237 271
238 AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON); 272 AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON, L"push");
239 AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON); 273 AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
240 274
241 AccessibleChecker grouping_checker(L"", L"div"); 275 AccessibleChecker grouping_checker(L"", L"div", L"");
242 grouping_checker.AppendExpectedChild(&button_checker); 276 grouping_checker.AppendExpectedChild(&button_checker);
243 grouping_checker.AppendExpectedChild(&checkbox_checker); 277 grouping_checker.AppendExpectedChild(&checkbox_checker);
244 278
245 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT); 279 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
246 document_checker.AppendExpectedChild(&grouping_checker); 280 document_checker.AppendExpectedChild(&grouping_checker);
247 281
248 // Check the accessible tree of the renderer. 282 // Check the accessible tree of the renderer.
249 document_checker.CheckAccessible(document_accessible); 283 document_checker.CheckAccessible(document_accessible);
250 284
251 // Check that document accessible has a parent accessible. 285 // Check that document accessible has a parent accessible.
252 ScopedComPtr<IDispatch> parent_dispatch; 286 ScopedComPtr<IDispatch> parent_dispatch;
253 hr = document_accessible->get_accParent(parent_dispatch.Receive()); 287 hr = document_accessible->get_accParent(parent_dispatch.Receive());
254 EXPECT_EQ(hr, S_OK); 288 EXPECT_EQ(hr, S_OK);
255 EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL)); 289 EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));
256 290
257 // Navigate to another page. 291 // Navigate to another page.
258 GURL about_url("about:"); 292 GURL about_url("about:");
259 ui_test_utils::NavigateToURL(browser(), about_url); 293 ui_test_utils::NavigateToURL(browser(), about_url);
260 294
261 // Verify that the IAccessible reference still points to a valid object and 295 // Verify that the IAccessible reference still points to a valid object and
262 // that calls to its methods fail since the tree is no longer valid after 296 // that calls to its methods fail since the tree is no longer valid after
263 // the page navagation. 297 // the page navagation.
264 // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
265 // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
266 // since the previous render view host connection is lost. Verify that
267 // instances are actually marked as invalid once the browse side cache is
268 // checked in.
269 CComBSTR name; 298 CComBSTR name;
270 hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name); 299 hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
271 ASSERT_EQ(E_FAIL, hr); 300 ASSERT_EQ(E_FAIL, hr);
272 } 301 }
302
303 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
304 TestDynamicAccessibilityTree) {
305 // By requesting an accessible chrome will believe a screen reader has been
306 // detected. Request and wait for the accessibility tree to be updated.
307 GURL tree_url(
308 "data:text/html,<html><body><div onclick=\"this.innerHTML='<b>new text"
309 "</b>';\"><b>old text</b></div></body></html>");
310 ScopedComPtr<IAccessible> document_accessible(
311 GetRenderWidgetHostViewClientAccessible());
312 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
313 ui_test_utils::WaitForNotification(
314 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
315
316 AccessibleChecker text_checker(L"", ROLE_SYSTEM_TEXT, L"old text");
317 AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
318
319 AccessibleChecker div_checker(L"", L"div", L"");
320 div_checker.AppendExpectedChild(&text_checker);
321
322 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
323 document_checker.AppendExpectedChild(&div_checker);
324
325 // Check the accessible tree of the browser.
326 document_accessible = GetRenderWidgetHostViewClientAccessible();
327 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
328 document_checker.CheckAccessible(document_accessible);
329
330 // Perform the default action on the div which executes the script that
331 // updates text node within the div.
332 CComPtr<IDispatch> div_dispatch;
333 HRESULT hr = document_accessible->get_accChild(CreateI4Variant(1),
334 &div_dispatch);
335 EXPECT_EQ(hr, S_OK);
336 CComQIPtr<IAccessible> div_accessible(div_dispatch);
337 hr = div_accessible->accDoDefaultAction(CreateI4Variant(CHILDID_SELF));
338 EXPECT_EQ(hr, S_OK);
339 ui_test_utils::WaitForNotification(
340 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
341
342 // Check that the accessibility tree of the browser has been updated.
343 text_checker.SetExpectedValue(L"new text");
344 document_checker.CheckAccessible(document_accessible);
345 }
273 } // namespace. 346 } // namespace.
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/browser_accessibility_manager_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698