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 FlutterSemanticsFlags emptyFlags = FlutterSemanticsFlags{};
23 node0.child_count = node0_children.size();
24 node0.children_in_traversal_order = node0_children.data();
25 node0.children_in_hit_test_order = node0_children.data();
26 node0.flags2 = &emptyFlags;
29 FlutterSemanticsNode2 node1{
sizeof(FlutterSemanticsNode2), 1};
30 node1.label =
"prefecture";
31 node1.value =
"Kyoto";
32 node1.flags2 = &emptyFlags;
34 bridge->AddFlutterSemanticsNodeUpdate(node0);
35 bridge->AddFlutterSemanticsNodeUpdate(node1);
36 bridge->CommitUpdates();
38 auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
39 auto node1_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
40 EXPECT_TRUE(node0_delegate->GetUniqueId() != node1_delegate->GetUniqueId());
43 TEST(FlutterPlatformNodeDelegateTest, canPerfomActions) {
44 std::shared_ptr<TestAccessibilityBridge> bridge =
45 std::make_shared<TestAccessibilityBridge>();
46 FlutterSemanticsNode2 root;
48 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
49 flags.is_text_field =
true;
52 root.actions =
static_cast<FlutterSemanticsAction
>(0);
53 root.text_selection_base = -1;
54 root.text_selection_extent = -1;
58 root.increased_value =
"";
59 root.decreased_value =
"";
62 root.custom_accessibility_actions_count = 0;
64 bridge->AddFlutterSemanticsNodeUpdate(root);
66 bridge->CommitUpdates();
68 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
70 ui::AXActionData action_data;
71 action_data.action = ax::mojom::Action::kDoDefault;
72 accessibility->AccessibilityPerformAction(action_data);
73 EXPECT_EQ(bridge->performed_actions.size(),
size_t{1});
74 EXPECT_EQ(bridge->performed_actions[0],
75 FlutterSemanticsAction::kFlutterSemanticsActionTap);
77 action_data.action = ax::mojom::Action::kFocus;
78 accessibility->AccessibilityPerformAction(action_data);
79 EXPECT_EQ(bridge->performed_actions.size(),
size_t{2});
81 bridge->performed_actions[1],
82 FlutterSemanticsAction::kFlutterSemanticsActionDidGainAccessibilityFocus);
84 action_data.action = ax::mojom::Action::kScrollToMakeVisible;
85 accessibility->AccessibilityPerformAction(action_data);
86 EXPECT_EQ(bridge->performed_actions.size(),
size_t{3});
87 EXPECT_EQ(bridge->performed_actions[2],
88 FlutterSemanticsAction::kFlutterSemanticsActionShowOnScreen);
91 TEST(FlutterPlatformNodeDelegateTest, canGetAXNode) {
93 std::shared_ptr<TestAccessibilityBridge> bridge =
94 std::make_shared<TestAccessibilityBridge>();
95 FlutterSemanticsNode2 root;
97 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
98 flags.is_text_field =
true;
101 root.actions =
static_cast<FlutterSemanticsAction
>(0);
102 root.text_selection_base = -1;
103 root.text_selection_extent = -1;
107 root.increased_value =
"";
108 root.decreased_value =
"";
110 root.child_count = 0;
111 root.custom_accessibility_actions_count = 0;
112 root.identifier =
"";
113 bridge->AddFlutterSemanticsNodeUpdate(root);
115 bridge->CommitUpdates();
117 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
118 EXPECT_EQ(accessibility->GetData().id, 0);
121 TEST(FlutterPlatformNodeDelegateTest, canCalculateBoundsCorrectly) {
122 std::shared_ptr<TestAccessibilityBridge> bridge =
123 std::make_shared<TestAccessibilityBridge>();
124 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
125 FlutterSemanticsNode2 root;
130 root.increased_value =
"";
131 root.decreased_value =
"";
133 root.child_count = 1;
134 root.flags2 = &flags;
135 int32_t children[] = {1};
136 root.children_in_traversal_order = children;
137 root.custom_accessibility_actions_count = 0;
138 root.identifier =
"";
139 root.rect = {0, 0, 100, 100};
140 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
141 bridge->AddFlutterSemanticsNodeUpdate(root);
143 FlutterSemanticsNode2 child1;
145 child1.label =
"child 1";
148 child1.increased_value =
"";
149 child1.decreased_value =
"";
151 child1.child_count = 0;
152 child1.flags2 = &flags;
153 child1.custom_accessibility_actions_count = 0;
154 child1.identifier =
"";
155 child1.rect = {0, 0, 50, 50};
156 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
157 bridge->AddFlutterSemanticsNodeUpdate(child1);
159 bridge->CommitUpdates();
160 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
161 ui::AXOffscreenResult result;
163 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
164 ui::AXClippingBehavior::kClipped, &result);
165 EXPECT_EQ(bounds.x(), 0);
166 EXPECT_EQ(bounds.y(), 0);
167 EXPECT_EQ(bounds.width(), 25);
168 EXPECT_EQ(bounds.height(), 25);
169 EXPECT_EQ(result, ui::AXOffscreenResult::kOnscreen);
172 TEST(FlutterPlatformNodeDelegateTest, canCalculateOffScreenBoundsCorrectly) {
173 std::shared_ptr<TestAccessibilityBridge> bridge =
174 std::make_shared<TestAccessibilityBridge>();
175 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
176 FlutterSemanticsNode2 root;
181 root.increased_value =
"";
182 root.decreased_value =
"";
184 root.child_count = 1;
185 root.flags2 = &flags;
186 int32_t children[] = {1};
187 root.children_in_traversal_order = children;
188 root.custom_accessibility_actions_count = 0;
189 root.identifier =
"";
190 root.rect = {0, 0, 100, 100};
191 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
192 bridge->AddFlutterSemanticsNodeUpdate(root);
194 FlutterSemanticsNode2 child1;
196 child1.label =
"child 1";
199 child1.increased_value =
"";
200 child1.decreased_value =
"";
202 child1.child_count = 0;
203 child1.flags2 = &flags;
204 child1.custom_accessibility_actions_count = 0;
205 child1.identifier =
"";
206 child1.rect = {90, 90, 100, 100};
207 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
208 bridge->AddFlutterSemanticsNodeUpdate(child1);
210 bridge->CommitUpdates();
211 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
212 ui::AXOffscreenResult result;
214 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
215 ui::AXClippingBehavior::kUnclipped, &result);
216 EXPECT_EQ(bounds.x(), 180);
217 EXPECT_EQ(bounds.y(), 180);
218 EXPECT_EQ(bounds.width(), 20);
219 EXPECT_EQ(bounds.height(), 20);
220 EXPECT_EQ(result, ui::AXOffscreenResult::kOffscreen);
223 TEST(FlutterPlatformNodeDelegateTest, canUseOwnerBridge) {
224 std::shared_ptr<TestAccessibilityBridge> bridge =
225 std::make_shared<TestAccessibilityBridge>();
226 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
227 FlutterSemanticsNode2 root{
sizeof(FlutterSemanticsNode2), 0};
231 root.increased_value =
"";
232 root.decreased_value =
"";
234 root.heading_level = 0;
235 root.child_count = 1;
236 root.flags2 = &flags;
237 int32_t children[] = {1};
238 root.children_in_traversal_order = children;
239 root.custom_accessibility_actions_count = 0;
240 root.identifier =
"";
241 root.rect = {0, 0, 100, 100};
242 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
243 bridge->AddFlutterSemanticsNodeUpdate(root);
245 FlutterSemanticsNode2 child1{
sizeof(FlutterSemanticsNode2), 1};
246 child1.label =
"child 1";
249 child1.increased_value =
"";
250 child1.decreased_value =
"";
252 child1.heading_level = 0;
253 child1.child_count = 0;
254 child1.flags2 = &flags;
255 child1.custom_accessibility_actions_count = 0;
256 child1.identifier =
"";
257 child1.rect = {0, 0, 50, 50};
258 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
259 bridge->AddFlutterSemanticsNodeUpdate(child1);
261 bridge->CommitUpdates();
262 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
263 auto owner_bridge = child1_node->GetOwnerBridge().lock();
266 gfx::RectF bounds = owner_bridge->RelativeToGlobalBounds(
267 child1_node->GetAXNode(), result,
true);
268 EXPECT_EQ(bounds.x(), 0);
269 EXPECT_EQ(bounds.y(), 0);
270 EXPECT_EQ(bounds.width(), 25);
271 EXPECT_EQ(bounds.height(), 25);
272 EXPECT_EQ(result,
false);
275 TEST(FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor) {
276 std::shared_ptr<TestAccessibilityBridge> bridge =
277 std::make_shared<TestAccessibilityBridge>();
278 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
279 FlutterSemanticsNode2 root;
284 root.increased_value =
"";
285 root.decreased_value =
"";
287 root.child_count = 0;
288 root.flags2 = &flags;
289 root.children_in_traversal_order =
nullptr;
290 root.custom_accessibility_actions_count = 0;
291 root.identifier =
"";
292 bridge->AddFlutterSemanticsNodeUpdate(root);
294 bridge->CommitUpdates();
295 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
296 auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
297 EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
300 TEST(FlutterPlatformNodeDelegateTest, canGetFromNodeID) {
301 std::shared_ptr<TestAccessibilityBridge> bridge =
302 std::make_shared<TestAccessibilityBridge>();
303 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
304 FlutterSemanticsNode2 root;
309 root.increased_value =
"";
310 root.decreased_value =
"";
312 root.child_count = 1;
313 root.flags2 = &flags;
314 int32_t children[] = {1};
315 root.children_in_traversal_order = children;
316 root.custom_accessibility_actions_count = 0;
317 root.identifier =
"";
318 bridge->AddFlutterSemanticsNodeUpdate(root);
320 FlutterSemanticsNode2 child1;
322 child1.label =
"child 1";
325 child1.increased_value =
"";
326 child1.decreased_value =
"";
328 child1.child_count = 0;
329 child1.flags2 = &flags;
330 child1.custom_accessibility_actions_count = 0;
331 child1.identifier =
"";
332 bridge->AddFlutterSemanticsNodeUpdate(child1);
334 bridge->CommitUpdates();
335 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
336 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
337 auto node_by_id = root_node->GetFromNodeID(1);
338 EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);
TEST(AccessibilityBridgeTest, BasicTest)