OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "ui/accessibility/platform/ax_platform_node.h" | 5 #include "ui/accessibility/platform/ax_platform_node.h" |
6 | 6 |
7 #include <atlbase.h> | 7 #include <atlbase.h> |
8 #include <atlcom.h> | 8 #include <atlcom.h> |
9 #include <oleacc.h> | 9 #include <oleacc.h> |
10 | 10 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 return ScopedComPtr<IAccessible>(); | 99 return ScopedComPtr<IAccessible>(); |
100 AXPlatformNode* ax_platform_node = wrapper->ax_platform_node(); | 100 AXPlatformNode* ax_platform_node = wrapper->ax_platform_node(); |
101 IAccessible* iaccessible = ax_platform_node->GetNativeViewAccessible(); | 101 IAccessible* iaccessible = ax_platform_node->GetNativeViewAccessible(); |
102 return ScopedComPtr<IAccessible>(iaccessible); | 102 return ScopedComPtr<IAccessible>(iaccessible); |
103 } | 103 } |
104 | 104 |
105 ScopedComPtr<IAccessible> GetRootIAccessible() { | 105 ScopedComPtr<IAccessible> GetRootIAccessible() { |
106 return IAccessibleFromNode(GetRootNode()); | 106 return IAccessibleFromNode(GetRootNode()); |
107 } | 107 } |
108 | 108 |
109 ScopedComPtr<IAccessible2> ToIAccessible2(ScopedComPtr<IUnknown> unknown) { | |
110 CHECK(unknown); | |
111 ScopedComPtr<IServiceProvider> service_provider; | |
112 unknown.CopyTo(service_provider.GetAddressOf()); | |
113 ScopedComPtr<IAccessible2> result; | |
114 CHECK(SUCCEEDED(service_provider->QueryService(IID_IAccessible2, | |
115 result.GetAddressOf()))); | |
116 return result; | |
117 } | |
118 | |
109 ScopedComPtr<IAccessible2> ToIAccessible2( | 119 ScopedComPtr<IAccessible2> ToIAccessible2( |
110 ScopedComPtr<IAccessible> accessible) { | 120 ScopedComPtr<IAccessible> accessible) { |
111 CHECK(accessible); | 121 CHECK(accessible); |
112 ScopedComPtr<IServiceProvider> service_provider; | 122 ScopedComPtr<IServiceProvider> service_provider; |
113 accessible.CopyTo(service_provider.GetAddressOf()); | 123 accessible.CopyTo(service_provider.GetAddressOf()); |
114 ScopedComPtr<IAccessible2> result; | 124 ScopedComPtr<IAccessible2> result; |
115 CHECK(SUCCEEDED(service_provider->QueryService(IID_IAccessible2, | 125 CHECK(SUCCEEDED(service_provider->QueryService(IID_IAccessible2, |
116 result.GetAddressOf()))); | 126 result.GetAddressOf()))); |
117 return result; | 127 return result; |
118 } | 128 } |
119 | 129 |
130 void CheckVariantHasName(ScopedVariant& variant, | |
131 const wchar_t* expected_name) { | |
132 ScopedComPtr<IAccessible> accessible; | |
133 HRESULT hr = | |
134 V_DISPATCH(variant.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); | |
135 EXPECT_EQ(S_OK, hr); | |
136 ScopedBstr name; | |
137 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); | |
138 EXPECT_STREQ(expected_name, name); | |
139 } | |
140 | |
141 void CheckIUnknownHasName(ScopedComPtr<IUnknown> unknown, | |
142 const wchar_t* expected_name) { | |
143 ScopedComPtr<IAccessible2> accessible = ToIAccessible2(unknown); | |
144 ASSERT_NE(nullptr, accessible); | |
145 | |
146 ScopedBstr name; | |
147 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); | |
148 EXPECT_STREQ(expected_name, name); | |
149 } | |
150 | |
151 void Build4X4Table() { | |
dmazzoni
2017/07/06 23:03:24
Very nice! But it's 3x3, right?
dougt
2017/07/11 23:25:41
off by one! :)
| |
152 /* | |
153 Build a table the looks like: | |
154 | |
155 ---------------------- (A) Column Header | |
156 | | (A) | (B) | (B) Column Header | |
157 ---------------------- (C) Row Header | |
158 | (C) | 1 | 2 | (D) Row Header | |
159 ---------------------- | |
160 | (D) | 3 | 4 | | |
161 ---------------------- | |
162 */ | |
163 | |
164 AXNodeData table; | |
165 table.id = 0; | |
166 table.role = ui::AX_ROLE_TABLE; | |
167 | |
168 table.AddIntAttribute(AX_ATTR_TABLE_ROW_COUNT, 3); | |
169 table.AddIntAttribute(AX_ATTR_TABLE_COLUMN_COUNT, 3); | |
170 | |
171 // Ordering in this list matters. It is used in the calculation | |
172 // of where cells are by the following: | |
173 // int position = row * GetTableColumnCount() + column; | |
174 | |
175 std::vector<int32_t> ids{51, 52, 53, 2, 3, 4, 11, 12, 13}; | |
176 table.AddIntListAttribute(AX_ATTR_CELL_IDS, ids); | |
177 table.AddIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS, ids); | |
178 | |
179 table.child_ids.push_back(50); // Header | |
180 table.child_ids.push_back(1); // Row 1 | |
181 table.child_ids.push_back(10); // Row 2 | |
182 | |
183 // Table column header | |
184 AXNodeData table_row_header; | |
185 table_row_header.id = 50; | |
186 table_row_header.role = ui::AX_ROLE_ROW; | |
187 table_row_header.child_ids.push_back(51); | |
188 table_row_header.child_ids.push_back(52); | |
189 table_row_header.child_ids.push_back(53); | |
190 | |
191 AXNodeData table_column_header_1; | |
192 table_column_header_1.id = 51; | |
193 table_column_header_1.role = ui::AX_ROLE_COLUMN_HEADER; | |
194 | |
195 AXNodeData table_column_header_2; | |
196 table_column_header_2.id = 52; | |
197 table_column_header_2.role = ui::AX_ROLE_COLUMN_HEADER; | |
198 table_column_header_2.AddStringAttribute(AX_ATTR_NAME, "column header 1"); | |
199 | |
200 AXNodeData table_column_header_3; | |
201 table_column_header_3.id = 53; | |
202 table_column_header_3.role = ui::AX_ROLE_COLUMN_HEADER; | |
203 // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a | |
204 // description | |
205 table_column_header_3.AddStringAttribute(AX_ATTR_DESCRIPTION, | |
206 "column header 2"); | |
207 | |
208 // Row 1 | |
209 AXNodeData table_row_1; | |
210 table_row_1.id = 1; | |
211 table_row_1.role = ui::AX_ROLE_ROW; | |
212 table_row_1.child_ids.push_back(2); | |
213 table_row_1.child_ids.push_back(3); | |
214 table_row_1.child_ids.push_back(4); | |
215 | |
216 AXNodeData table_row_header_1; | |
217 table_row_header_1.id = 2; | |
218 table_row_header_1.role = ui::AX_ROLE_ROW_HEADER; | |
219 table_row_header_1.AddStringAttribute(AX_ATTR_NAME, "row header 1"); | |
220 | |
221 AXNodeData table_cell_1; | |
222 table_cell_1.id = 3; | |
223 table_cell_1.role = ui::AX_ROLE_CELL; | |
224 table_cell_1.AddStringAttribute(AX_ATTR_NAME, "1"); | |
225 | |
226 AXNodeData table_cell_2; | |
227 table_cell_2.id = 4; | |
228 table_cell_2.role = ui::AX_ROLE_CELL; | |
229 table_cell_2.AddStringAttribute(AX_ATTR_NAME, "2"); | |
230 | |
231 // Row 2 | |
232 AXNodeData table_row_2; | |
233 table_row_2.id = 10; | |
234 table_row_2.role = ui::AX_ROLE_ROW; | |
235 table_row_2.child_ids.push_back(11); | |
236 table_row_2.child_ids.push_back(12); | |
237 table_row_2.child_ids.push_back(13); | |
238 | |
239 AXNodeData table_row_header_2; | |
240 table_row_header_2.id = 11; | |
241 table_row_header_2.role = ui::AX_ROLE_ROW_HEADER; | |
242 // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a | |
243 // description | |
244 table_row_header_2.AddStringAttribute(AX_ATTR_DESCRIPTION, "row header 2"); | |
245 | |
246 AXNodeData table_cell_3; | |
247 table_cell_3.id = 12; | |
248 table_cell_3.role = ui::AX_ROLE_CELL; | |
249 table_cell_3.AddStringAttribute(AX_ATTR_NAME, "3"); | |
250 | |
251 AXNodeData table_cell_4; | |
252 table_cell_4.id = 13; | |
253 table_cell_4.role = ui::AX_ROLE_CELL; | |
254 table_cell_4.AddStringAttribute(AX_ATTR_NAME, "4"); | |
255 | |
256 AXTreeUpdate update; | |
257 update.root_id = table.id; | |
258 | |
259 update.nodes.push_back(table); | |
260 | |
261 update.nodes.push_back(table_row_header); | |
262 update.nodes.push_back(table_column_header_1); | |
263 update.nodes.push_back(table_column_header_2); | |
264 update.nodes.push_back(table_column_header_3); | |
265 | |
266 update.nodes.push_back(table_row_1); | |
267 update.nodes.push_back(table_row_header_1); | |
268 update.nodes.push_back(table_cell_1); | |
269 update.nodes.push_back(table_cell_2); | |
270 | |
271 update.nodes.push_back(table_row_2); | |
272 update.nodes.push_back(table_row_header_2); | |
273 update.nodes.push_back(table_cell_3); | |
274 update.nodes.push_back(table_cell_4); | |
275 | |
276 Init(update); | |
277 } | |
278 | |
279 ScopedComPtr<IAccessibleTableCell> GetCellInTable() { | |
280 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
281 | |
282 ScopedComPtr<IAccessibleTable2> table; | |
283 root_obj.CopyTo(table.GetAddressOf()); | |
284 if (!table) | |
285 return ScopedComPtr<IAccessibleTableCell>(); | |
286 | |
287 ScopedComPtr<IUnknown> cell; | |
288 table->get_cellAt(1, 1, cell.GetAddressOf()); | |
289 if (!cell) | |
290 return ScopedComPtr<IAccessibleTableCell>(); | |
291 | |
292 ScopedComPtr<IAccessibleTableCell> table_cell; | |
293 cell.CopyTo(table_cell.GetAddressOf()); | |
294 return table_cell; | |
295 } | |
296 | |
120 std::unique_ptr<AXTree> tree_; | 297 std::unique_ptr<AXTree> tree_; |
121 }; | 298 }; |
122 | 299 |
123 TEST_F(AXPlatformNodeWinTest, TestIAccessibleDetachedObject) { | 300 TEST_F(AXPlatformNodeWinTest, TestIAccessibleDetachedObject) { |
124 AXNodeData root; | 301 AXNodeData root; |
125 root.id = 1; | 302 root.id = 1; |
126 root.AddStringAttribute(AX_ATTR_NAME, "Name"); | 303 root.AddStringAttribute(AX_ATTR_NAME, "Name"); |
127 Init(root); | 304 Init(root); |
128 | 305 |
129 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | 306 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); |
(...skipping 30 matching lines...) Expand all Loading... | |
160 ScopedVariant obj; | 337 ScopedVariant obj; |
161 | 338 |
162 // This is way outside of the root node | 339 // This is way outside of the root node |
163 EXPECT_EQ(S_FALSE, root_obj->accHitTest(50, 50, obj.Receive())); | 340 EXPECT_EQ(S_FALSE, root_obj->accHitTest(50, 50, obj.Receive())); |
164 EXPECT_EQ(VT_EMPTY, obj.type()); | 341 EXPECT_EQ(VT_EMPTY, obj.type()); |
165 | 342 |
166 // this is directly on node 1. | 343 // this is directly on node 1. |
167 EXPECT_EQ(S_OK, root_obj->accHitTest(5, 5, obj.Receive())); | 344 EXPECT_EQ(S_OK, root_obj->accHitTest(5, 5, obj.Receive())); |
168 ASSERT_NE(nullptr, obj.ptr()); | 345 ASSERT_NE(nullptr, obj.ptr()); |
169 | 346 |
170 // We got something back, make sure that it has the correct name. | 347 CheckVariantHasName(obj, L"Name1"); |
171 base::win::ScopedComPtr<IAccessible> accessible; | |
172 HRESULT hr = V_DISPATCH(obj.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); | |
173 EXPECT_EQ(S_OK, hr); | |
174 ScopedBstr name; | |
175 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); | |
176 EXPECT_STREQ(L"Name1", name); | |
177 } | 348 } |
178 | 349 |
179 TEST_F(AXPlatformNodeWinTest, TestIAccessibleName) { | 350 TEST_F(AXPlatformNodeWinTest, TestIAccessibleName) { |
180 AXNodeData root; | 351 AXNodeData root; |
181 root.id = 1; | 352 root.id = 1; |
182 root.AddStringAttribute(AX_ATTR_NAME, "Name"); | 353 root.AddStringAttribute(AX_ATTR_NAME, "Name"); |
183 Init(root); | 354 Init(root); |
184 | 355 |
185 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | 356 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); |
186 ScopedBstr name; | 357 ScopedBstr name; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 list_item_3.AddStringAttribute(AX_ATTR_NAME, "Name3"); | 485 list_item_3.AddStringAttribute(AX_ATTR_NAME, "Name3"); |
315 | 486 |
316 Init(list, list_item_2, list_item_3); | 487 Init(list, list_item_2, list_item_3); |
317 | 488 |
318 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | 489 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); |
319 | 490 |
320 ScopedVariant selection; | 491 ScopedVariant selection; |
321 EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive())); | 492 EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive())); |
322 ASSERT_NE(nullptr, selection.ptr()); | 493 ASSERT_NE(nullptr, selection.ptr()); |
323 | 494 |
324 // We got something back, make sure that it has the correct name. | 495 CheckVariantHasName(selection, L"Name2"); |
325 base::win::ScopedComPtr<IAccessible> accessible; | |
326 HRESULT hr = | |
327 V_DISPATCH(selection.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); | |
328 EXPECT_EQ(S_OK, hr); | |
329 ScopedBstr name; | |
330 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); | |
331 EXPECT_STREQ(L"Name2", name); | |
332 } | 496 } |
333 | 497 |
334 TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionMultipleSelected) { | 498 TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionMultipleSelected) { |
335 // We're going to set up a AX_ROLE_LIST_BOX_OPTION with 3 options with | 499 // We're going to set up a AX_ROLE_LIST_BOX_OPTION with 3 options with |
336 // two selected. | 500 // two selected. |
337 AXNodeData list; | 501 AXNodeData list; |
338 list.id = 0; | 502 list.id = 0; |
339 list.role = AX_ROLE_LIST_BOX; | 503 list.role = AX_ROLE_LIST_BOX; |
340 | 504 |
341 list.child_ids.push_back(2); | 505 list.child_ids.push_back(2); |
(...skipping 17 matching lines...) Expand all Loading... | |
359 list_item_4.role = AX_ROLE_LIST_BOX_OPTION; | 523 list_item_4.role = AX_ROLE_LIST_BOX_OPTION; |
360 list_item_4.AddStringAttribute(AX_ATTR_NAME, "Name4"); | 524 list_item_4.AddStringAttribute(AX_ATTR_NAME, "Name4"); |
361 Init(list, list_item_2, list_item_3, list_item_4); | 525 Init(list, list_item_2, list_item_3, list_item_4); |
362 | 526 |
363 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | 527 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); |
364 | 528 |
365 ScopedVariant selection; | 529 ScopedVariant selection; |
366 EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive())); | 530 EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive())); |
367 ASSERT_NE(nullptr, selection.ptr()); | 531 ASSERT_NE(nullptr, selection.ptr()); |
368 | 532 |
369 // We got something back, make sure that it has the corrent name. | 533 // Loop through the selections and make sure we have the right ones |
370 base::win::ScopedComPtr<IEnumVARIANT> accessibles; | 534 ScopedComPtr<IEnumVARIANT> accessibles; |
371 HRESULT hr = | 535 HRESULT hr = |
372 V_DISPATCH(selection.ptr())->QueryInterface(IID_PPV_ARGS(&accessibles)); | 536 V_DISPATCH(selection.ptr())->QueryInterface(IID_PPV_ARGS(&accessibles)); |
373 EXPECT_EQ(S_OK, hr); | 537 EXPECT_EQ(S_OK, hr); |
374 ULONG ignore; | 538 ULONG ignore; |
375 | 539 |
376 // Check out the first selected item. | 540 // Check out the first selected item. |
377 { | 541 { |
378 ScopedVariant item; | 542 ScopedVariant item; |
379 hr = accessibles->Next(1, item.Receive(), &ignore); | 543 hr = accessibles->Next(1, item.Receive(), &ignore); |
380 EXPECT_EQ(S_OK, hr); | 544 EXPECT_EQ(S_OK, hr); |
381 | 545 |
382 base::win::ScopedComPtr<IAccessible> accessible; | 546 ScopedComPtr<IAccessible> accessible; |
383 HRESULT hr = | 547 HRESULT hr = |
384 V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); | 548 V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); |
385 EXPECT_EQ(S_OK, hr); | 549 EXPECT_EQ(S_OK, hr); |
386 ScopedBstr name; | 550 ScopedBstr name; |
387 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); | 551 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); |
388 EXPECT_STREQ(L"Name2", name); | 552 EXPECT_STREQ(L"Name2", name); |
389 } | 553 } |
390 | 554 |
391 // and the second selected element. | 555 // and the second selected element. |
392 { | 556 { |
393 ScopedVariant item; | 557 ScopedVariant item; |
394 hr = accessibles->Next(1, item.Receive(), &ignore); | 558 hr = accessibles->Next(1, item.Receive(), &ignore); |
395 EXPECT_EQ(S_OK, hr); | 559 EXPECT_EQ(S_OK, hr); |
396 | 560 |
397 base::win::ScopedComPtr<IAccessible> accessible; | 561 ScopedComPtr<IAccessible> accessible; |
398 HRESULT hr = | 562 HRESULT hr = |
399 V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); | 563 V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)); |
400 EXPECT_EQ(S_OK, hr); | 564 EXPECT_EQ(S_OK, hr); |
401 ScopedBstr name; | 565 ScopedBstr name; |
402 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); | 566 EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive())); |
403 EXPECT_STREQ(L"Name3", name); | 567 EXPECT_STREQ(L"Name3", name); |
404 } | 568 } |
405 | 569 |
406 // There shouldn't be any more selected. | 570 // There shouldn't be any more selected. |
407 { | 571 { |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 0, 1)); | 894 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 0, 1)); |
731 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 1, 0)); | 895 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 1, 0)); |
732 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 2, 2)); | 896 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 2, 2)); |
733 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, IA2_TEXT_OFFSET_CARET, | 897 EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, IA2_TEXT_OFFSET_CARET, |
734 IA2_TEXT_OFFSET_LENGTH)); | 898 IA2_TEXT_OFFSET_LENGTH)); |
735 | 899 |
736 EXPECT_HRESULT_FAILED(text_field->setSelection(1, 0, 0)); | 900 EXPECT_HRESULT_FAILED(text_field->setSelection(1, 0, 0)); |
737 EXPECT_HRESULT_FAILED(text_field->setSelection(0, 0, 5)); | 901 EXPECT_HRESULT_FAILED(text_field->setSelection(0, 0, 5)); |
738 } | 902 } |
739 | 903 |
904 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetAccessibilityAt) { | |
905 Build4X4Table(); | |
906 | |
907 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
908 | |
909 ScopedComPtr<IAccessibleTable> result; | |
910 root_obj.CopyTo(result.GetAddressOf()); | |
911 ASSERT_NE(nullptr, result); | |
912 | |
913 ScopedComPtr<IUnknown> cell_1; | |
914 EXPECT_EQ(S_OK, result->get_accessibleAt(1, 1, cell_1.GetAddressOf())); | |
915 CheckIUnknownHasName(cell_1, L"1"); | |
916 | |
917 ScopedComPtr<IUnknown> cell_2; | |
918 EXPECT_EQ(S_OK, result->get_accessibleAt(1, 2, cell_2.GetAddressOf())); | |
919 CheckIUnknownHasName(cell_2, L"2"); | |
920 | |
921 ScopedComPtr<IUnknown> cell_3; | |
922 EXPECT_EQ(S_OK, result->get_accessibleAt(2, 1, cell_3.GetAddressOf())); | |
923 CheckIUnknownHasName(cell_3, L"3"); | |
924 | |
925 ScopedComPtr<IUnknown> cell_4; | |
926 EXPECT_EQ(S_OK, result->get_accessibleAt(2, 2, cell_4.GetAddressOf())); | |
927 CheckIUnknownHasName(cell_4, L"4"); | |
928 } | |
929 | |
930 TEST_F(AXPlatformNodeWinTest, | |
931 TestIAccessibleTableGetAccessibilityAtOutOfBounds) { | |
932 Build4X4Table(); | |
933 | |
934 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
935 | |
936 ScopedComPtr<IAccessibleTable> result; | |
937 root_obj.CopyTo(result.GetAddressOf()); | |
938 ASSERT_NE(nullptr, result); | |
939 | |
940 { | |
941 ScopedComPtr<IUnknown> cell; | |
942 EXPECT_EQ(E_INVALIDARG, | |
943 result->get_accessibleAt(-1, -1, cell.GetAddressOf())); | |
944 } | |
945 | |
946 { | |
947 ScopedComPtr<IUnknown> cell; | |
948 EXPECT_EQ(E_INVALIDARG, | |
949 result->get_accessibleAt(0, 5, cell.GetAddressOf())); | |
950 } | |
951 | |
952 { | |
953 ScopedComPtr<IUnknown> cell; | |
954 EXPECT_EQ(E_INVALIDARG, | |
955 result->get_accessibleAt(5, 0, cell.GetAddressOf())); | |
956 } | |
957 | |
958 { | |
959 ScopedComPtr<IUnknown> cell; | |
960 EXPECT_EQ(E_INVALIDARG, | |
961 result->get_accessibleAt(10, 10, cell.GetAddressOf())); | |
962 } | |
963 } | |
964 | |
965 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetChildIndex) { | |
966 Build4X4Table(); | |
967 | |
968 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
969 | |
970 ScopedComPtr<IAccessibleTable> result; | |
971 root_obj.CopyTo(result.GetAddressOf()); | |
972 ASSERT_NE(nullptr, result); | |
973 | |
974 long id; | |
975 EXPECT_EQ(S_OK, result->get_childIndex(0, 0, &id)); | |
976 EXPECT_EQ(id, 0); | |
977 | |
978 EXPECT_EQ(S_OK, result->get_childIndex(0, 1, &id)); | |
979 EXPECT_EQ(id, 1); | |
980 | |
981 EXPECT_EQ(S_OK, result->get_childIndex(1, 0, &id)); | |
982 EXPECT_EQ(id, 3); | |
983 | |
984 EXPECT_EQ(S_OK, result->get_childIndex(1, 1, &id)); | |
985 EXPECT_EQ(id, 4); | |
986 | |
987 EXPECT_EQ(E_INVALIDARG, result->get_childIndex(-1, -1, &id)); | |
988 EXPECT_EQ(E_INVALIDARG, result->get_childIndex(0, 5, &id)); | |
989 EXPECT_EQ(E_INVALIDARG, result->get_childIndex(5, 0, &id)); | |
990 EXPECT_EQ(E_INVALIDARG, result->get_childIndex(5, 5, &id)); | |
991 } | |
992 | |
993 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnDescription) { | |
994 Build4X4Table(); | |
995 | |
996 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
997 | |
998 ScopedComPtr<IAccessibleTable> result; | |
999 root_obj.CopyTo(result.GetAddressOf()); | |
1000 ASSERT_NE(nullptr, result); | |
1001 | |
1002 { | |
1003 ScopedBstr name; | |
1004 EXPECT_EQ(S_FALSE, result->get_columnDescription(0, name.Receive())); | |
1005 } | |
1006 { | |
1007 ScopedBstr name; | |
1008 EXPECT_EQ(S_OK, result->get_columnDescription(1, name.Receive())); | |
1009 EXPECT_STREQ(L"column header 1", name); | |
1010 } | |
1011 | |
1012 { | |
1013 ScopedBstr name; | |
1014 EXPECT_EQ(S_OK, result->get_columnDescription(2, name.Receive())); | |
1015 EXPECT_STREQ(L"column header 2", name); | |
1016 } | |
1017 } | |
1018 | |
1019 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnExtentAt) { | |
1020 // TODO(dougt) This table doesn't have any spanning cells. This test | |
1021 // tests get_columnExtentAt for (1) and an invalid input. | |
1022 Build4X4Table(); | |
1023 | |
1024 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1025 | |
1026 ScopedComPtr<IAccessibleTable> result; | |
1027 root_obj.CopyTo(result.GetAddressOf()); | |
1028 ASSERT_NE(nullptr, result); | |
1029 | |
1030 long columns_spanned; | |
1031 EXPECT_EQ(S_OK, result->get_columnExtentAt(1, 1, &columns_spanned)); | |
1032 EXPECT_EQ(columns_spanned, 1); | |
1033 | |
1034 EXPECT_EQ(E_INVALIDARG, result->get_columnExtentAt(-1, -1, &columns_spanned)); | |
1035 } | |
1036 | |
1037 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnIndex) { | |
1038 Build4X4Table(); | |
1039 | |
1040 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1041 | |
1042 ScopedComPtr<IAccessibleTable> result; | |
1043 root_obj.CopyTo(result.GetAddressOf()); | |
1044 ASSERT_NE(nullptr, result); | |
1045 | |
1046 long index; | |
1047 EXPECT_EQ(S_OK, result->get_columnIndex(1, &index)); | |
1048 EXPECT_EQ(index, 0); | |
1049 | |
1050 EXPECT_EQ(E_INVALIDARG, result->get_columnIndex(-1, &index)); | |
1051 } | |
1052 | |
1053 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNColumns) { | |
1054 Build4X4Table(); | |
1055 | |
1056 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1057 | |
1058 ScopedComPtr<IAccessibleTable> result; | |
1059 root_obj.CopyTo(result.GetAddressOf()); | |
1060 ASSERT_NE(nullptr, result); | |
1061 | |
1062 long count; | |
1063 EXPECT_EQ(S_OK, result->get_nColumns(&count)); | |
1064 EXPECT_EQ(count, 3); | |
1065 } | |
1066 | |
1067 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNRows) { | |
1068 Build4X4Table(); | |
1069 | |
1070 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1071 | |
1072 ScopedComPtr<IAccessibleTable> result; | |
1073 root_obj.CopyTo(result.GetAddressOf()); | |
1074 ASSERT_NE(nullptr, result); | |
1075 | |
1076 long count; | |
1077 EXPECT_EQ(S_OK, result->get_nRows(&count)); | |
1078 EXPECT_EQ(count, 3); | |
1079 } | |
1080 | |
1081 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowDescription) { | |
1082 Build4X4Table(); | |
1083 | |
1084 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1085 | |
1086 ScopedComPtr<IAccessibleTable> result; | |
1087 root_obj.CopyTo(result.GetAddressOf()); | |
1088 ASSERT_NE(nullptr, result); | |
1089 | |
1090 { | |
1091 ScopedBstr name; | |
1092 EXPECT_EQ(S_FALSE, result->get_rowDescription(0, name.Receive())); | |
1093 } | |
1094 { | |
1095 ScopedBstr name; | |
1096 EXPECT_EQ(S_OK, result->get_rowDescription(1, name.Receive())); | |
1097 EXPECT_STREQ(L"row header 1", name); | |
1098 } | |
1099 | |
1100 { | |
1101 ScopedBstr name; | |
1102 EXPECT_EQ(S_OK, result->get_rowDescription(2, name.Receive())); | |
1103 EXPECT_STREQ(L"row header 2", name); | |
1104 } | |
1105 } | |
1106 | |
1107 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowExtentAt) { | |
1108 // TODO(dougt) This table doesn't have any spanning cells. This test | |
1109 // tests get_rowExtentAt for (1) and an invalid input. | |
1110 Build4X4Table(); | |
1111 | |
1112 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1113 | |
1114 ScopedComPtr<IAccessibleTable> result; | |
1115 root_obj.CopyTo(result.GetAddressOf()); | |
1116 ASSERT_NE(nullptr, result); | |
1117 | |
1118 long rows_spanned; | |
1119 EXPECT_EQ(S_OK, result->get_rowExtentAt(0, 1, &rows_spanned)); | |
1120 EXPECT_EQ(rows_spanned, 0); | |
1121 | |
1122 EXPECT_EQ(E_INVALIDARG, result->get_columnExtentAt(-1, -1, &rows_spanned)); | |
1123 } | |
1124 | |
1125 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowIndex) { | |
1126 Build4X4Table(); | |
1127 | |
1128 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1129 | |
1130 ScopedComPtr<IAccessibleTable> result; | |
1131 root_obj.CopyTo(result.GetAddressOf()); | |
1132 ASSERT_NE(nullptr, result); | |
1133 | |
1134 long index; | |
1135 EXPECT_EQ(S_OK, result->get_rowIndex(1, &index)); | |
1136 EXPECT_EQ(index, 0); | |
1137 | |
1138 EXPECT_EQ(E_INVALIDARG, result->get_rowIndex(-1, &index)); | |
1139 } | |
1140 | |
1141 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowColumnExtentsAtIndex) { | |
1142 Build4X4Table(); | |
1143 | |
1144 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1145 | |
1146 ScopedComPtr<IAccessibleTable> result; | |
1147 root_obj.CopyTo(result.GetAddressOf()); | |
1148 ASSERT_NE(nullptr, result); | |
1149 | |
1150 long row, column, row_extents, column_extents; | |
1151 boolean is_selected; | |
1152 EXPECT_EQ(S_OK, | |
1153 result->get_rowColumnExtentsAtIndex(0, &row, &column, &row_extents, | |
1154 &column_extents, &is_selected)); | |
1155 | |
1156 EXPECT_EQ(row, 0); | |
1157 EXPECT_EQ(column, 0); | |
1158 EXPECT_EQ(row_extents, 0); | |
1159 EXPECT_EQ(column_extents, 0); | |
1160 | |
1161 EXPECT_EQ(E_INVALIDARG, | |
1162 result->get_rowColumnExtentsAtIndex(-1, &row, &column, &row_extents, | |
1163 &column_extents, &is_selected)); | |
1164 } | |
1165 | |
1166 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetCellAt) { | |
1167 Build4X4Table(); | |
1168 | |
1169 ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); | |
1170 | |
1171 ScopedComPtr<IAccessibleTable2> result; | |
1172 root_obj.CopyTo(result.GetAddressOf()); | |
1173 ASSERT_NE(nullptr, result); | |
1174 | |
1175 { | |
1176 ScopedComPtr<IUnknown> cell; | |
1177 EXPECT_EQ(S_OK, result->get_cellAt(1, 1, cell.GetAddressOf())); | |
1178 CheckIUnknownHasName(cell, L"1"); | |
1179 } | |
1180 | |
1181 { | |
1182 ScopedComPtr<IUnknown> cell; | |
1183 EXPECT_EQ(E_INVALIDARG, result->get_cellAt(-1, -1, cell.GetAddressOf())); | |
1184 } | |
1185 } | |
1186 | |
1187 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnExtent) { | |
1188 Build4X4Table(); | |
1189 | |
1190 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1191 ASSERT_NE(nullptr, cell); | |
1192 | |
1193 long column_spanned; | |
1194 EXPECT_EQ(S_OK, cell->get_columnExtent(&column_spanned)); | |
1195 EXPECT_EQ(column_spanned, 1); | |
1196 } | |
1197 | |
1198 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnHeaderCells) { | |
1199 Build4X4Table(); | |
1200 | |
1201 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1202 ASSERT_NE(nullptr, cell); | |
1203 | |
1204 IUnknown** cell_accessibles; | |
1205 | |
1206 long number_cells; | |
1207 EXPECT_EQ(S_OK, | |
1208 cell->get_columnHeaderCells(&cell_accessibles, &number_cells)); | |
1209 EXPECT_EQ(number_cells, 1); | |
1210 } | |
1211 | |
1212 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnIndex) { | |
1213 Build4X4Table(); | |
1214 | |
1215 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1216 ASSERT_NE(nullptr, cell); | |
1217 | |
1218 long index; | |
1219 EXPECT_EQ(S_OK, cell->get_columnIndex(&index)); | |
1220 EXPECT_EQ(index, 0); | |
1221 } | |
1222 | |
1223 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowExtent) { | |
1224 Build4X4Table(); | |
1225 | |
1226 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1227 ASSERT_NE(nullptr, cell); | |
1228 | |
1229 long rows_spanned; | |
1230 EXPECT_EQ(S_OK, cell->get_rowExtent(&rows_spanned)); | |
1231 EXPECT_EQ(rows_spanned, 1); | |
1232 } | |
1233 | |
1234 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowHeaderCells) { | |
1235 Build4X4Table(); | |
1236 | |
1237 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1238 ASSERT_NE(nullptr, cell); | |
1239 | |
1240 IUnknown** cell_accessibles; | |
1241 | |
1242 long number_cells; | |
1243 EXPECT_EQ(S_OK, cell->get_rowHeaderCells(&cell_accessibles, &number_cells)); | |
1244 | |
1245 // Since we do not have AX_ATTR_TABLE_CELL_ROW_INDEX set, the evaluated row | |
1246 // will be 0. In this case, we do not expect any row headers. | |
1247 EXPECT_EQ(number_cells, 0); | |
1248 } | |
1249 | |
1250 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowIndex) { | |
1251 Build4X4Table(); | |
1252 | |
1253 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1254 ASSERT_NE(nullptr, cell); | |
1255 | |
1256 long index; | |
1257 EXPECT_EQ(S_OK, cell->get_rowIndex(&index)); | |
1258 EXPECT_EQ(index, 0); | |
1259 } | |
1260 | |
1261 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowColumnExtent) { | |
1262 Build4X4Table(); | |
1263 | |
1264 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1265 ASSERT_NE(nullptr, cell); | |
1266 | |
1267 long row, column, row_extents, column_extents; | |
1268 boolean is_selected; | |
1269 EXPECT_EQ(S_OK, cell->get_rowColumnExtents(&row, &column, &row_extents, | |
1270 &column_extents, &is_selected)); | |
1271 EXPECT_EQ(row, 0); | |
1272 EXPECT_EQ(column, 0); | |
1273 EXPECT_EQ(row_extents, 1); | |
1274 EXPECT_EQ(column_extents, 1); | |
1275 } | |
1276 | |
1277 TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetTable) { | |
1278 Build4X4Table(); | |
1279 | |
1280 ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); | |
1281 ASSERT_NE(nullptr, cell); | |
1282 | |
1283 ScopedComPtr<IUnknown> table; | |
1284 EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); | |
1285 | |
1286 ScopedComPtr<IAccessibleTable> result; | |
1287 table.CopyTo(result.GetAddressOf()); | |
1288 ASSERT_NE(nullptr, result); | |
1289 | |
1290 // Check to make sure that this is the right table by checking one cell. | |
1291 ScopedComPtr<IUnknown> cell_1; | |
1292 EXPECT_EQ(S_OK, result->get_accessibleAt(1, 1, cell_1.GetAddressOf())); | |
1293 CheckIUnknownHasName(cell_1, L"1"); | |
1294 } | |
1295 | |
740 } // namespace ui | 1296 } // namespace ui |
OLD | NEW |