Flutter Engine
The Flutter Engine
flutter_platform_node_delegate_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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
6
7#include "flutter/third_party/accessibility/ax/ax_action_data.h"
8#include "gtest/gtest.h"
9
11
12namespace flutter {
13namespace testing {
14
15TEST(FlutterPlatformNodeDelegateTest, NodeDelegateHasUniqueId) {
16 std::shared_ptr<TestAccessibilityBridge> bridge =
17 std::make_shared<TestAccessibilityBridge>();
18
19 // Add node 0: root.
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();
25
26 // Add node 1: text child of node 0.
28 node1.label = "prefecture";
29 node1.value = "Kyoto";
30
31 bridge->AddFlutterSemanticsNodeUpdate(node0);
32 bridge->AddFlutterSemanticsNodeUpdate(node1);
33 bridge->CommitUpdates();
34
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());
38}
39
40TEST(FlutterPlatformNodeDelegateTest, canPerfomActions) {
41 std::shared_ptr<TestAccessibilityBridge> bridge =
42 std::make_shared<TestAccessibilityBridge>();
44 root.id = 0;
46 root.actions = static_cast<FlutterSemanticsAction>(0);
47 root.text_selection_base = -1;
48 root.text_selection_extent = -1;
49 root.label = "root";
50 root.hint = "";
51 root.value = "";
52 root.increased_value = "";
53 root.decreased_value = "";
54 root.tooltip = "";
55 root.child_count = 0;
56 root.custom_accessibility_actions_count = 0;
57 bridge->AddFlutterSemanticsNodeUpdate(root);
58
59 bridge->CommitUpdates();
60
61 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
62 // Performs an AXAction.
63 ui::AXActionData action_data;
65 accessibility->AccessibilityPerformAction(action_data);
66 EXPECT_EQ(bridge->performed_actions.size(), size_t{1});
67 EXPECT_EQ(bridge->performed_actions[0],
69
71 accessibility->AccessibilityPerformAction(action_data);
72 EXPECT_EQ(bridge->performed_actions.size(), size_t{2});
73 EXPECT_EQ(
74 bridge->performed_actions[1],
76
78 accessibility->AccessibilityPerformAction(action_data);
79 EXPECT_EQ(bridge->performed_actions.size(), size_t{3});
80 EXPECT_EQ(bridge->performed_actions[2],
82}
83
84TEST(FlutterPlatformNodeDelegateTest, canGetAXNode) {
85 // Set up a flutter accessibility node.
86 std::shared_ptr<TestAccessibilityBridge> bridge =
87 std::make_shared<TestAccessibilityBridge>();
89 root.id = 0;
91 root.actions = static_cast<FlutterSemanticsAction>(0);
92 root.text_selection_base = -1;
93 root.text_selection_extent = -1;
94 root.label = "root";
95 root.hint = "";
96 root.value = "";
97 root.increased_value = "";
98 root.decreased_value = "";
99 root.tooltip = "";
100 root.child_count = 0;
101 root.custom_accessibility_actions_count = 0;
102 bridge->AddFlutterSemanticsNodeUpdate(root);
103
104 bridge->CommitUpdates();
105
106 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
107 EXPECT_EQ(accessibility->GetData().id, 0);
108}
109
110TEST(FlutterPlatformNodeDelegateTest, canCalculateBoundsCorrectly) {
111 std::shared_ptr<TestAccessibilityBridge> bridge =
112 std::make_shared<TestAccessibilityBridge>();
114 root.id = 0;
115 root.label = "root";
116 root.hint = "";
117 root.value = "";
118 root.increased_value = "";
119 root.decreased_value = "";
120 root.tooltip = "";
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}; // LTRB
126 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
127 bridge->AddFlutterSemanticsNodeUpdate(root);
128
130 child1.id = 1;
131 child1.label = "child 1";
132 child1.hint = "";
133 child1.value = "";
134 child1.increased_value = "";
135 child1.decreased_value = "";
136 child1.tooltip = "";
137 child1.child_count = 0;
139 child1.rect = {0, 0, 50, 50}; // LTRB
140 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
141 bridge->AddFlutterSemanticsNodeUpdate(child1);
142
143 bridge->CommitUpdates();
144 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
147 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
149 EXPECT_EQ(bounds.x(), 0);
150 EXPECT_EQ(bounds.y(), 0);
151 EXPECT_EQ(bounds.width(), 25);
152 EXPECT_EQ(bounds.height(), 25);
154}
155
156TEST(FlutterPlatformNodeDelegateTest, canCalculateOffScreenBoundsCorrectly) {
157 std::shared_ptr<TestAccessibilityBridge> bridge =
158 std::make_shared<TestAccessibilityBridge>();
160 root.id = 0;
161 root.label = "root";
162 root.hint = "";
163 root.value = "";
164 root.increased_value = "";
165 root.decreased_value = "";
166 root.tooltip = "";
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}; // LTRB
172 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
173 bridge->AddFlutterSemanticsNodeUpdate(root);
174
176 child1.id = 1;
177 child1.label = "child 1";
178 child1.hint = "";
179 child1.value = "";
180 child1.increased_value = "";
181 child1.decreased_value = "";
182 child1.tooltip = "";
183 child1.child_count = 0;
185 child1.rect = {90, 90, 100, 100}; // LTRB
186 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
187 bridge->AddFlutterSemanticsNodeUpdate(child1);
188
189 bridge->CommitUpdates();
190 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
193 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
195 EXPECT_EQ(bounds.x(), 180);
196 EXPECT_EQ(bounds.y(), 180);
197 EXPECT_EQ(bounds.width(), 20);
198 EXPECT_EQ(bounds.height(), 20);
200}
201
202TEST(FlutterPlatformNodeDelegateTest, canUseOwnerBridge) {
203 std::shared_ptr<TestAccessibilityBridge> bridge =
204 std::make_shared<TestAccessibilityBridge>();
206 root.id = 0;
207 root.label = "root";
208 root.hint = "";
209 root.value = "";
210 root.increased_value = "";
211 root.decreased_value = "";
212 root.tooltip = "";
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}; // LTRB
218 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
219 bridge->AddFlutterSemanticsNodeUpdate(root);
220
222 child1.id = 1;
223 child1.label = "child 1";
224 child1.hint = "";
225 child1.value = "";
226 child1.increased_value = "";
227 child1.decreased_value = "";
228 child1.tooltip = "";
229 child1.child_count = 0;
231 child1.rect = {0, 0, 50, 50}; // LTRB
232 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
233 bridge->AddFlutterSemanticsNodeUpdate(child1);
234
235 bridge->CommitUpdates();
236 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
237 auto owner_bridge = child1_node->GetOwnerBridge().lock();
238
239 bool result;
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);
246 EXPECT_EQ(result, false);
247}
248
249TEST(FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor) {
250 std::shared_ptr<TestAccessibilityBridge> bridge =
251 std::make_shared<TestAccessibilityBridge>();
253 root.id = 0;
254 root.label = "root";
255 root.hint = "";
256 root.value = "";
257 root.increased_value = "";
258 root.decreased_value = "";
259 root.tooltip = "";
260 root.child_count = 0;
261 root.children_in_traversal_order = nullptr;
262 root.custom_accessibility_actions_count = 0;
263 bridge->AddFlutterSemanticsNodeUpdate(root);
264
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);
269}
270
271TEST(FlutterPlatformNodeDelegateTest, canGetFromNodeID) {
272 std::shared_ptr<TestAccessibilityBridge> bridge =
273 std::make_shared<TestAccessibilityBridge>();
275 root.id = 0;
276 root.label = "root";
277 root.hint = "";
278 root.value = "";
279 root.increased_value = "";
280 root.decreased_value = "";
281 root.tooltip = "";
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);
287
289 child1.id = 1;
290 child1.label = "child 1";
291 child1.hint = "";
292 child1.value = "";
293 child1.increased_value = "";
294 child1.decreased_value = "";
295 child1.tooltip = "";
296 child1.child_count = 0;
298 bridge->AddFlutterSemanticsNodeUpdate(child1);
299
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);
305}
306
307} // namespace testing
308} // namespace flutter
Definition: rect.h:36
FlutterSemanticsAction
Definition: embedder.h:113
@ kFlutterSemanticsActionShowOnScreen
A request to fully show the semantics node on screen.
Definition: embedder.h:138
@ kFlutterSemanticsActionDidGainAccessibilityFocus
Indicate that the node has gained accessibility focus.
Definition: embedder.h:152
@ kFlutterSemanticsActionTap
Definition: embedder.h:116
@ kFlutterSemanticsFlagIsTextField
Whether the semantic node represents a text field.
Definition: embedder.h:183
GAsyncResult * result
Optional< SkRect > bounds
Definition: SkRecords.h:189
TEST(DisplayListComplexity, EmptyDisplayList)
string root
Definition: scale_cpu.py:20
const char * increased_value
Definition: embedder.h:1370
const char * tooltip
A textual tooltip attached to the node.
Definition: embedder.h:1397
size_t custom_accessibility_actions_count
The number of custom accessibility action associated with this node.
Definition: embedder.h:1389
int32_t id
The unique identifier for this node.
Definition: embedder.h:1337
FlutterRect rect
The bounding box for this node in its coordinate system.
Definition: embedder.h:1378
FlutterTransformation transform
Definition: embedder.h:1381
size_t child_count
The number of children this node has.
Definition: embedder.h:1383
const char * decreased_value
Definition: embedder.h:1373
const char * label
A textual description of the node.
Definition: embedder.h:1363
const char * hint
A brief description of the result of performing an action on the node.
Definition: embedder.h:1365
const char * value
A textual description of the current value of the node.
Definition: embedder.h:1367
ax::mojom::Action action
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678