tree: 8c8f1592d1141fd6ecbe8a082596168b800aa528 [search]
  1. src/
  2. BUILD.bazel
  3. BUILD.gn
  4. METADATA.textproto
  5. OWNERS
  6. README.md
src/lib/ui/input-synthesis/README.md

Input synthesis

The input synthesis library supports input event injection for testing purposes.

Injection is performed by creating and registering a synthetic input device via the fuchsia.input.injection.InputDeviceRegistry FIDL protocol served by the Scene Manager component via the Input Pipeline library. It then uses that device to send InputReports to the input service, mimicking real user input on HID devices (e.g. touchscreens, media buttons, keyboards).

The library allows test code to send high-level commands that get converted into low-level input messages, without having to write the low-level commands directly. For example, it will convert a command Text.Send("hello") into a sequence of presses and releases of the keys h, e, l, l, and o in a rapid succession. Fuchsia platform's input handlers, and downstream UI clients, cannot distinguish these fake key presses from those typed up on a real keyboard.

Use the library in tests

Import the library

To use input_synthesis directly in tests written in Rust, first import the library in your test file and add it as a dependency in your test's BUILD file:

// my-test.rs
use input_synthesis;
# BUILD
rustc_test("factory_reset_handler_test") {
  sources = [ "my-test.rs" ]
  deps = [
    "//src/lib/ui/input-synthesis",
    # other deps
  ]
}

Implicit InputDeviceRegistry

You can then use the device registry to fire any input event supported in the library:

input_synthesis::text_command("hello world", /* key_event_duration */ 100).await?;

As an example reference, the sl4f Input command uses the library directly with an implicit InputDeviceRegistry based on the build argument.

Explicit InputDeviceRegistry

You can alternatively create a device registry using the preferred InputDeviceRegistry protocol by first connecting to it. The example below connects to the protocol the way an integration test would using a Realm Builder RealmInstance.

let injection_registry = realm.root
    .connect_to_protocol_at_exposed_dir::<fidl_fuchsia_input_injection::InputDeviceRegistryMarker>()
    .expect("Failed to connect to InputDeviceRegistry");
let mut device_registry =
    input_synthesis::modern_backend::InputDeviceRegistry::new(injection_registry);
input_synthesis::synthesizer::text(
    "hello world",
    /* key_event_duration */ 100,
    &mut device_registry,
)
.await?;

As an example reference, the factory-reset-handler test uses the library directly with a specific InputDeviceRegistry.