4 #include "flutter/testing/testing.h"
19 AccessibilityBridgeMacSpy(__weak
FlutterEngine* flutter_engine,
26 void DispatchMacOSNotification(gfx::NativeViewAccessible native_node,
27 NSAccessibilityNotificationName mac_notification)
override {
36 - (std::shared_ptr<flutter::AccessibilityBridgeMac>)createAccessibilityBridgeWithEngine:
41 - (std::shared_ptr<flutter::AccessibilityBridgeMac>)createAccessibilityBridgeWithEngine:
43 return std::make_shared<flutter::testing::AccessibilityBridgeMacSpy>(
engine,
self);
53 NSString* fixtures = @(testing::GetFixturesPath());
55 initWithAssetsPath:fixtures
56 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
61 TEST(AccessibilityBridgeMacTest, SendsAccessibilityCreateNotificationToWindowOfFlutterView) {
64 [viewController loadView];
66 NSWindow* expectedTarget = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
67 styleMask:NSBorderlessWindowMask
68 backing:NSBackingStoreBuffered
70 expectedTarget.contentView = viewController.view;
73 engine.semanticsEnabled = YES;
74 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
75 viewController.accessibilityBridge.lock());
76 FlutterSemanticsNode2 root;
78 root.flags =
static_cast<FlutterSemanticsFlag
>(0);
79 root.actions =
static_cast<FlutterSemanticsAction
>(0);
80 root.text_selection_base = -1;
81 root.text_selection_extent = -1;
85 root.increased_value =
"";
86 root.decreased_value =
"";
89 root.custom_accessibility_actions_count = 0;
90 bridge->AddFlutterSemanticsNodeUpdate(root);
92 bridge->CommitUpdates();
93 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
97 ui::AXNode ax_node(&tree,
nullptr, 0, 0);
98 ui::AXNodeData node_data;
100 ax_node.SetData(node_data);
101 std::vector<ui::AXEventIntent> intent;
102 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
103 ax::mojom::EventFrom::kNone, intent);
104 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
106 bridge->OnAccessibilityEvent(targeted_event);
108 EXPECT_EQ(bridge->actual_notifications.size(), 1u);
110 bridge->actual_notifications.find([NSAccessibilityCreatedNotification UTF8String])->second,
122 TEST(AccessibilityBridgeMacTest, NonZeroRootNodeId) {
125 [viewController loadView];
127 NSWindow* expectedTarget = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
128 styleMask:NSBorderlessWindowMask
129 backing:NSBackingStoreBuffered
131 expectedTarget.contentView = viewController.view;
134 engine.semanticsEnabled = YES;
135 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
136 viewController.accessibilityBridge.lock());
138 FlutterSemanticsNode2 node1;
139 std::vector<int32_t> node1_children{2};
141 node1.flags =
static_cast<FlutterSemanticsFlag
>(0);
142 node1.actions =
static_cast<FlutterSemanticsAction
>(0);
143 node1.text_selection_base = -1;
144 node1.text_selection_extent = -1;
145 node1.label =
"node1";
148 node1.increased_value =
"";
149 node1.decreased_value =
"";
151 node1.child_count = node1_children.size();
152 node1.children_in_traversal_order = node1_children.data();
153 node1.children_in_hit_test_order = node1_children.data();
154 node1.custom_accessibility_actions_count = 0;
156 FlutterSemanticsNode2 node2;
158 node2.flags =
static_cast<FlutterSemanticsFlag
>(0);
159 node2.actions =
static_cast<FlutterSemanticsAction
>(0);
160 node2.text_selection_base = -1;
161 node2.text_selection_extent = -1;
162 node2.label =
"node2";
165 node2.increased_value =
"";
166 node2.decreased_value =
"";
168 node2.child_count = 0;
169 node2.custom_accessibility_actions_count = 0;
171 bridge->AddFlutterSemanticsNodeUpdate(node1);
172 bridge->AddFlutterSemanticsNodeUpdate(node2);
173 bridge->CommitUpdates();
176 auto root_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
177 ASSERT_TRUE(root_delegate);
178 ASSERT_EQ(root_delegate->GetChildCount(), 1);
181 auto child_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
182 ASSERT_TRUE(child_delegate);
183 ASSERT_EQ(child_delegate->GetChildCount(), 0);
186 auto invalid_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
187 ASSERT_FALSE(invalid_delegate);
192 TEST(AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenHeadless) {
195 [viewController loadView];
198 engine.semanticsEnabled = YES;
199 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
200 viewController.accessibilityBridge.lock());
201 FlutterSemanticsNode2 root;
203 root.flags =
static_cast<FlutterSemanticsFlag
>(0);
204 root.actions =
static_cast<FlutterSemanticsAction
>(0);
205 root.text_selection_base = -1;
206 root.text_selection_extent = -1;
210 root.increased_value =
"";
211 root.decreased_value =
"";
213 root.child_count = 0;
214 root.custom_accessibility_actions_count = 0;
215 bridge->AddFlutterSemanticsNodeUpdate(root);
217 bridge->CommitUpdates();
218 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
222 ui::AXNode ax_node(&tree,
nullptr, 0, 0);
223 ui::AXNodeData node_data;
225 ax_node.SetData(node_data);
226 std::vector<ui::AXEventIntent> intent;
227 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
228 ax::mojom::EventFrom::kNone, intent);
229 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
231 bridge->OnAccessibilityEvent(targeted_event);
234 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
238 TEST(AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenNoWindow) {
241 [viewController loadView];
245 engine.semanticsEnabled = YES;
246 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
247 viewController.accessibilityBridge.lock());
248 FlutterSemanticsNode2 root;
250 root.flags =
static_cast<FlutterSemanticsFlag
>(0);
251 root.actions =
static_cast<FlutterSemanticsAction
>(0);
252 root.text_selection_base = -1;
253 root.text_selection_extent = -1;
257 root.increased_value =
"";
258 root.decreased_value =
"";
260 root.child_count = 0;
261 root.custom_accessibility_actions_count = 0;
262 bridge->AddFlutterSemanticsNodeUpdate(root);
264 bridge->CommitUpdates();
265 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
269 ui::AXNode ax_node(&tree,
nullptr, 0, 0);
270 ui::AXNodeData node_data;
272 ax_node.SetData(node_data);
273 std::vector<ui::AXEventIntent> intent;
274 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
275 ax::mojom::EventFrom::kNone, intent);
276 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
278 bridge->OnAccessibilityEvent(targeted_event);
281 EXPECT_EQ(bridge->actual_notifications.size(), 0u);