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 – swap
mock() for headless() or windowed() and the same test
code runs at different fidelity levels.
Backend variants
- mock(): pure Gleam, no renderer process. Runs the Elm loop directly. Fast, deterministic, no external dependencies. Best for unit-testing logic, tree structure, and model state.
- headless(): starts the Rust binary with
--headlessfor software rendering. Supports screenshots and pixel-level assertions. Requires the plushie binary on PATH or configured. - windowed(): starts the Rust binary with GPU rendering and a visible window. For manual visual verification and interactive debugging.
Concurrency
Mock backends are synchronous – each operation completes
immediately in the calling process. Headless and windowed
backends communicate with a renderer actor over OTP messages,
so operations involve a process.call with a timeout.
All backends are single-session; concurrent access to the
same session is not supported.
Types
Selector for finding elements: by ID string, by role, by label, or focused.
pub type Selector {
ById(String)
ByRole(String)
ByLabel(String)
Focused
}
Constructors
-
ById(String) -
ByRole(String) -
ByLabel(String) -
Focused
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,
event.Event,
),
stop: fn(session.TestSession(model, event.Event)) -> Nil,
find: fn(session.TestSession(model, event.Event), String) -> option.Option(
element.Element,
),
click: fn(session.TestSession(model, event.Event), String) -> session.TestSession(
model,
event.Event,
),
type_text: fn(
session.TestSession(model, event.Event),
String,
String,
) -> session.TestSession(model, event.Event),
submit: fn(session.TestSession(model, event.Event), String) -> session.TestSession(
model,
event.Event,
),
toggle: fn(session.TestSession(model, event.Event), String) -> session.TestSession(
model,
event.Event,
),
select: fn(
session.TestSession(model, event.Event),
String,
String,
) -> session.TestSession(model, event.Event),
slide: fn(
session.TestSession(model, event.Event),
String,
Float,
) -> session.TestSession(model, event.Event),
model: fn(session.TestSession(model, event.Event)) -> model,
tree: fn(session.TestSession(model, event.Event)) -> node.Node,
reset: fn(session.TestSession(model, event.Event)) -> session.TestSession(
model,
event.Event,
),
send_event: fn(
session.TestSession(model, event.Event),
event.Event,
) -> session.TestSession(model, event.Event),
)
}
Constructors
-
TestBackend( start: fn(app.App(model, event.Event)) -> session.TestSession( model, event.Event, ), stop: fn(session.TestSession(model, event.Event)) -> Nil, find: fn(session.TestSession(model, event.Event), String) -> option.Option( element.Element, ), click: fn(session.TestSession(model, event.Event), String) -> session.TestSession( model, event.Event, ), type_text: fn( session.TestSession(model, event.Event), String, String, ) -> session.TestSession(model, event.Event), submit: fn(session.TestSession(model, event.Event), String) -> session.TestSession( model, event.Event, ), toggle: fn(session.TestSession(model, event.Event), String) -> session.TestSession( model, event.Event, ), select: fn( session.TestSession(model, event.Event), String, String, ) -> session.TestSession(model, event.Event), slide: fn( session.TestSession(model, event.Event), String, Float, ) -> session.TestSession(model, event.Event), model: fn(session.TestSession(model, event.Event)) -> model, tree: fn(session.TestSession(model, event.Event)) -> node.Node, reset: fn(session.TestSession(model, event.Event)) -> session.TestSession( model, event.Event, ), send_event: fn( session.TestSession(model, event.Event), event.Event, ) -> session.TestSession(model, event.Event), )
Values
pub fn mock() -> TestBackend(model)
Create a mock backend using the existing functional test session. This is the default backend: pure Gleam, no renderer needed.