Skip to main content

Harness

Struct Harness 

Source
pub struct Harness<A: App> { /* private fields */ }
Expand description

A headless app under test. See the module docs for the model.

Implementations§

Source§

impl<A: App> Harness<A>
where A::Msg: Send,

Source

pub fn new(app: A, theme: Theme, size: (u32, u32)) -> Self

Builds the first frame. App::init runs with a collecting Proxy; proxied messages drain at every rebuild (after each input, Self::pump, or Self::update).

§Panics

If no compute-capable GPU adapter exists.

Source

pub fn rebuild(&mut self)

Rebuilds every window from current app state (proxied messages drain first) and reconciles the declared window set: new keys open, missing keys close (the active window falls back to main). Runs automatically after every input; call it yourself only after mutating via Self::app_mut.

Source

pub fn set_reduced_motion(&mut self, reduced: bool)

Enables or disables real animation. The harness defaults to reduced motion (everything snaps — deterministic pixels); motion tests opt into physics and drive it with Self::pump.

Source

pub fn activate_window(&mut self, key: &str)

Switches which window the verbs and queries target. Open windows come from App::windows; MAIN_WINDOW is always open.

§Panics

If no open window has this key (the message lists the open ones).

Source

pub fn resize(&mut self, key: &str, width: u32, height: u32)

Resizes one window: clamps to the renderer’s limits, updates the slot’s pixel and logical size, and rebuilds its frame via App::view_at at the new size — the headless analogue of dragging a window edge, and how view_at window breakpoints and responsive container queries are driven. Other windows are untouched.

§Panics

If no open window has this key.

Source

pub fn window_keys(&self) -> Vec<String>

The keys of every open window, sorted (main first).

Source

pub fn input(&mut self, event: InputEvent)

Dispatches one raw input event against the active window’s current frame, logs and applies the emitted messages, and rebuilds (which also reconciles the window set).

Source

pub fn hover(&mut self, q: &Query)

Moves the pointer to the center of the matched node.

§Panics

If the query matches zero or several nodes.

Source

pub fn click(&mut self, q: &Query)

Clicks (press + release) the center of the matched node.

§Panics

If the query matches zero or several nodes.

Source

pub fn right_click(&mut self, q: &Query)

Right-clicks the center of the matched node.

§Panics

If the query matches zero or several nodes.

Source

pub fn double_click(&mut self, q: &Query)

Double-clicks the matched node (two clicks inside the double-click window — the harness clock does not advance).

§Panics

If the query matches zero or several nodes.

Source

pub fn triple_click(&mut self, q: &Query)

Triple-clicks the matched node (text inputs select the line).

§Panics

If the query matches zero or several nodes.

Source

pub fn shift_click(&mut self, q: &Query)

Clicks with Shift held (text inputs extend the selection from the caret to the click point).

§Panics

If the query matches zero or several nodes.

Source

pub fn type_text(&mut self, text: impl Into<String>)

Commits text to the focused element (like typing or IME commit).

Source

pub fn key(&mut self, key: KeyInput)

Presses one key.

Source

pub fn tab(&mut self)

Focuses the next focusable element (Tab).

Source

pub fn shift_tab(&mut self)

Focuses the previous focusable element (Shift-Tab).

Source

pub fn focus(&mut self, q: &Query)

Focuses the matched node directly (what assistive technology’s Focus action does). Prefer Self::tab to test the real path.

§Panics

If the query matches zero or several nodes.

Source

pub fn drag(&mut self, from: &Query, to: &Query)

Drags from one node to another: press on from, move to to (recomputed after the press, in case layout shifted), release.

§Panics

If either query matches zero or several nodes.

Source

pub fn drop_file(&mut self, q: &Query, path: impl Into<PathBuf>)

Drops an OS file onto the matched node.

§Panics

If the query matches zero or several nodes.

Source

pub fn wheel(&mut self, q: &Query, dy: f32)

Scrolls the wheel over the matched node (positive dy moves content down, winit convention).

§Panics

If the query matches zero or several nodes.

Source

pub fn wheel_xy(&mut self, q: &Query, dx: f32, dy: f32)

Scrolls the wheel on both axes over the matched node (positive dx moves content right, positive dy moves content down).

§Panics

If the query matches zero or several nodes.

Source

pub fn pump(&mut self, ms: f64)

Advances the deterministic clock by ms milliseconds and rebuilds — animations and timers move exactly this far.

Source

pub fn update(&mut self, msg: A::Msg)

Applies one message directly (as a proxy or window event would) and rebuilds. Not logged in Self::take_messages.

Source

pub fn get(&self, q: &Query) -> AccessNode

The single matching node; panics (with the accessibility tree in the message) on zero or several matches.

§Panics

If the query matches zero or several nodes.

Source

pub fn query(&self, q: &Query) -> Option<AccessNode>

The single matching node, or None. Use to assert absence.

§Panics

If the query matches several nodes.

Source

pub fn get_all(&self, q: &Query) -> Vec<AccessNode>

Every matching node in tree order.

Source

pub fn take_messages(&mut self) -> Vec<A::Msg>

Messages emitted by handlers since the last call (the Elm-level assertion: what the UI said, independent of state effects). Proxied and Self::update messages are inputs, not logged.

Source

pub fn frame(&self) -> &Frame

The active window’s current frame, for direct queries and access_yaml().

Source

pub fn app(&self) -> &A

The app under test.

Source

pub fn app_mut(&mut self) -> &mut A

Mutable access to the app; call Self::rebuild afterwards.

Source

pub fn render(&mut self) -> RgbaImage

Renders the active window to pixels. Mid-test captures are fine — the frame is not consumed.

§Panics

If rendering fails.

Source

pub fn render_window(&mut self, key: &str) -> RgbaImage

Renders any open window to pixels.

§Panics

If no open window has this key, or rendering fails.

Source

pub fn film(&mut self, frames: usize, interval_ms: u64) -> Vec<RgbaImage>

Captures frames renders of the active window, interval_ms apart on the deterministic clock: the first frame is the window exactly as it stands now, then Self::pump and Self::render repeat — so film(3, 100) returns the states at +0ms, +100ms, +200ms.

Self::new defaults every harness to reduced motion, the same default every other verification path relies on so single-shot goldens stay stable — under it every transition snaps to its target immediately, so a filmstrip captured without changing that is frames copies of the same pixels. Call Self::set_reduced_motion(false) first to see real motion play; determinism still holds, because it comes from the clock (advanced only by Self::pump), never from suppressing animation.

frames is floored at 1 and clamped to MAX_FILM_FRAMES; interval_ms is clamped to MAX_FILM_INTERVAL_MS (see their docs).

§Panics

If rendering fails (see Self::render).

Auto Trait Implementations§

§

impl<A> !RefUnwindSafe for Harness<A>

§

impl<A> !Send for Harness<A>

§

impl<A> !Sync for Harness<A>

§

impl<A> !UnwindSafe for Harness<A>

§

impl<A> Freeze for Harness<A>
where A: Freeze,

§

impl<A> Unpin for Harness<A>
where A: Unpin, <A as App>::Msg: Unpin,

§

impl<A> UnsafeUnpin for Harness<A>
where A: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more