5#import "flutter/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMac.h"
7#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
8#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
9#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
10#include "flutter/testing/autoreleasepool_test.h"
11#include "flutter/testing/testing.h"
17class AccessibilityBridgeMacSpy :
public AccessibilityBridgeMac {
21 AccessibilityBridgeMacSpy(__weak
FlutterEngine* flutter_engine,
23 : AccessibilityBridgeMac(flutter_engine, view_controller) {}
29 NSAccessibilityNotificationName mac_notification)
override {
38- (
std::shared_ptr<flutter::AccessibilityBridgeMac>)createAccessibilityBridgeWithEngine:
43- (
std::shared_ptr<flutter::AccessibilityBridgeMac>)createAccessibilityBridgeWithEngine:
45 return std::make_shared<flutter::testing::AccessibilityBridgeMacSpy>(
engine,
self);
57 initWithAssetsPath:fixtures
58 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
65class AccessibilityBridgeMacWindowTest :
public AutoreleasePoolTest {
67 AccessibilityBridgeMacWindowTest() {
69 gWindow_ = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
70 styleMask:NSBorderlessWindowMask
71 backing:NSBackingStoreBuffered
76 NSWindow* GetWindow()
const {
return gWindow_; }
79 static NSWindow* gWindow_;
83NSWindow* AccessibilityBridgeMacWindowTest::gWindow_ = nil;
86using AccessibilityBridgeMacTest = AutoreleasePoolTest;
90TEST_F(AccessibilityBridgeMacWindowTest, SendsAccessibilityCreateNotificationFlutterViewWindow) {
93 NSWindow* expectedTarget = GetWindow();
99 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
105 root.text_selection_base = -1;
106 root.text_selection_extent = -1;
110 root.increased_value =
"";
111 root.decreased_value =
"";
113 root.child_count = 0;
114 root.custom_accessibility_actions_count = 0;
115 bridge->AddFlutterSemanticsNodeUpdate(
root);
117 bridge->CommitUpdates();
118 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
126 std::vector<ui::AXEventIntent> intent;
131 bridge->OnAccessibilityEvent(targeted_event);
133 ASSERT_EQ(bridge->actual_notifications.size(), 1u);
134 auto target = bridge->actual_notifications.find([NSAccessibilityCreatedNotification UTF8String]);
135 ASSERT_NE(
target, bridge->actual_notifications.end());
136 EXPECT_EQ(
target->second, expectedTarget);
137 [engine shutDownEngine];
147TEST_F(AccessibilityBridgeMacWindowTest, NonZeroRootNodeId) {
150 NSWindow* expectedTarget = GetWindow();
156 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
160 std::vector<int32_t> node1_children{2};
166 node1.
label =
"node1";
183 node2.
label =
"node2";
192 bridge->AddFlutterSemanticsNodeUpdate(node1);
193 bridge->AddFlutterSemanticsNodeUpdate(node2);
194 bridge->CommitUpdates();
197 auto root_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
198 ASSERT_TRUE(root_delegate);
199 ASSERT_EQ(root_delegate->GetChildCount(), 1);
202 auto child_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
203 ASSERT_TRUE(child_delegate);
204 ASSERT_EQ(child_delegate->GetChildCount(), 0);
207 auto invalid_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
208 ASSERT_FALSE(invalid_delegate);
210 [engine shutDownEngine];
213TEST_F(AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenHeadless) {
220 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
226 root.text_selection_base = -1;
227 root.text_selection_extent = -1;
231 root.increased_value =
"";
232 root.decreased_value =
"";
234 root.child_count = 0;
235 root.custom_accessibility_actions_count = 0;
236 bridge->AddFlutterSemanticsNodeUpdate(
root);
238 bridge->CommitUpdates();
239 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
247 std::vector<ui::AXEventIntent> intent;
252 bridge->OnAccessibilityEvent(targeted_event);
255 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
256 [engine shutDownEngine];
259TEST_F(AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenNoWindow) {
266 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
272 root.text_selection_base = -1;
273 root.text_selection_extent = -1;
277 root.increased_value =
"";
278 root.decreased_value =
"";
280 root.child_count = 0;
281 root.custom_accessibility_actions_count = 0;
282 bridge->AddFlutterSemanticsNodeUpdate(
root);
284 bridge->CommitUpdates();
285 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
293 std::vector<ui::AXEventIntent> intent;
298 bridge->OnAccessibilityEvent(targeted_event);
301 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
302 [engine shutDownEngine];
std::unordered_map< std::string, gfx::NativeViewAccessible > actual_notifications
void OnAccessibilityEvent(ui::AXEventGenerator::TargetedEvent targeted_event) override
Handle accessibility events generated due to accessibility tree changes. These events are needed to b...
void SetData(const AXNodeData &src)
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
std::weak_ptr< flutter::AccessibilityBridgeMac > accessibilityBridge()
FlutterViewController * viewController
TEST_F(DisplayListTest, Defaults)
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
UnimplementedNativeViewAccessible * NativeViewAccessible
const char * increased_value
const char * tooltip
A textual tooltip attached to the node.
size_t custom_accessibility_actions_count
The number of custom accessibility action associated with this node.
const int32_t * children_in_traversal_order
Array of child node IDs in traversal order. Has length child_count.
const int32_t * children_in_hit_test_order
Array of child node IDs in hit test order. Has length child_count.
int32_t text_selection_extent
The position at which the text selection terminates.
FlutterSemanticsAction actions
The set of semantics actions applicable to this node.
int32_t id
The unique identifier for this node.
size_t child_count
The number of children this node has.
const char * decreased_value
const char * label
A textual description of the node.
int32_t text_selection_base
The position at which the text selection originates.
const char * hint
A brief description of the result of performing an action on the node.
const char * value
A textual description of the current value of the node.
FlutterSemanticsFlag flags
The set of semantics flags associated with this node.