Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 77 additions & 84 deletions shell/platform/embedder/tests/embedder_a11y_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
#include "flutter/testing/testing.h"
#include "third_party/tonic/converter/dart_converter.h"

#include "gmock/gmock.h" // For EXPECT_THAT and matchers
#include "gtest/gtest.h"

// CREATE_NATIVE_ENTRY is leaky by design
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
Expand All @@ -23,6 +27,7 @@ namespace flutter {
namespace testing {

using EmbedderA11yTest = testing::EmbedderTest;
using ::testing::ElementsAre;

constexpr static char kTooltip[] = "tooltip";

Expand Down Expand Up @@ -175,9 +180,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistent) {
// Wait for initial NotifySemanticsEnabled(false).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check exception is still null?

ASSERT_FALSE(enabled);
notify_semantics_enabled_latch.Signal();
};
Expand All @@ -186,19 +191,19 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistent) {
// Prepare to NotifyAccessibilityFeatures call
fml::AutoResetWaitableEvent notify_features_latch;
notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_features_latch.Signal();
};

// Enable semantics. Wait for NotifySemanticsEnabled(true).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch_2;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = false;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_TRUE(enabled);
notify_semantics_enabled_latch_2.Signal();
};
Expand All @@ -212,9 +217,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistent) {
// Set accessibility features: (reduce_motion == true)
fml::AutoResetWaitableEvent notify_features_latch_2;
notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
bool enabled = false;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_TRUE(enabled);
notify_features_latch_2.Signal();
};
Expand All @@ -231,24 +236,19 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistent) {
// Dispatch a tap to semantics node 42. Wait for NotifySemanticsAction.
fml::AutoResetWaitableEvent notify_semantics_action_latch;
notify_semantics_action_callback = [&](Dart_NativeArguments args) {
int64_t node_id = 0;
Dart_GetNativeIntegerArgument(args, 0, &node_id);
Dart_Handle exception = nullptr;
int64_t node_id =
::tonic::DartConverter<int64_t>::FromArguments(args, 0, exception);
ASSERT_EQ(42, node_id);

int64_t action_id;
auto handle = Dart_GetNativeIntegerArgument(args, 1, &action_id);
ASSERT_FALSE(Dart_IsError(handle));
int64_t action_id =
::tonic::DartConverter<int64_t>::FromArguments(args, 1, exception);
ASSERT_EQ(static_cast<int32_t>(flutter::SemanticsAction::kTap), action_id);

Dart_Handle semantic_args = Dart_GetNativeArgument(args, 2);
int64_t data;
Dart_Handle dart_int = Dart_ListGetAt(semantic_args, 0);
Dart_IntegerToInt64(dart_int, &data);
ASSERT_EQ(2, data);

dart_int = Dart_ListGetAt(semantic_args, 1);
Dart_IntegerToInt64(dart_int, &data);
ASSERT_EQ(1, data);
std::vector<int64_t> semantic_args =
::tonic::DartConverter<std::vector<int64_t>>::FromArguments(args, 2,
exception);
ASSERT_THAT(semantic_args, ElementsAre(2, 1));
notify_semantics_action_latch.Signal();
};
std::vector<uint8_t> bytes({2, 1});
Expand All @@ -260,8 +260,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistent) {
// Disable semantics. Wait for NotifySemanticsEnabled(false).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch_3;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
Dart_GetNativeBooleanArgument(args, 0, &enabled);
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_semantics_enabled_latch_3.Signal();
};
Expand Down Expand Up @@ -355,9 +356,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingUnstableCallbacks) {
// Wait for initial NotifySemanticsEnabled(false).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_semantics_enabled_latch.Signal();
};
Expand All @@ -366,19 +367,19 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingUnstableCallbacks) {
// Prepare to NotifyAccessibilityFeatures call
fml::AutoResetWaitableEvent notify_features_latch;
notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_features_latch.Signal();
};

// Enable semantics. Wait for NotifySemanticsEnabled(true).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch_2;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = false;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_TRUE(enabled);
notify_semantics_enabled_latch_2.Signal();
};
Expand All @@ -392,9 +393,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingUnstableCallbacks) {
// Set accessibility features: (reduce_motion == true)
fml::AutoResetWaitableEvent notify_features_latch_2;
notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
bool enabled = false;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_TRUE(enabled);
notify_features_latch_2.Signal();
};
Expand All @@ -411,24 +412,19 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingUnstableCallbacks) {
// Dispatch a tap to semantics node 42. Wait for NotifySemanticsAction.
fml::AutoResetWaitableEvent notify_semantics_action_latch;
notify_semantics_action_callback = [&](Dart_NativeArguments args) {
int64_t node_id = 0;
Dart_GetNativeIntegerArgument(args, 0, &node_id);
Dart_Handle exception = nullptr;
int64_t node_id =
::tonic::DartConverter<int64_t>::FromArguments(args, 0, exception);
ASSERT_EQ(42, node_id);

int64_t action_id;
auto handle = Dart_GetNativeIntegerArgument(args, 1, &action_id);
ASSERT_FALSE(Dart_IsError(handle));
int64_t action_id =
::tonic::DartConverter<int64_t>::FromArguments(args, 1, exception);
ASSERT_EQ(static_cast<int32_t>(flutter::SemanticsAction::kTap), action_id);

Dart_Handle semantic_args = Dart_GetNativeArgument(args, 2);
int64_t data;
Dart_Handle dart_int = Dart_ListGetAt(semantic_args, 0);
Dart_IntegerToInt64(dart_int, &data);
ASSERT_EQ(2, data);

dart_int = Dart_ListGetAt(semantic_args, 1);
Dart_IntegerToInt64(dart_int, &data);
ASSERT_EQ(1, data);
std::vector<int64_t> semantic_args =
::tonic::DartConverter<std::vector<int64_t>>::FromArguments(args, 2,
exception);
ASSERT_THAT(semantic_args, ElementsAre(2, 1));
notify_semantics_action_latch.Signal();
};
std::vector<uint8_t> bytes({2, 1});
Expand All @@ -440,8 +436,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingUnstableCallbacks) {
// Disable semantics. Wait for NotifySemanticsEnabled(false).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch_3;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
Dart_GetNativeBooleanArgument(args, 0, &enabled);
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_semantics_enabled_latch_3.Signal();
};
Expand Down Expand Up @@ -552,9 +549,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingLegacyCallbacks) {
// Wait for initial NotifySemanticsEnabled(false).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_semantics_enabled_latch.Signal();
};
Expand All @@ -563,19 +560,19 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingLegacyCallbacks) {
// Prepare to NotifyAccessibilityFeatures call
fml::AutoResetWaitableEvent notify_features_latch;
notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_features_latch.Signal();
};

// Enable semantics. Wait for NotifySemanticsEnabled(true).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch_2;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = false;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_TRUE(enabled);
notify_semantics_enabled_latch_2.Signal();
};
Expand All @@ -589,9 +586,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingLegacyCallbacks) {
// Set accessibility features: (reduce_motion == true)
fml::AutoResetWaitableEvent notify_features_latch_2;
notify_accessibility_features_callback = [&](Dart_NativeArguments args) {
bool enabled = false;
auto handle = Dart_GetNativeBooleanArgument(args, 0, &enabled);
ASSERT_FALSE(Dart_IsError(handle));
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_TRUE(enabled);
notify_features_latch_2.Signal();
};
Expand All @@ -613,24 +610,19 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingLegacyCallbacks) {
// Dispatch a tap to semantics node 42. Wait for NotifySemanticsAction.
fml::AutoResetWaitableEvent notify_semantics_action_latch;
notify_semantics_action_callback = [&](Dart_NativeArguments args) {
int64_t node_id = 0;
Dart_GetNativeIntegerArgument(args, 0, &node_id);
Dart_Handle exception = nullptr;
int64_t node_id =
::tonic::DartConverter<int64_t>::FromArguments(args, 0, exception);
ASSERT_EQ(42, node_id);

int64_t action_id;
auto handle = Dart_GetNativeIntegerArgument(args, 1, &action_id);
ASSERT_FALSE(Dart_IsError(handle));
int64_t action_id =
::tonic::DartConverter<int64_t>::FromArguments(args, 1, exception);
ASSERT_EQ(static_cast<int32_t>(flutter::SemanticsAction::kTap), action_id);

Dart_Handle semantic_args = Dart_GetNativeArgument(args, 2);
int64_t data;
Dart_Handle dart_int = Dart_ListGetAt(semantic_args, 0);
Dart_IntegerToInt64(dart_int, &data);
ASSERT_EQ(2, data);

dart_int = Dart_ListGetAt(semantic_args, 1);
Dart_IntegerToInt64(dart_int, &data);
ASSERT_EQ(1, data);
std::vector<int64_t> semantic_args =
::tonic::DartConverter<std::vector<int64_t>>::FromArguments(args, 2,
exception);
ASSERT_THAT(semantic_args, ElementsAre(2, 1));
notify_semantics_action_latch.Signal();
};
std::vector<uint8_t> bytes({2, 1});
Expand All @@ -642,8 +634,9 @@ TEST_F(EmbedderA11yTest, A11yTreeIsConsistentUsingLegacyCallbacks) {
// Disable semantics. Wait for NotifySemanticsEnabled(false).
fml::AutoResetWaitableEvent notify_semantics_enabled_latch_3;
notify_semantics_enabled_callback = [&](Dart_NativeArguments args) {
bool enabled = true;
Dart_GetNativeBooleanArgument(args, 0, &enabled);
Dart_Handle exception = nullptr;
bool enabled =
::tonic::DartConverter<bool>::FromArguments(args, 0, exception);
ASSERT_FALSE(enabled);
notify_semantics_enabled_latch_3.Signal();
};
Expand Down