fission-test-driver 0.2.0

Live app testing client and protocol helpers for Fission shells
Documentation

fission-test-driver

Automated UI testing client and protocol for Fission applications.

This crate provides both the JSON protocol types (shared between the test client and the desktop shell server) and a LiveTestClient that drives a running Fission application over HTTP.

Architecture

Test process                        Application process
+-----------------+                 +-------------------------+
| LiveTestClient  | ---HTTP/JSON--> | test_control server     |
|   .tap(x, y)    |                 |   (fission-shell-desktop)|
|   .type_text()  |                 |   dispatches to Runtime |
|   .screenshot() | <--HTTP/JSON--- |   returns TestResponse  |
+-----------------+                 +-------------------------+

The application must be launched with FISSION_TEST_CONTROL_PORT=<port> to enable the test control server. The LiveTestClient connects to http://127.0.0.1:<port> and sends TestCommand JSON payloads to /cmd.

Protocol types

TestCommand

All commands are serialized with #[serde(tag = "cmd")]:

Command Fields Description
Tap x: f32, y: f32 Simulate a pointer down + up at the given logical coordinates.
TapText text: String Find visible text matching the string and tap its center.
Scroll x, y, dx, dy: f32 Simulate a scroll event at logical position (x, y) with logical delta (dx, dy).
TypeText text: String Type each character as a keyboard event into the focused input.
PressKey key: String, modifiers: u8 Press a named key (e.g., "Enter", "Escape", "Tab", "a") with modifier flags.
Screenshot path: String Capture the current frame to a PNG file at the given path. The PNG dimensions are in logical test-space pixels so they align with GetText / GetTree coordinates.
GetText (none) Return all visible text items with bounding rects in logical test-space pixels.
GetTree (none) Return the semantic accessibility tree with bounds in logical test-space pixels.
Wait ms: u64 Sleep for the given duration (server-side).
Pump (none) Force a frame render and wait for it to complete.
Quit (none) Exit the application.
SimulateResize width: u32, height: u32 Resize the test viewport to the given logical size.

TestResponse

Variant Fields Description
Ok (none) Command succeeded.
Text items: Vec<TextItem> Response to GetText.
Tree nodes: Vec<SemanticNode> Response to GetTree.
Error message: String Command failed with a reason.

TextItem

pub struct TextItem {
    pub text: String,
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
}

All geometry in TextItem is reported in logical test-space pixels.

SemanticNode

pub struct SemanticNode {
    pub role: String,       // e.g., "Button", "TextInput", "Generic"
    pub label: Option<String>,
    pub value: Option<String>,
    pub focusable: bool,
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
}

All geometry in SemanticNode is reported in logical test-space pixels.

LiveTestClient

The client provides both low-level command methods and high-level convenience helpers.

Connection

use fission_test_driver::LiveTestClient;

let client = LiveTestClient::connect(9876);
client.wait_for_ready(5000)?; // Wait up to 5s for the app to start

Low-level methods

Method Description
tap(x, y) Tap at coordinates.
tap_text(text) Find and tap text (pumps before and after).
scroll(x, y, dx, dy) Scroll at coordinates.
type_text(text) Type characters into the focused input.
press_key(key, modifiers) Press a key with modifiers (pumps after).
screenshot(path) Save a screenshot PNG.
get_text() Get all visible text items.
get_tree() Get the semantic tree.
wait(ms) Server-side sleep.
pump() Force a frame and wait for completion.
quit() Exit the application.

High-level helpers

Method Description
tap_text_and_wait(text, ms) Tap text then wait.
assert_text_visible(needle) Assert that text containing needle is on screen.
assert_text_not_visible(needle) Assert that text containing needle is not on screen.

Usage example

use fission_test_driver::LiveTestClient;

#[test]
fn test_login_flow() {
    let client = LiveTestClient::connect(9876);
    client.wait_for_ready(10_000).unwrap();

    // Type into the email field
    client.tap_text("Email").unwrap();
    client.type_text("user@example.com").unwrap();
    client.pump().unwrap();

    // Click the login button
    client.tap_text("Log In").unwrap();

    // Verify navigation
    client.assert_text_visible("Dashboard").unwrap();
    client.assert_text_not_visible("Log In").unwrap();

    // Take a screenshot for visual regression
    client.screenshot("/tmp/dashboard.png").unwrap();

    client.quit().unwrap();
}

Modifier flags

The modifiers parameter is a bitmask:

Bit Modifier
0x01 Shift
0x02 Alt/Option
0x04 Control
0x08 Super/Command