7 #include "flutter/third_party/accessibility/ax/ax_action_data.h"
8 #include "gtest/gtest.h"
15 TEST(FlutterPlatformNodeDelegateTest, NodeDelegateHasUniqueId) {
16 std::shared_ptr<TestAccessibilityBridge> bridge =
17 std::make_shared<TestAccessibilityBridge>();
20 FlutterSemanticsNode2 node0{
sizeof(FlutterSemanticsNode2), 0};
21 std::vector<int32_t> node0_children{1};
22 node0.child_count = node0_children.size();
23 node0.children_in_traversal_order = node0_children.data();
24 node0.children_in_hit_test_order = node0_children.data();
27 FlutterSemanticsNode2 node1{
sizeof(FlutterSemanticsNode2), 1};
28 node1.label =
"prefecture";
29 node1.value =
"Kyoto";
31 bridge->AddFlutterSemanticsNodeUpdate(node0);
32 bridge->AddFlutterSemanticsNodeUpdate(node1);
33 bridge->CommitUpdates();
35 auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
36 auto node1_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
37 EXPECT_TRUE(node0_delegate->GetUniqueId() != node1_delegate->GetUniqueId());
40 TEST(FlutterPlatformNodeDelegateTest, canPerfomActions) {
41 std::shared_ptr<TestAccessibilityBridge> bridge =
42 std::make_shared<TestAccessibilityBridge>();
43 FlutterSemanticsNode2 root;
45 root.flags = FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField;
46 root.actions =
static_cast<FlutterSemanticsAction
>(0);
47 root.text_selection_base = -1;
48 root.text_selection_extent = -1;
52 root.increased_value =
"";
53 root.decreased_value =
"";
56 root.custom_accessibility_actions_count = 0;
57 bridge->AddFlutterSemanticsNodeUpdate(root);
59 bridge->CommitUpdates();
61 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
63 ui::AXActionData action_data;
64 action_data.action = ax::mojom::Action::kDoDefault;
65 accessibility->AccessibilityPerformAction(action_data);
66 EXPECT_EQ(bridge->performed_actions.size(),
size_t{1});
67 EXPECT_EQ(bridge->performed_actions[0],
68 FlutterSemanticsAction::kFlutterSemanticsActionTap);
70 action_data.action = ax::mojom::Action::kFocus;
71 accessibility->AccessibilityPerformAction(action_data);
72 EXPECT_EQ(bridge->performed_actions.size(),
size_t{2});
74 bridge->performed_actions[1],
75 FlutterSemanticsAction::kFlutterSemanticsActionDidGainAccessibilityFocus);
77 action_data.action = ax::mojom::Action::kScrollToMakeVisible;
78 accessibility->AccessibilityPerformAction(action_data);
79 EXPECT_EQ(bridge->performed_actions.size(),
size_t{3});
80 EXPECT_EQ(bridge->performed_actions[2],
81 FlutterSemanticsAction::kFlutterSemanticsActionShowOnScreen);
84 TEST(FlutterPlatformNodeDelegateTest, canGetAXNode) {
86 std::shared_ptr<TestAccessibilityBridge> bridge =
87 std::make_shared<TestAccessibilityBridge>();
88 FlutterSemanticsNode2 root;
90 root.flags = FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField;
91 root.actions =
static_cast<FlutterSemanticsAction
>(0);
92 root.text_selection_base = -1;
93 root.text_selection_extent = -1;
97 root.increased_value =
"";
98 root.decreased_value =
"";
100 root.child_count = 0;
101 root.custom_accessibility_actions_count = 0;
102 bridge->AddFlutterSemanticsNodeUpdate(root);
104 bridge->CommitUpdates();
106 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
107 EXPECT_EQ(accessibility->GetData().id, 0);
110 TEST(FlutterPlatformNodeDelegateTest, canCalculateBoundsCorrectly) {
111 std::shared_ptr<TestAccessibilityBridge> bridge =
112 std::make_shared<TestAccessibilityBridge>();
113 FlutterSemanticsNode2 root;
118 root.increased_value =
"";
119 root.decreased_value =
"";
121 root.child_count = 1;
122 int32_t children[] = {1};
123 root.children_in_traversal_order = children;
124 root.custom_accessibility_actions_count = 0;
125 root.rect = {0, 0, 100, 100};
126 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
127 bridge->AddFlutterSemanticsNodeUpdate(root);
129 FlutterSemanticsNode2 child1;
131 child1.label =
"child 1";
134 child1.increased_value =
"";
135 child1.decreased_value =
"";
137 child1.child_count = 0;
138 child1.custom_accessibility_actions_count = 0;
139 child1.rect = {0, 0, 50, 50};
140 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
141 bridge->AddFlutterSemanticsNodeUpdate(child1);
143 bridge->CommitUpdates();
144 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
145 ui::AXOffscreenResult
result;
147 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
148 ui::AXClippingBehavior::kClipped, &
result);
149 EXPECT_EQ(bounds.x(), 0);
150 EXPECT_EQ(bounds.y(), 0);
151 EXPECT_EQ(bounds.width(), 25);
152 EXPECT_EQ(bounds.height(), 25);
153 EXPECT_EQ(
result, ui::AXOffscreenResult::kOnscreen);
156 TEST(FlutterPlatformNodeDelegateTest, canCalculateOffScreenBoundsCorrectly) {
157 std::shared_ptr<TestAccessibilityBridge> bridge =
158 std::make_shared<TestAccessibilityBridge>();
159 FlutterSemanticsNode2 root;
164 root.increased_value =
"";
165 root.decreased_value =
"";
167 root.child_count = 1;
168 int32_t children[] = {1};
169 root.children_in_traversal_order = children;
170 root.custom_accessibility_actions_count = 0;
171 root.rect = {0, 0, 100, 100};
172 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
173 bridge->AddFlutterSemanticsNodeUpdate(root);
175 FlutterSemanticsNode2 child1;
177 child1.label =
"child 1";
180 child1.increased_value =
"";
181 child1.decreased_value =
"";
183 child1.child_count = 0;
184 child1.custom_accessibility_actions_count = 0;
185 child1.rect = {90, 90, 100, 100};
186 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
187 bridge->AddFlutterSemanticsNodeUpdate(child1);
189 bridge->CommitUpdates();
190 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
191 ui::AXOffscreenResult
result;
193 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
194 ui::AXClippingBehavior::kUnclipped, &
result);
195 EXPECT_EQ(bounds.x(), 180);
196 EXPECT_EQ(bounds.y(), 180);
197 EXPECT_EQ(bounds.width(), 20);
198 EXPECT_EQ(bounds.height(), 20);
199 EXPECT_EQ(
result, ui::AXOffscreenResult::kOffscreen);
202 TEST(FlutterPlatformNodeDelegateTest, canUseOwnerBridge) {
203 std::shared_ptr<TestAccessibilityBridge> bridge =
204 std::make_shared<TestAccessibilityBridge>();
205 FlutterSemanticsNode2 root;
210 root.increased_value =
"";
211 root.decreased_value =
"";
213 root.child_count = 1;
214 int32_t children[] = {1};
215 root.children_in_traversal_order = children;
216 root.custom_accessibility_actions_count = 0;
217 root.rect = {0, 0, 100, 100};
218 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
219 bridge->AddFlutterSemanticsNodeUpdate(root);
221 FlutterSemanticsNode2 child1;
223 child1.label =
"child 1";
226 child1.increased_value =
"";
227 child1.decreased_value =
"";
229 child1.child_count = 0;
230 child1.custom_accessibility_actions_count = 0;
231 child1.rect = {0, 0, 50, 50};
232 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
233 bridge->AddFlutterSemanticsNodeUpdate(child1);
235 bridge->CommitUpdates();
236 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
237 auto owner_bridge = child1_node->GetOwnerBridge().lock();
240 gfx::RectF bounds = owner_bridge->RelativeToGlobalBounds(
241 child1_node->GetAXNode(),
result,
true);
242 EXPECT_EQ(bounds.x(), 0);
243 EXPECT_EQ(bounds.y(), 0);
244 EXPECT_EQ(bounds.width(), 25);
245 EXPECT_EQ(bounds.height(), 25);
249 TEST(FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor) {
250 std::shared_ptr<TestAccessibilityBridge> bridge =
251 std::make_shared<TestAccessibilityBridge>();
252 FlutterSemanticsNode2 root;
257 root.increased_value =
"";
258 root.decreased_value =
"";
260 root.child_count = 0;
261 root.children_in_traversal_order =
nullptr;
262 root.custom_accessibility_actions_count = 0;
263 bridge->AddFlutterSemanticsNodeUpdate(root);
265 bridge->CommitUpdates();
266 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
267 auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
268 EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
271 TEST(FlutterPlatformNodeDelegateTest, canGetFromNodeID) {
272 std::shared_ptr<TestAccessibilityBridge> bridge =
273 std::make_shared<TestAccessibilityBridge>();
274 FlutterSemanticsNode2 root;
279 root.increased_value =
"";
280 root.decreased_value =
"";
282 root.child_count = 1;
283 int32_t children[] = {1};
284 root.children_in_traversal_order = children;
285 root.custom_accessibility_actions_count = 0;
286 bridge->AddFlutterSemanticsNodeUpdate(root);
288 FlutterSemanticsNode2 child1;
290 child1.label =
"child 1";
293 child1.increased_value =
"";
294 child1.decreased_value =
"";
296 child1.child_count = 0;
297 child1.custom_accessibility_actions_count = 0;
298 bridge->AddFlutterSemanticsNodeUpdate(child1);
300 bridge->CommitUpdates();
301 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
302 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
303 auto node_by_id = root_node->GetFromNodeID(1);
304 EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);