plushie/testing/backend
Test backend: record-of-functions defining backend capabilities.
The TestBackend type is a record of functions that implement
each testing operation (find, click, type_text, etc.). This
design lets tests be polymorphic over the backend: the same
test code runs at different fidelity levels.
Backend variants
- mock:
plushie-renderer --mockvia session pool. Protocol-only, no rendering. Default backend. - headless:
plushie-renderer --headlesswith software rendering. Supports screenshots and pixel assertions. - windowed:
plushie-rendererwith GPU rendering and visible windows.
See plushie/testing.gleam for backend selection via
PLUSHIE_TEST_BACKEND env var.
Types
Selector for finding elements.
pub type Selector {
ById(String)
ByRole(String)
ByLabel(String)
ByText(String)
Focused
InWindow(window_id: String, selector: Selector)
}
Constructors
-
ById(String)Match a widget by ID (local, scoped, or window-qualified).
-
ByRole(String)Match a widget by accessibility role.
-
ByLabel(String)Match a widget by accessibility label or content.
-
ByText(String)Match a widget by visible text content.
-
FocusedMatch the focused widget.
-
InWindow(window_id: String, selector: Selector)Scope any selector to a specific window subtree.
A test backend defined as a record of functions. Each function implements a specific testing operation.
pub type TestBackend(model) {
TestBackend(
start: fn(app.App(model, event.Event)) -> session.TestSession(
model,
),
stop: fn(session.TestSession(model)) -> Nil,
find: fn(session.TestSession(model), String) -> option.Option(
element.Element,
),
click: fn(session.TestSession(model), String) -> session.TestSession(
model,
),
type_text: fn(session.TestSession(model), String, String) -> session.TestSession(
model,
),
submit: fn(session.TestSession(model), String) -> session.TestSession(
model,
),
toggle: fn(session.TestSession(model), String) -> session.TestSession(
model,
),
select: fn(session.TestSession(model), String, String) -> session.TestSession(
model,
),
slide: fn(session.TestSession(model), String, Float) -> session.TestSession(
model,
),
press_key: fn(session.TestSession(model), String) -> session.TestSession(
model,
),
release_key: fn(session.TestSession(model), String) -> session.TestSession(
model,
),
type_key: fn(session.TestSession(model), String) -> session.TestSession(
model,
),
canvas_press: fn(
session.TestSession(model),
String,
Float,
Float,
) -> session.TestSession(model),
paste: fn(session.TestSession(model), String, String) -> session.TestSession(
model,
),
sort: fn(session.TestSession(model), String, String) -> session.TestSession(
model,
),
canvas_touch_press: fn(
session.TestSession(model),
String,
Float,
Float,
Int,
) -> session.TestSession(model),
canvas_touch_release: fn(
session.TestSession(model),
String,
Float,
Float,
Int,
) -> session.TestSession(model),
canvas_touch_move: fn(
session.TestSession(model),
String,
Float,
Float,
Int,
) -> session.TestSession(model),
model: fn(session.TestSession(model)) -> model,
tree: fn(session.TestSession(model)) -> node.Node,
reset: fn(session.TestSession(model)) -> session.TestSession(
model,
),
send_event: fn(session.TestSession(model), event.Event) -> session.TestSession(
model,
),
)
}
Constructors
-
TestBackend( start: fn(app.App(model, event.Event)) -> session.TestSession( model, ), stop: fn(session.TestSession(model)) -> Nil, find: fn(session.TestSession(model), String) -> option.Option( element.Element, ), click: fn(session.TestSession(model), String) -> session.TestSession( model, ), type_text: fn(session.TestSession(model), String, String) -> session.TestSession( model, ), submit: fn(session.TestSession(model), String) -> session.TestSession( model, ), toggle: fn(session.TestSession(model), String) -> session.TestSession( model, ), select: fn(session.TestSession(model), String, String) -> session.TestSession( model, ), slide: fn(session.TestSession(model), String, Float) -> session.TestSession( model, ), press_key: fn(session.TestSession(model), String) -> session.TestSession( model, ), release_key: fn(session.TestSession(model), String) -> session.TestSession( model, ), type_key: fn(session.TestSession(model), String) -> session.TestSession( model, ), canvas_press: fn( session.TestSession(model), String, Float, Float, ) -> session.TestSession(model), paste: fn(session.TestSession(model), String, String) -> session.TestSession( model, ), sort: fn(session.TestSession(model), String, String) -> session.TestSession( model, ), canvas_touch_press: fn( session.TestSession(model), String, Float, Float, Int, ) -> session.TestSession(model), canvas_touch_release: fn( session.TestSession(model), String, Float, Float, Int, ) -> session.TestSession(model), canvas_touch_move: fn( session.TestSession(model), String, Float, Float, Int, ) -> session.TestSession(model), model: fn(session.TestSession(model)) -> model, tree: fn(session.TestSession(model)) -> node.Node, reset: fn(session.TestSession(model)) -> session.TestSession( model, ), send_event: fn(session.TestSession(model), event.Event) -> session.TestSession( model, ), )
Values
pub fn parse_selector(input: String) -> Selector
Parse a selector from a unified string syntax.
Supported forms:
"form/email"or"#form/email"-> ById(“form/email”)"main#form/email"-> ById(“main#form/email”) (window-qualified ID)":focused"-> Focused"main#:focused"-> InWindow(“main”, Focused)"[role=button]"-> ByRole(“button”)"main#[text=Save]"-> InWindow(“main”, ByText(“Save”))
Plain strings without special prefixes are treated as ID selectors.