Skip to main content

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(root: TestRoot, view: impl IntoView) -> HeadlessHarness

Create a new headless harness with the given root view.

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

§Example
use floem::headless::{TestRoot, HeadlessHarness};
use floem::views::Empty;

let root = TestRoot::new();
let view = Empty::new().style(|s| s.size(100.0, 100.0));
let harness = HeadlessHarness::new(root, view);
Source

pub fn new_with_size( root: TestRoot, view: impl IntoView, width: f64, height: f64, ) -> HeadlessHarness

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

Use this when you need to create views before creating the harness.

§Example
use floem::headless::{TestRoot, HeadlessHarness};
use floem::views::Empty;

let root = TestRoot::new();
let view = Empty::new().style(|s| s.size(100.0, 100.0));
let harness = HeadlessHarness::new_with_size(root, view, 100.0, 100.0);
Source

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

Set the window size and rebuild layout.

Source

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

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_messages(&mut self)

process update messages

this can be used so that style requests can be integrated into the window state without restyling

Source

pub fn process_update_no_paint(&mut self)

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 window_id(&self) -> WindowId

Returns the winit::window::WindowId of the underlying headless window.

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 pointer_leave(&mut self) -> EventResult

Simulate a pointer leave window 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 element_id_at(&self, x: f64, y: f64) -> Option<ElementId>

Find the visual id at the given position (hit test).

Source

pub fn is_active(&self, id: impl Into<ElementId>) -> bool

Check if a view is currently in the “active” state active: pointer down and not up with the pointer in the element either by 1: remaining in or 2: returning into the element or keyboard trigger is down).

Source

pub fn is_hovered(&self, id: impl Into<ElementId>) -> bool

Check if a view is currently hovered.

Source

pub fn is_focused(&self, id: impl Into<ElementId>) -> bool

Check if a view is currently focused.

Source

pub fn has_capture(&self, id: impl Into<ElementId>) -> bool

Check if a view has pointer capture.

Source

pub fn get_interaction_state( &mut self, id: impl Into<ElementId>, ) -> 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. 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_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_view(&self, id: ViewId) -> Rc<RefCell<Box<dyn View>>>

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
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

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

§

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.
§

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.
§

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.
§

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

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. 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.
§

impl<T> Upcast<T> for T

§

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

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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