blob: 8ef85983904f75a83b0ad6a2f5d857c0217ab6cc [file] [log] [blame]
Sharon Yang28eac792019-10-16 00:28:231// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "fuchsia/engine/browser/ax_tree_converter.h"
6
7#include <lib/ui/scenic/cpp/commands.h>
8#include <vector>
9
10#include "testing/gtest/include/gtest/gtest.h"
11#include "ui/gfx/transform.h"
12
13using fuchsia::accessibility::semantics::Action;
14using fuchsia::accessibility::semantics::Attributes;
Sharon Yang6f3a47b2020-01-08 21:32:2915using fuchsia::accessibility::semantics::CheckedState;
Sharon Yang28eac792019-10-16 00:28:2316using fuchsia::accessibility::semantics::Node;
17using fuchsia::accessibility::semantics::Role;
Sharon Yang6f3a47b2020-01-08 21:32:2918using fuchsia::accessibility::semantics::States;
Sharon Yang28eac792019-10-16 00:28:2319
20namespace {
21
22const char kLabel1[] = "label nodes, not people";
23const char kLabel2[] = "fancy stickers";
Sharon Yang6f3a47b2020-01-08 21:32:2924const char kDescription1[] = "this node does some stuff";
25const char kValue1[] = "user entered value";
Sharon Yang28eac792019-10-16 00:28:2326const int32_t kChildId1 = 23901;
27const int32_t kChildId2 = 484345;
28const int32_t kChildId3 = 4156877;
29const int32_t kRectX = 1;
30const int32_t kRectY = 2;
31const int32_t kRectWidth = 7;
32const int32_t kRectHeight = 8;
Yilong Li4ada6192020-01-06 21:01:1933const std::array<float, 16> k4DIdentityMatrix = {1, 0, 0, 0, 0, 1, 0, 0,
34 0, 0, 1, 0, 0, 0, 0, 1};
Sharon Yang28eac792019-10-16 00:28:2335
Sharon Yang28eac792019-10-16 00:28:2336ui::AXNodeData CreateAXNodeData(ax::mojom::Role role,
Sharon Yang6f3a47b2020-01-08 21:32:2937 ax::mojom::Action action,
Sharon Yang28eac792019-10-16 00:28:2338 std::vector<int32_t> child_ids,
39 ui::AXRelativeBounds relative_bounds,
Sharon Yang6f3a47b2020-01-08 21:32:2940 base::StringPiece name,
41 base::StringPiece description,
42 ax::mojom::CheckedState checked_state) {
Sharon Yang28eac792019-10-16 00:28:2343 ui::AXNodeData node;
44 node.role = role;
Sharon Yang6f3a47b2020-01-08 21:32:2945 node.AddAction(action);
46 node.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
47 static_cast<int32_t>(checked_state));
Sharon Yang28eac792019-10-16 00:28:2348 node.child_ids = child_ids;
49 node.relative_bounds = relative_bounds;
50 if (!name.empty())
51 node.AddStringAttribute(ax::mojom::StringAttribute::kName, name.data());
Sharon Yang6f3a47b2020-01-08 21:32:2952 if (!description.empty()) {
53 node.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
54 description.data());
55 }
Sharon Yang28eac792019-10-16 00:28:2356 return node;
57}
58
59Node CreateSemanticNode(uint32_t id,
60 Role role,
61 Attributes attributes,
Sharon Yang6f3a47b2020-01-08 21:32:2962 States states,
Sharon Yang28eac792019-10-16 00:28:2363 std::vector<Action> actions,
64 std::vector<uint32_t> child_ids,
65 fuchsia::ui::gfx::BoundingBox location,
66 fuchsia::ui::gfx::mat4 transform) {
67 Node node;
68 node.set_node_id(id);
69 node.set_role(role);
70 node.set_attributes(std::move(attributes));
Sharon Yang6f3a47b2020-01-08 21:32:2971 node.set_states(std::move(states));
Sharon Yang28eac792019-10-16 00:28:2372 node.set_actions(actions);
73 node.set_child_ids(child_ids);
74 node.set_location(location);
75 node.set_transform(transform);
76 return node;
77}
78
79class AXTreeConverterTest : public testing::Test {
80 public:
81 AXTreeConverterTest() = default;
82 ~AXTreeConverterTest() override = default;
83
84 DISALLOW_COPY_AND_ASSIGN(AXTreeConverterTest);
85};
86
87TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) {
88 ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds();
89 relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight);
90 relative_bounds.transform =
91 std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization);
92 relative_bounds.transform->MakeIdentity();
Sharon Yang6f3a47b2020-01-08 21:32:2993 auto source_node_data = CreateAXNodeData(
94 ax::mojom::Role::kButton, ax::mojom::Action::kFocus,
95 std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds,
96 kLabel1, kDescription1, ax::mojom::CheckedState::kMixed);
97 source_node_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
Lucas Radaelli6afb9022020-10-09 19:32:0098 source_node_data.RemoveState(ax::mojom::State::kIgnored);
Sharon Yang28eac792019-10-16 00:28:2399 auto converted_node = AXNodeDataToSemanticNode(source_node_data);
100 EXPECT_EQ(static_cast<uint32_t>(source_node_data.id),
101 converted_node.node_id());
102
103 Attributes attributes;
104 attributes.set_label(kLabel1);
Sharon Yang6f3a47b2020-01-08 21:32:29105 attributes.set_secondary_label(kDescription1);
Sharon Yang28eac792019-10-16 00:28:23106 fuchsia::ui::gfx::BoundingBox box;
Yilong Li4ada6192020-01-06 21:01:19107 box.min = scenic::NewVector3({kRectX, kRectY + kRectHeight, 0.0f});
108 box.max = scenic::NewVector3({kRectHeight, kRectY, 0.0f});
Sharon Yang28eac792019-10-16 00:28:23109 fuchsia::ui::gfx::Matrix4Value mat =
110 scenic::NewMatrix4Value(k4DIdentityMatrix);
Sharon Yang6f3a47b2020-01-08 21:32:29111 States states;
112 states.set_checked_state(CheckedState::MIXED);
113 states.set_hidden(false);
114 states.set_selected(false);
Sharon Yang28eac792019-10-16 00:28:23115 auto expected_node = CreateSemanticNode(
Findit066982f12020-09-30 05:18:34116 source_node_data.id, Role::BUTTON, std::move(attributes),
117 std::move(states), std::vector<Action>{Action::SET_FOCUS},
Sharon Yang28eac792019-10-16 00:28:23118 std::vector<uint32_t>{kChildId1, kChildId2, kChildId3}, box, mat.value);
119
Sharon Yang6f3a47b2020-01-08 21:32:29120 EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
Sharon Yang28eac792019-10-16 00:28:23121}
122
123TEST_F(AXTreeConverterTest, SomeFieldsSetAndEqual) {
124 ui::AXNodeData source_node_data;
Sharon Yang6f3a47b2020-01-08 21:32:29125 source_node_data.AddAction(ax::mojom::Action::kFocus);
126 source_node_data.AddAction(ax::mojom::Action::kSetValue);
Sharon Yang28eac792019-10-16 00:28:23127 source_node_data.child_ids = std::vector<int32_t>{kChildId1};
Sharon Yang6f3a47b2020-01-08 21:32:29128 source_node_data.role = ax::mojom::Role::kImage;
129 source_node_data.AddStringAttribute(ax::mojom::StringAttribute::kValue,
130 kValue1);
Sharon Yang28eac792019-10-16 00:28:23131 auto converted_node = AXNodeDataToSemanticNode(source_node_data);
132 EXPECT_EQ(static_cast<uint32_t>(source_node_data.id),
133 converted_node.node_id());
134
135 Node expected_node;
Findit066982f12020-09-30 05:18:34136 expected_node.set_node_id(source_node_data.id);
Sharon Yang6f3a47b2020-01-08 21:32:29137 expected_node.set_actions(
138 std::vector<Action>{Action::SET_FOCUS, Action::SET_VALUE});
Findit066982f12020-09-30 05:18:34139 expected_node.set_child_ids(std::vector<uint32_t>{kChildId1});
Sharon Yang6f3a47b2020-01-08 21:32:29140 expected_node.set_role(Role::IMAGE);
141 States states;
142 states.set_hidden(false);
143 states.set_value(kValue1);
144 expected_node.set_states(std::move(states));
145 Attributes attributes;
146 expected_node.set_attributes(std::move(attributes));
147 fuchsia::ui::gfx::BoundingBox box;
148 expected_node.set_location(std::move(box));
Sharon Yang28eac792019-10-16 00:28:23149
Sharon Yang6f3a47b2020-01-08 21:32:29150 EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
Sharon Yang28eac792019-10-16 00:28:23151}
152
153TEST_F(AXTreeConverterTest, FieldMismatch) {
154 ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds();
155 relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight);
156 relative_bounds.transform =
157 std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization);
158 relative_bounds.transform->MakeIdentity();
Sharon Yang6f3a47b2020-01-08 21:32:29159 auto source_node_data = CreateAXNodeData(
160 ax::mojom::Role::kHeader, ax::mojom::Action::kSetValue,
161 std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds,
162 kLabel1, kDescription1, ax::mojom::CheckedState::kFalse);
Sharon Yang28eac792019-10-16 00:28:23163 auto converted_node = AXNodeDataToSemanticNode(source_node_data);
164 EXPECT_EQ(static_cast<uint32_t>(source_node_data.id),
165 converted_node.node_id());
166
167 Attributes attributes;
168 attributes.set_label(kLabel1);
Sharon Yang6f3a47b2020-01-08 21:32:29169 attributes.set_secondary_label(kDescription1);
170 States states;
171 states.set_hidden(false);
172 states.set_checked_state(CheckedState::UNCHECKED);
Sharon Yang28eac792019-10-16 00:28:23173 fuchsia::ui::gfx::BoundingBox box;
Sharon Yang6f3a47b2020-01-08 21:32:29174 box.min = scenic::NewVector3({kRectX, kRectY + kRectHeight, 0.0f});
175 box.max = scenic::NewVector3({kRectHeight, kRectY, 0.0f});
Sharon Yang28eac792019-10-16 00:28:23176 fuchsia::ui::gfx::Matrix4Value mat =
177 scenic::NewMatrix4Value(k4DIdentityMatrix);
178 auto expected_node = CreateSemanticNode(
Sharon Yang6f3a47b2020-01-08 21:32:29179 source_node_data.id, Role::HEADER, std::move(attributes),
180 std::move(states), std::vector<Action>{Action::SET_VALUE},
Sharon Yang28eac792019-10-16 00:28:23181 std::vector<uint32_t>{kChildId1, kChildId2, kChildId3}, box, mat.value);
182
183 // Start with nodes being equal.
Sharon Yang6f3a47b2020-01-08 21:32:29184 EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
Sharon Yang28eac792019-10-16 00:28:23185
186 // Make a copy of |source_node_data| and change the name attribute. Check that
187 // the resulting |converted_node| is different from |expected_node|.
188 auto modified_node_data = source_node_data;
189 modified_node_data.AddStringAttribute(ax::mojom::StringAttribute::kName,
190 kLabel2);
191 converted_node = AXNodeDataToSemanticNode(modified_node_data);
Sharon Yang6f3a47b2020-01-08 21:32:29192 EXPECT_FALSE(fidl::Equals(converted_node, expected_node));
Sharon Yang28eac792019-10-16 00:28:23193
194 // The same as above, this time changing |child_ids|.
195 modified_node_data = source_node_data;
196 modified_node_data.child_ids = std::vector<int32_t>{};
197 converted_node = AXNodeDataToSemanticNode(modified_node_data);
Sharon Yang6f3a47b2020-01-08 21:32:29198 EXPECT_FALSE(fidl::Equals(converted_node, expected_node));
Sharon Yang28eac792019-10-16 00:28:23199}
200
Sharon Yang28eac792019-10-16 00:28:23201} // namespace