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;
51 root.actions =
static_cast<FlutterSemanticsAction
>(0);
52 root.text_selection_base = -1;
53 root.text_selection_extent = -1;
57 root.increased_value =
"";
58 root.decreased_value =
"";
61 root.custom_accessibility_actions_count = 0;
62 bridge->AddFlutterSemanticsNodeUpdate(root);
64 bridge->CommitUpdates();
66 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
68 ui::AXActionData action_data;
69 action_data.action = ax::mojom::Action::kDoDefault;
70 accessibility->AccessibilityPerformAction(action_data);
71 EXPECT_EQ(bridge->performed_actions.size(),
size_t{1});
72 EXPECT_EQ(bridge->performed_actions[0],
73 FlutterSemanticsAction::kFlutterSemanticsActionTap);
75 action_data.action = ax::mojom::Action::kFocus;
76 accessibility->AccessibilityPerformAction(action_data);
77 EXPECT_EQ(bridge->performed_actions.size(),
size_t{2});
79 bridge->performed_actions[1],
80 FlutterSemanticsAction::kFlutterSemanticsActionDidGainAccessibilityFocus);
82 action_data.action = ax::mojom::Action::kScrollToMakeVisible;
83 accessibility->AccessibilityPerformAction(action_data);
84 EXPECT_EQ(bridge->performed_actions.size(),
size_t{3});
85 EXPECT_EQ(bridge->performed_actions[2],
86 FlutterSemanticsAction::kFlutterSemanticsActionShowOnScreen);
89 TEST(FlutterPlatformNodeDelegateTest, canGetAXNode) {
91 std::shared_ptr<TestAccessibilityBridge> bridge =
92 std::make_shared<TestAccessibilityBridge>();
93 FlutterSemanticsNode2 root;
95 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
96 flags.is_text_field =
true;
98 root.actions =
static_cast<FlutterSemanticsAction
>(0);
99 root.text_selection_base = -1;
100 root.text_selection_extent = -1;
104 root.increased_value =
"";
105 root.decreased_value =
"";
107 root.child_count = 0;
108 root.custom_accessibility_actions_count = 0;
109 bridge->AddFlutterSemanticsNodeUpdate(root);
111 bridge->CommitUpdates();
113 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
114 EXPECT_EQ(accessibility->GetData().id, 0);
117 TEST(FlutterPlatformNodeDelegateTest, canCalculateBoundsCorrectly) {
118 std::shared_ptr<TestAccessibilityBridge> bridge =
119 std::make_shared<TestAccessibilityBridge>();
120 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
121 FlutterSemanticsNode2 root;
126 root.increased_value =
"";
127 root.decreased_value =
"";
129 root.child_count = 1;
130 root.flags2 = &flags;
131 int32_t children[] = {1};
132 root.children_in_traversal_order = children;
133 root.custom_accessibility_actions_count = 0;
134 root.rect = {0, 0, 100, 100};
135 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
136 bridge->AddFlutterSemanticsNodeUpdate(root);
138 FlutterSemanticsNode2 child1;
140 child1.label =
"child 1";
143 child1.increased_value =
"";
144 child1.decreased_value =
"";
146 child1.child_count = 0;
147 child1.flags2 = &flags;
148 child1.custom_accessibility_actions_count = 0;
149 child1.rect = {0, 0, 50, 50};
150 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
151 bridge->AddFlutterSemanticsNodeUpdate(child1);
153 bridge->CommitUpdates();
154 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
155 ui::AXOffscreenResult result;
157 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
158 ui::AXClippingBehavior::kClipped, &result);
159 EXPECT_EQ(bounds.x(), 0);
160 EXPECT_EQ(bounds.y(), 0);
161 EXPECT_EQ(bounds.width(), 25);
162 EXPECT_EQ(bounds.height(), 25);
163 EXPECT_EQ(result, ui::AXOffscreenResult::kOnscreen);
166 TEST(FlutterPlatformNodeDelegateTest, canCalculateOffScreenBoundsCorrectly) {
167 std::shared_ptr<TestAccessibilityBridge> bridge =
168 std::make_shared<TestAccessibilityBridge>();
169 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
170 FlutterSemanticsNode2 root;
175 root.increased_value =
"";
176 root.decreased_value =
"";
178 root.child_count = 1;
179 root.flags2 = &flags;
180 int32_t children[] = {1};
181 root.children_in_traversal_order = children;
182 root.custom_accessibility_actions_count = 0;
183 root.rect = {0, 0, 100, 100};
184 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
185 bridge->AddFlutterSemanticsNodeUpdate(root);
187 FlutterSemanticsNode2 child1;
189 child1.label =
"child 1";
192 child1.increased_value =
"";
193 child1.decreased_value =
"";
195 child1.child_count = 0;
196 child1.flags2 = &flags;
197 child1.custom_accessibility_actions_count = 0;
198 child1.rect = {90, 90, 100, 100};
199 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
200 bridge->AddFlutterSemanticsNodeUpdate(child1);
202 bridge->CommitUpdates();
203 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
204 ui::AXOffscreenResult result;
206 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
207 ui::AXClippingBehavior::kUnclipped, &result);
208 EXPECT_EQ(bounds.x(), 180);
209 EXPECT_EQ(bounds.y(), 180);
210 EXPECT_EQ(bounds.width(), 20);
211 EXPECT_EQ(bounds.height(), 20);
212 EXPECT_EQ(result, ui::AXOffscreenResult::kOffscreen);
215 TEST(FlutterPlatformNodeDelegateTest, canUseOwnerBridge) {
216 std::shared_ptr<TestAccessibilityBridge> bridge =
217 std::make_shared<TestAccessibilityBridge>();
218 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
219 FlutterSemanticsNode2 root;
224 root.increased_value =
"";
225 root.decreased_value =
"";
227 root.child_count = 1;
228 root.flags2 = &flags;
229 int32_t children[] = {1};
230 root.children_in_traversal_order = children;
231 root.custom_accessibility_actions_count = 0;
232 root.rect = {0, 0, 100, 100};
233 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
234 bridge->AddFlutterSemanticsNodeUpdate(root);
236 FlutterSemanticsNode2 child1;
238 child1.label =
"child 1";
241 child1.increased_value =
"";
242 child1.decreased_value =
"";
244 child1.child_count = 0;
245 child1.flags2 = &flags;
246 child1.custom_accessibility_actions_count = 0;
247 child1.rect = {0, 0, 50, 50};
248 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
249 bridge->AddFlutterSemanticsNodeUpdate(child1);
251 bridge->CommitUpdates();
252 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
253 auto owner_bridge = child1_node->GetOwnerBridge().lock();
256 gfx::RectF bounds = owner_bridge->RelativeToGlobalBounds(
257 child1_node->GetAXNode(), result,
true);
258 EXPECT_EQ(bounds.x(), 0);
259 EXPECT_EQ(bounds.y(), 0);
260 EXPECT_EQ(bounds.width(), 25);
261 EXPECT_EQ(bounds.height(), 25);
262 EXPECT_EQ(result,
false);
265 TEST(FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor) {
266 std::shared_ptr<TestAccessibilityBridge> bridge =
267 std::make_shared<TestAccessibilityBridge>();
268 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
269 FlutterSemanticsNode2 root;
274 root.increased_value =
"";
275 root.decreased_value =
"";
277 root.child_count = 0;
278 root.flags2 = &flags;
279 root.children_in_traversal_order =
nullptr;
280 root.custom_accessibility_actions_count = 0;
281 bridge->AddFlutterSemanticsNodeUpdate(root);
283 bridge->CommitUpdates();
284 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
285 auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
286 EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
289 TEST(FlutterPlatformNodeDelegateTest, canGetFromNodeID) {
290 std::shared_ptr<TestAccessibilityBridge> bridge =
291 std::make_shared<TestAccessibilityBridge>();
292 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
293 FlutterSemanticsNode2 root;
298 root.increased_value =
"";
299 root.decreased_value =
"";
301 root.child_count = 1;
302 root.flags2 = &flags;
303 int32_t children[] = {1};
304 root.children_in_traversal_order = children;
305 root.custom_accessibility_actions_count = 0;
306 bridge->AddFlutterSemanticsNodeUpdate(root);
308 FlutterSemanticsNode2 child1;
310 child1.label =
"child 1";
313 child1.increased_value =
"";
314 child1.decreased_value =
"";
316 child1.child_count = 0;
317 child1.flags2 = &flags;
318 child1.custom_accessibility_actions_count = 0;
319 bridge->AddFlutterSemanticsNodeUpdate(child1);
321 bridge->CommitUpdates();
322 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
323 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
324 auto node_by_id = root_node->GetFromNodeID(1);
325 EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);
TEST(AccessibilityBridgeWindows, GetParent)