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 Build3X3Table() { |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 Build3X3Table(); |
| 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 |