The Test UI Stack is a Fuchsia package that leverages the UITestRealm library to streamline UI realm setup for tests that depend on or interoperate with a UI layer, but that may not be concerned with the details of setting up that UI layer.
The Test UI Stack provides UI-specific testing capabilities to test clients both in- and out-of-tree. See the Test UI Stack RFC for more details.
The Test UI Stack always creates a Scene Manager-owner scene with Scenic, accessibility protocols through a Fake A11y Manager, and production-like input support through the Input Pipeline library (integrated as a part of Scene Manager).
The Test UI Stack supports configuring the underlying UITestRealm instance using the following arguments via Structured Configuration:
The pseudo-C++ snippet below outlines a basic touch input test using the Test UI Stack component.
// Client test code creates a RealmBuilder instance.
component_testing::RealmBuilder realm_builder;
// Instantiate Test UI Stack component by absolute URL in the test realm.
realm_builder.AddChild("test-ui-stack",
"fuchsia-pkg://fuchsia.com/test-ui-stack#meta/test-ui-stack.cm");
// Add a test view component to the test realm, and route required UI services
// to it.
realm_builder.AddChild("test-view", ...);
realm_builder.AddRoute({
.capabilities = {Protocol{fuchsia::ui::scenic::Scenic::Name_}},
.source = ChildRef{"test-ui-stack"},
.targets = {"test-view"}});
// Expose fuchsia.ui.app.ViewProvider from the test view.
realm_builder.AddRoute({
.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
.source = ChildRef{"test-view"},
.targets = {ParentRef()}});
// Build the test realm.
RealmRoot realm_root = realm_builder_.Build();
// Connect to the scene provider "helper service", and request to attach a
// test view to the scene.
std::optional<zx_koid_t> client_view_ref_koid;
fuchsia::ui::observation::geometry::Provider geometry_provider;
auto scene_provider = realm_root->Connect<fuchsia::ui::test::scene::Provider>();
auto view_provider = realm_root_->Connect<fuchsia::ui::app::ViewProvider>();
scene_provider->AttachView(std::move(view_provider), geometry_provider.NewRequest(),
[&client_view_ref_koid](auto view_ref_koid) {
// Save the client's ViewRef koid.
client_view_ref_koid = view_ref_koid;
});
// Wait for client view ref koid to become available.
RunLoopUntil([&client_view_ref_koid] {
return client_view_ref_koid.has_value();
});
// Use registered geometry provider to wait for client view to render.
ASSERT_TRUE(geometry_provider.is_bound());
geometry_provider.Watch(...);
RunLoopUntil(...);
// Connect to input synthesis helper service, and use to inject input.
auto input_synthesis = realm_root->Connect<fuchsia::ui::test::input::Touch>();
input_synthesis->InjectTap(...);