Index: ui/accessibility/platform/ax_platform_node_win_unittest.cc |
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1e4e2858c7d2fbc6ddf189a1b790d99acd64740c |
--- /dev/null |
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc |
@@ -0,0 +1,273 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <atlbase.h> |
+#include <atlcom.h> |
+#include <oleacc.h> |
+ |
+#include "base/memory/scoped_ptr.h" |
+#include "base/win/scoped_bstr.h" |
+#include "base/win/scoped_comptr.h" |
+#include "base/win/scoped_variant.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/iaccessible2/ia2_api_all.h" |
+#include "ui/accessibility/ax_node_data.h" |
+#include "ui/accessibility/platform/ax_platform_node.h" |
+#include "ui/accessibility/platform/test_ax_node_wrapper.h" |
+#include "ui/base/win/atl_module.h" |
+ |
+namespace ui { |
+ |
+namespace { |
+ |
+// Most IAccessible functions require a VARIANT set to CHILDID_SELF as |
+// the first argument. |
+base::win::ScopedVariant SELF(CHILDID_SELF); |
+ |
+} // namespace |
+ |
+class AXPlatformNodeWinTest : public testing::Test { |
+ public: |
+ AXPlatformNodeWinTest() {} |
+ virtual ~AXPlatformNodeWinTest() {} |
+ |
+ void SetUp() override { |
+ win::CreateATLModuleIfNeeded(); |
+ } |
+ |
+ // Initialize given an AXTreeUpdate. |
+ void Init(const AXTreeUpdate& initial_state) { |
+ tree_.reset(new AXTree(initial_state)); |
+ } |
+ |
+ // Convenience functions to initialize directly from a few AXNodeDatas. |
+ void Init(const AXNodeData& node1) { |
+ AXTreeUpdate update; |
+ update.nodes.push_back(node1); |
+ Init(update); |
+ } |
+ |
+ void Init(const AXNodeData& node1, |
+ const AXNodeData& node2) { |
+ AXTreeUpdate update; |
+ update.nodes.push_back(node1); |
+ update.nodes.push_back(node2); |
+ Init(update); |
+ } |
+ |
+ void Init(const AXNodeData& node1, |
+ const AXNodeData& node2, |
+ const AXNodeData& node3) { |
+ AXTreeUpdate update; |
+ update.nodes.push_back(node1); |
+ update.nodes.push_back(node2); |
+ update.nodes.push_back(node3); |
+ Init(update); |
+ } |
+ |
+ protected: |
+ AXNode* RootNode() { |
David Tseng
2015/02/14 00:09:01
nit: GetRootNode
dmazzoni
2015/02/17 22:48:05
Done.
|
+ return tree_->GetRoot(); |
+ } |
+ |
+ IAccessible* IAccessibleFromNode(AXNode* node) { |
+ TestAXNodeWrapper* wrapper = |
+ TestAXNodeWrapper::GetOrCreate(tree_.get(), node); |
+ AXPlatformNode* ax_platform_node = wrapper->ax_platform_node(); |
+ return ax_platform_node->GetNativeViewAccessible(); |
+ } |
+ |
+ IAccessible* RootIAccessible() { |
+ return IAccessibleFromNode(RootNode()); |
+ } |
+ |
+ base::win::ScopedComPtr<IAccessible2> ToIAccessible2( |
+ IAccessible* accessible) { |
+ base::win::ScopedComPtr<IServiceProvider> service_provider; |
+ CHECK(SUCCEEDED(accessible->QueryInterface(service_provider.Receive()))); |
+ base::win::ScopedComPtr<IAccessible2> result; |
+ CHECK(SUCCEEDED( |
+ service_provider->QueryService(IID_IAccessible2, result.Receive()))); |
+ return result; |
+ } |
+ |
+ scoped_ptr<AXTree> tree_; |
+}; |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleName) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.AddStringAttribute(AX_ATTR_NAME, "Name"); |
+ Init(root); |
+ |
+ base::win::ScopedBstr name; |
+ ASSERT_EQ(S_OK, RootIAccessible()->get_accName(SELF, name.Receive())); |
+ EXPECT_EQ(L"Name", base::string16(name)); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleDescription) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.AddStringAttribute(AX_ATTR_DESCRIPTION, "Description"); |
+ Init(root); |
+ |
+ base::win::ScopedBstr description; |
+ ASSERT_EQ(S_OK, RootIAccessible()->get_accDescription( |
+ SELF, description.Receive())); |
+ EXPECT_EQ(L"Description", base::string16(description)); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleHelp) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.AddStringAttribute(AX_ATTR_HELP, "Help"); |
+ Init(root); |
+ |
+ base::win::ScopedBstr help; |
+ ASSERT_EQ(S_OK, RootIAccessible()->get_accHelp(SELF, help.Receive())); |
+ EXPECT_EQ(L"Help", base::string16(help)); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleValue) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.AddStringAttribute(AX_ATTR_VALUE, "Value"); |
+ Init(root); |
+ |
+ base::win::ScopedBstr value; |
+ ASSERT_EQ(S_OK, RootIAccessible()->get_accValue(SELF, value.Receive())); |
+ EXPECT_EQ(L"Value", base::string16(value)); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleShortcut) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.AddStringAttribute(AX_ATTR_SHORTCUT, "Shortcut"); |
+ Init(root); |
+ |
+ base::win::ScopedBstr shortcut; |
+ ASSERT_EQ(S_OK, RootIAccessible()->get_accKeyboardShortcut( |
+ SELF, shortcut.Receive())); |
+ EXPECT_EQ(L"Shortcut", base::string16(shortcut)); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleRole) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.child_ids.push_back(2); |
+ |
+ AXNodeData child; |
+ child.id = 2; |
+ |
+ Init(root, child); |
+ AXNode* child_node = RootNode()->children()[0]; |
+ IAccessible* child_iaccessible = IAccessibleFromNode(child_node); |
+ |
+ base::win::ScopedVariant role; |
+ |
+ child.role = AX_ROLE_ALERT; |
+ child_node->SetData(child); |
+ ASSERT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive())); |
+ EXPECT_EQ(ROLE_SYSTEM_ALERT, V_I4(&role)); |
+ |
+ child.role = AX_ROLE_BUTTON; |
+ child_node->SetData(child); |
+ ASSERT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive())); |
+ EXPECT_EQ(ROLE_SYSTEM_PUSHBUTTON, V_I4(&role)); |
+ |
+ child.role = AX_ROLE_POP_UP_BUTTON; |
+ child_node->SetData(child); |
+ ASSERT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive())); |
+ EXPECT_EQ(ROLE_SYSTEM_BUTTONMENU, V_I4(&role)); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleLocation) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.location = gfx::Rect(10, 40, 800, 600); |
+ Init(root); |
+ |
+ TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(100, 200)); |
+ |
+ LONG x_left, y_top, width, height; |
+ ASSERT_EQ(S_OK, RootIAccessible()->accLocation( |
+ &x_left, &y_top, &width, &height, SELF)); |
+ EXPECT_EQ(110, x_left); |
+ EXPECT_EQ(240, y_top); |
+ EXPECT_EQ(800, width); |
+ EXPECT_EQ(600, height); |
+} |
+ |
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { |
+ AXNodeData root; |
+ root.id = 1; |
+ root.role = AX_ROLE_ROOT_WEB_AREA; |
+ root.child_ids.push_back(2); |
+ root.child_ids.push_back(3); |
+ |
+ AXNodeData button; |
+ button.role = AX_ROLE_BUTTON; |
+ button.id = 2; |
+ |
+ AXNodeData checkbox; |
+ checkbox.role = AX_ROLE_CHECK_BOX; |
+ checkbox.id = 3; |
+ |
+ Init(root, button, checkbox); |
+ AXNode* button_node = RootNode()->children()[0]; |
+ AXNode* checkbox_node = RootNode()->children()[1]; |
+ IAccessible* root_iaccessible = RootIAccessible(); |
+ IAccessible* button_iaccessible = IAccessibleFromNode(button_node); |
+ IAccessible* checkbox_iaccessible = IAccessibleFromNode(checkbox_node); |
+ |
+ LONG child_count; |
+ ASSERT_EQ(S_OK, root_iaccessible->get_accChildCount(&child_count)); |
+ ASSERT_EQ(2L, child_count); |
+ ASSERT_EQ(S_OK, button_iaccessible->get_accChildCount(&child_count)); |
+ ASSERT_EQ(0L, child_count); |
+ ASSERT_EQ(S_OK, checkbox_iaccessible->get_accChildCount(&child_count)); |
+ ASSERT_EQ(0L, child_count); |
+ |
+ base::win::ScopedComPtr<IDispatch> result; |
+ ASSERT_EQ(S_OK, root_iaccessible->get_accChild(SELF, result.Receive())); |
+ ASSERT_EQ(result.get(), root_iaccessible); |
+ |
+ base::win::ScopedVariant child1(1); |
+ ASSERT_EQ(S_OK, root_iaccessible->get_accChild(child1, result.Receive())); |
+ ASSERT_EQ(result.get(), button_iaccessible); |
+ base::win::ScopedVariant child2(2); |
+ ASSERT_EQ(S_OK, root_iaccessible->get_accChild(child2, result.Receive())); |
+ ASSERT_EQ(result.get(), checkbox_iaccessible); |
+ base::win::ScopedVariant child3(3); |
+ |
+ // Asking for child id 3 should fail. |
+ ASSERT_EQ(E_FAIL, root_iaccessible->get_accChild(child3, result.Receive())); |
+ |
+ // We should be able to ask for the button by its unique id too. |
+ LONG button_unique_id; |
+ base::win::ScopedComPtr<IAccessible2> button_iaccessible2 = |
+ ToIAccessible2(button_iaccessible); |
+ button_iaccessible2->get_uniqueID(&button_unique_id); |
+ ASSERT_LT(button_unique_id, 0); |
+ base::win::ScopedVariant button_id_variant(button_unique_id); |
+ ASSERT_EQ(S_OK, root_iaccessible->get_accChild(button_id_variant, |
+ result.Receive())); |
+ ASSERT_EQ(result.get(), button_iaccessible); |
+ |
+ // Now check parents. |
+ ASSERT_EQ(S_OK, button_iaccessible->get_accParent(result.Receive())); |
+ ASSERT_EQ(result.get(), root_iaccessible); |
+ ASSERT_EQ(S_OK, checkbox_iaccessible->get_accParent(result.Receive())); |
+ ASSERT_EQ(result.get(), root_iaccessible); |
+ ASSERT_EQ(S_FALSE, root_iaccessible->get_accParent(result.Receive())); |
+} |
+ |
+} // namespace ui |