Chromium Code Reviews| 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 |