tree: f39e1d7be4dfec548643d52f1dc3ff271e7bc8a1 [path history] [tgz]
  1. meta/
  2. BUILD.gn
  3. main.cc
  4. README.md
src/ui/testing/test_ui_stack/README.md

Test UI Stack

Overview

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.

Scene Setup

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).

Configurability

The Test UI Stack supports configuring the underlying UITestRealm instance using the following arguments via Structured Configuration:

  • display_rotation: The rotation of the display, counter-clockwise, in 90-degree increments.
  • device_pixel_ratio: The conversion factor between logical and physical coordinates.
  • use_flatland (soon to be deprecated): Whether to use Flatland or not.

Example Usage

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(...);