HeadlessHarness

Struct HeadlessHarness 

Source
pub struct HeadlessHarness { /* private fields */ }
Expand description

A headless harness for UI testing and benchmarking.

HeadlessHarness manages a view tree and provides methods to simulate user interactions without creating an actual window.

Internally, it uses a headless WindowHandle to ensure behavior matches real window behavior, including the full process_update() cycle for style recalculation and layout.

Implementations§

Source§

impl HeadlessHarness

Source

pub fn new(view: impl IntoView) -> Self

Create a new headless harness with the given root view.

The view will be set up with default size (800x600) and scale (1.0).

Source

pub fn new_with_size(view: impl IntoView, width: f64, height: f64) -> Self

Create a new headless harness with the given root view and window size.

Source

pub fn set_size(&mut self, width: f64, height: f64) -> &mut Self

Set the window size and rebuild layout.

Source

pub fn set_scale(&mut self, scale: f64) -> &mut Self

Set the window scale factor.

Source

pub fn rebuild(&mut self)

Run all passes: style → layout → compute_layout.

This must be called after any changes to view styles or structure for events to be dispatched correctly.

Note: When using the headless WindowHandle, this is typically called automatically via process_update_no_paint() after event dispatch.

Source

pub fn process_update_no_paint(&mut self) -> bool

Run pending reactive effects and process all updates.

Returns true if a repaint would be scheduled (style or layout changed). This is the return value from the underlying WindowHandle::process_update_no_paint().

Use this method when you need to verify that style/layout changes trigger repaints:

signal.set(new_value);
let needs_repaint = harness.process_update_no_paint();
assert!(needs_repaint, "Style change should trigger repaint");
Source

pub fn root_id(&self) -> ViewId

Get the root view ID.

Source

pub fn dispatch_event(&mut self, event: Event) -> EventResult

Dispatch an event to the view tree.

This uses the full WindowHandle event dispatch and processing, including the process_update() cycle that handles:

  • Update messages
  • Style recalculation
  • Layout passes
Source

pub fn pointer_down(&mut self, x: f64, y: f64) -> EventResult

Simulate a pointer down event at the given position.

Source

pub fn pointer_up(&mut self, x: f64, y: f64) -> EventResult

Simulate a pointer up event at the given position.

Source

pub fn pointer_move(&mut self, x: f64, y: f64) -> EventResult

Simulate a pointer move event to the given position.

Source

pub fn click(&mut self, x: f64, y: f64) -> EventResult

Simulate a click (pointer down + pointer up) at the given position.

Source

pub fn double_click(&mut self, x: f64, y: f64) -> EventResult

Simulate a double click at the given position.

Source

pub fn secondary_click(&mut self, x: f64, y: f64) -> EventResult

Simulate a secondary (right) click at the given position.

Source

pub fn touch_down(&mut self, x: f64, y: f64) -> EventResult

Simulate a touch down event at the given position.

Touch pointers automatically get implicit capture per W3C Pointer Events spec.

Source

pub fn touch_up(&mut self, x: f64, y: f64) -> EventResult

Simulate a touch up event at the given position.

Source

pub fn touch_move(&mut self, x: f64, y: f64) -> EventResult

Simulate a touch move event to the given position.

Source

pub fn tap(&mut self, x: f64, y: f64) -> EventResult

Simulate a tap (touch down + touch up) at the given position.

Source

pub fn scroll( &mut self, x: f64, y: f64, delta_x: f64, delta_y: f64, ) -> EventResult

Simulate a scroll wheel event at the given position.

delta_x and delta_y are the scroll amounts in pixels. These are raw scroll deltas - the scroll view negates them internally. Typically: negative delta_y = scroll down (see lower content).

Source

pub fn scroll_down(&mut self, x: f64, y: f64, amount: f64) -> EventResult

Simulate scrolling down (to see lower content).

amount is how many pixels to scroll down (positive value).

Source

pub fn scroll_up(&mut self, x: f64, y: f64, amount: f64) -> EventResult

Simulate scrolling up (to see higher content).

amount is how many pixels to scroll up (positive value).

Source

pub fn scroll_right(&mut self, x: f64, y: f64, amount: f64) -> EventResult

Simulate scrolling right (to see content further right).

amount is how many pixels to scroll right (positive value).

Source

pub fn scroll_left(&mut self, x: f64, y: f64, amount: f64) -> EventResult

Simulate scrolling left (to see content further left).

amount is how many pixels to scroll left (positive value).

Source

pub fn scroll_lines( &mut self, x: f64, y: f64, lines_x: f32, lines_y: f32, ) -> EventResult

Simulate a line-based scroll wheel event at the given position.

lines_x and lines_y are the number of lines to scroll. This is converted to pixel delta using a default line height of 20 pixels.

Source

pub fn view_at(&self, x: f64, y: f64) -> Option<ViewId>

Find the view at the given position (hit test).

Source

pub fn is_clicking(&self, id: ViewId) -> bool

Check if a view is currently in the “clicking” state (pointer down but not up).

Source

pub fn is_hovered(&self, id: ViewId) -> bool

Check if a view is currently hovered.

Source

pub fn is_focused(&self, id: ViewId) -> bool

Check if a view is currently focused.

Source

pub fn is_active(&self, id: ViewId) -> bool

Check if a view is currently active.

Source

pub fn get_interaction_state(&self, id: ViewId) -> InteractionState

Get the current interaction state for a view.

This returns the same state used during style computation to determine which style selectors (hover, active, focused, etc.) apply to the view.

Source

pub fn has_style_for_selector( &mut self, id: ViewId, selector: StyleSelector, ) -> bool

Check if a view has styles defined for the given selector.

For example, has_style_for_selector(id, StyleSelector::Active) returns true if the view has an :active style defined.

Source

pub fn get_computed_style(&self, id: ViewId) -> Style

Get the computed style for a view.

This returns a clone of the fully computed style after all style passes have run. Use this to verify that style changes (e.g., from :active or :hover selectors) are being applied correctly.

§Example
use floem::style::Background;

harness.pointer_down(50.0, 50.0);
let style = harness.get_computed_style(id);
let bg = style.get(Background);
assert!(bg.is_some(), "Background should be set when :active");
Source

pub fn recompute_styles(&mut self)

Trigger a style recalculation pass.

This runs the full process_update cycle which includes style recalculation. With the headless WindowHandle, this is typically called automatically after event dispatch, but can be called manually if needed.

Source

pub fn process_pointer_up_styles(&mut self)

Request style recalculation for views with Active selector, then recompute.

This simulates the full pointer-up flow:

  1. Request style update for views with Active selector
  2. Clear clicking state
  3. Run style recalculation via process_update
Source

pub fn paint_requested(&self) -> bool

Check if a repaint was requested.

This is useful for verifying that style changes trigger repaints.

Source

pub fn clear_paint_request(&mut self)

Clear the paint request flag.

Call this before an operation to then check if it triggered a repaint.

Source

pub fn has_pending_style_change(&self, id: ViewId) -> bool

Check if a view has pending style changes.

Source

pub fn has_scheduled_updates(&self) -> bool

Check if there are scheduled updates for the next frame.

This is useful for testing transitions, which schedule style updates to animate across frames.

Source

pub fn is_style_dirty(&self, id: ViewId) -> bool

Check if a view is in the style_dirty set.

Views in this set will be processed during the next style pass.

Source

pub fn get_viewport(&self, id: ViewId) -> Option<Rect>

Get the viewport rectangle for a view, if one is set.

This is typically set on children of scroll views to indicate which portion of the child is currently visible.

Source

pub fn get_layout_rect(&self, id: ViewId) -> Rect

Get the layout rectangle for a view.

This is the rectangle in window coordinates where the view is positioned.

Source

pub fn get_size(&self, id: ViewId) -> Option<Size>

Get the size of a view from its layout.

Source

pub fn get_content_rect(&self, id: ViewId) -> Rect

Get the content rectangle for a view (excluding padding/borders).

Source

pub fn paint_and_get_order(&mut self) -> Vec<ViewId>

Paint the view tree and record the order in which views are painted.

This enables paint order tracking, paints the entire view tree (including overlays), and returns the list of ViewIds in the order they were painted.

§Example
let paint_order = harness.paint_and_get_order();
// Views are painted from back to front (lowest z-index first)
// Regular views paint first, then overlays
Source

pub fn enable_paint_tracking(&mut self)

Enable paint order tracking for subsequent paint operations.

Call this before operations that trigger painting, then use get_paint_order() to retrieve the recorded order.

Source

pub fn disable_paint_tracking(&mut self)

Disable paint order tracking.

Source

pub fn clear_paint_order(&mut self)

Clear the recorded paint order without disabling tracking.

Source

pub fn get_paint_order(&self) -> Vec<ViewId>

Get the recorded paint order from the most recent paint operation.

Returns the list of ViewIds in the order they were painted (from back to front).

Source

pub fn paint(&mut self)

Trigger a paint operation (without returning the image).

This runs the full paint cycle including overlays and drag overlay. Use with enable_paint_tracking() and get_paint_order() to verify paint order.

Trait Implementations§

Source§

impl Drop for HeadlessHarness

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

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<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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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> 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
Source§

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

Source§

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