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
impl HeadlessHarness
Sourcepub fn new(view: impl IntoView) -> Self
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).
Sourcepub fn new_with_size(view: impl IntoView, width: f64, height: f64) -> Self
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.
Sourcepub fn set_size(&mut self, width: f64, height: f64) -> &mut Self
pub fn set_size(&mut self, width: f64, height: f64) -> &mut Self
Set the window size and rebuild layout.
Sourcepub fn rebuild(&mut self)
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.
Sourcepub fn process_update_no_paint(&mut self) -> bool
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");Sourcepub fn dispatch_event(&mut self, event: Event) -> EventResult
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
Sourcepub fn pointer_down(&mut self, x: f64, y: f64) -> EventResult
pub fn pointer_down(&mut self, x: f64, y: f64) -> EventResult
Simulate a pointer down event at the given position.
Sourcepub fn pointer_up(&mut self, x: f64, y: f64) -> EventResult
pub fn pointer_up(&mut self, x: f64, y: f64) -> EventResult
Simulate a pointer up event at the given position.
Sourcepub fn pointer_move(&mut self, x: f64, y: f64) -> EventResult
pub fn pointer_move(&mut self, x: f64, y: f64) -> EventResult
Simulate a pointer move event to the given position.
Sourcepub fn click(&mut self, x: f64, y: f64) -> EventResult
pub fn click(&mut self, x: f64, y: f64) -> EventResult
Simulate a click (pointer down + pointer up) at the given position.
Sourcepub fn double_click(&mut self, x: f64, y: f64) -> EventResult
pub fn double_click(&mut self, x: f64, y: f64) -> EventResult
Simulate a double click at the given position.
Sourcepub fn secondary_click(&mut self, x: f64, y: f64) -> EventResult
pub fn secondary_click(&mut self, x: f64, y: f64) -> EventResult
Simulate a secondary (right) click at the given position.
Sourcepub fn touch_down(&mut self, x: f64, y: f64) -> EventResult
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.
Sourcepub fn touch_up(&mut self, x: f64, y: f64) -> EventResult
pub fn touch_up(&mut self, x: f64, y: f64) -> EventResult
Simulate a touch up event at the given position.
Sourcepub fn touch_move(&mut self, x: f64, y: f64) -> EventResult
pub fn touch_move(&mut self, x: f64, y: f64) -> EventResult
Simulate a touch move event to the given position.
Sourcepub fn tap(&mut self, x: f64, y: f64) -> EventResult
pub fn tap(&mut self, x: f64, y: f64) -> EventResult
Simulate a tap (touch down + touch up) at the given position.
Sourcepub fn scroll(
&mut self,
x: f64,
y: f64,
delta_x: f64,
delta_y: f64,
) -> EventResult
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).
Sourcepub fn scroll_down(&mut self, x: f64, y: f64, amount: f64) -> EventResult
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).
Sourcepub fn scroll_up(&mut self, x: f64, y: f64, amount: f64) -> EventResult
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).
Sourcepub fn scroll_right(&mut self, x: f64, y: f64, amount: f64) -> EventResult
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).
Sourcepub fn scroll_left(&mut self, x: f64, y: f64, amount: f64) -> EventResult
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).
Sourcepub fn scroll_lines(
&mut self,
x: f64,
y: f64,
lines_x: f32,
lines_y: f32,
) -> EventResult
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.
Sourcepub fn view_at(&self, x: f64, y: f64) -> Option<ViewId>
pub fn view_at(&self, x: f64, y: f64) -> Option<ViewId>
Find the view at the given position (hit test).
Sourcepub fn is_clicking(&self, id: ViewId) -> bool
pub fn is_clicking(&self, id: ViewId) -> bool
Check if a view is currently in the “clicking” state (pointer down but not up).
Sourcepub fn is_hovered(&self, id: ViewId) -> bool
pub fn is_hovered(&self, id: ViewId) -> bool
Check if a view is currently hovered.
Sourcepub fn is_focused(&self, id: ViewId) -> bool
pub fn is_focused(&self, id: ViewId) -> bool
Check if a view is currently focused.
Sourcepub fn get_interaction_state(&self, id: ViewId) -> InteractionState
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.
Sourcepub fn has_style_for_selector(
&mut self,
id: ViewId,
selector: StyleSelector,
) -> bool
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.
Sourcepub fn get_computed_style(&self, id: ViewId) -> Style
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");Sourcepub fn recompute_styles(&mut self)
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.
Sourcepub fn process_pointer_up_styles(&mut self)
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:
- Request style update for views with Active selector
- Clear clicking state
- Run style recalculation via process_update
Sourcepub fn paint_requested(&self) -> bool
pub fn paint_requested(&self) -> bool
Check if a repaint was requested.
This is useful for verifying that style changes trigger repaints.
Sourcepub fn clear_paint_request(&mut self)
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.
Sourcepub fn has_pending_style_change(&self, id: ViewId) -> bool
pub fn has_pending_style_change(&self, id: ViewId) -> bool
Check if a view has pending style changes.
Sourcepub fn has_scheduled_updates(&self) -> bool
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.
Sourcepub fn is_style_dirty(&self, id: ViewId) -> bool
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.
Sourcepub fn get_viewport(&self, id: ViewId) -> Option<Rect>
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.
Sourcepub fn get_layout_rect(&self, id: ViewId) -> Rect
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.
Sourcepub fn get_content_rect(&self, id: ViewId) -> Rect
pub fn get_content_rect(&self, id: ViewId) -> Rect
Get the content rectangle for a view (excluding padding/borders).
Sourcepub fn paint_and_get_order(&mut self) -> Vec<ViewId>
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 overlaysSourcepub fn enable_paint_tracking(&mut self)
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.
Sourcepub fn disable_paint_tracking(&mut self)
pub fn disable_paint_tracking(&mut self)
Disable paint order tracking.
Sourcepub fn clear_paint_order(&mut self)
pub fn clear_paint_order(&mut self)
Clear the recorded paint order without disabling tracking.
Sourcepub fn get_paint_order(&self) -> Vec<ViewId>
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).
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for HeadlessHarness
impl !RefUnwindSafe for HeadlessHarness
impl !Send for HeadlessHarness
impl !Sync for HeadlessHarness
impl Unpin for HeadlessHarness
impl !UnwindSafe for HeadlessHarness
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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