Skip to content

Commit

Permalink
Change Harness::run to run until no more repaints are requested (#5580
Browse files Browse the repository at this point in the history
)

Previously, `Harness::run` just called `Harness::step` 3 times. If that
wasn't enough, tests would often call run multiple times so all
animations would finish properly.

Also, I introduced `HarnessBuilder::with_step_dt` to customize with how
big of a dt each frame is called. I set the default to 1.0 / 6.0 (~6fps)
so we don't waste cpu in tests waiting on animations.

`HarnessBuilder::max_steps` allows us to control how many steps
`Harness::run` should run before panicing.
The default is 6, so we run for up to 1.0 logical seconds (six frames at
6 fps), which should be enough to finish most animations.

Turns out a lot of snapshots where rendered before fully shown and had a
light opacity, those are now fixed.

* [x] I have followed the instructions in the PR template
  • Loading branch information
lucasmerlin authored Jan 7, 2025
1 parent 3586041 commit 52060c0
Show file tree
Hide file tree
Showing 38 changed files with 230 additions and 97 deletions.
2 changes: 1 addition & 1 deletion crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ impl Context {
writer(&mut self.0.write())
}

/// Run the ui code for one 1.
/// Run the ui code for one frame.
///
/// At most [`Options::max_passes`] calls will be issued to `run_ui`,
/// and only on the rare occasion that [`Context::request_discard`] is called.
Expand Down
5 changes: 3 additions & 2 deletions crates/egui_demo_app/tests/test_demo_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn test_demo_app() {
// Load a local image where we know it exists and loads quickly
#[cfg(feature = "image_viewer")]
Anchor::ImageViewer => {
harness.run();
harness.step();

harness
.get_by_role_and_label(Role::TextInput, "URI:")
Expand All @@ -65,7 +65,8 @@ fn test_demo_app() {
_ => {}
}

harness.run();
// Can't use Harness::run because fractal clock keeps requesting repaints
harness.run_steps(2);

if let Err(e) = harness.try_snapshot(&anchor.to_string()) {
results.push(e);
Expand Down
2 changes: 1 addition & 1 deletion crates/egui_demo_lib/src/demo/demo_app_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ mod tests {
harness.set_size(Vec2::new(size.width as f32, size.height as f32));

// Run the app for some more frames...
harness.run();
harness.run_ok();

let mut options = SnapshotOptions::default();
// The Bézier Curve demo needs a threshold of 2.1 to pass on linux
Expand Down
22 changes: 7 additions & 15 deletions crates/egui_demo_lib/src/demo/modals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,13 @@ mod tests {

harness.get_by_role(Role::ComboBox).click();

harness.run();
// Harness::run would fail because we keep requesting repaints to simulate progress.
harness.run_ok();
assert!(harness.ctx.memory(|mem| mem.any_popup_open()));
assert!(harness.state().user_modal_open);

harness.press_key(Key::Escape);
harness.run();
harness.run_ok();
assert!(!harness.ctx.memory(|mem| mem.any_popup_open()));
assert!(harness.state().user_modal_open);
}
Expand Down Expand Up @@ -238,17 +239,11 @@ mod tests {
results.push(harness.try_snapshot("modals_1"));

harness.get_by_label("Save").click();
// TODO(lucasmerlin): Remove these extra runs once run checks for repaint requests
harness.run();
harness.run();
harness.run();
harness.run_ok();
results.push(harness.try_snapshot("modals_2"));

harness.get_by_label("Yes Please").click();
// TODO(lucasmerlin): Remove these extra runs once run checks for repaint requests
harness.run();
harness.run();
harness.run();
harness.run_ok();
results.push(harness.try_snapshot("modals_3"));

for result in results {
Expand All @@ -272,14 +267,11 @@ mod tests {
initial_state,
);

// TODO(lucasmerlin): Remove these extra runs once run checks for repaint requests
harness.run();
harness.run();
harness.run();
harness.run_ok();

harness.get_by_label("Yes Please").simulate_click();

harness.run();
harness.run_ok();

// This snapshots should show the progress bar modal on top of the save modal.
harness.snapshot("modals_backdrop_should_prevent_focusing_lower_area");
Expand Down
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Code Example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Font Book.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Modals.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Painting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Panels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Sliders.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Strip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/demos/Window Options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions crates/egui_demo_lib/tests/snapshots/modals_1.png
24 changes: 24 additions & 0 deletions crates/egui_kittest/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use std::marker::PhantomData;
pub struct HarnessBuilder<State = ()> {
pub(crate) screen_rect: Rect,
pub(crate) pixels_per_point: f32,
pub(crate) max_steps: u64,
pub(crate) step_dt: f32,
pub(crate) state: PhantomData<State>,
pub(crate) renderer: Box<dyn TestRenderer>,
}
Expand All @@ -19,6 +21,8 @@ impl<State> Default for HarnessBuilder<State> {
pixels_per_point: 1.0,
state: PhantomData,
renderer: Box::new(LazyRenderer::default()),
max_steps: 4,
step_dt: 1.0 / 4.0,
}
}
}
Expand All @@ -40,6 +44,26 @@ impl<State> HarnessBuilder<State> {
self
}

/// Set the maximum number of steps to run when calling [`Harness::run`].
///
/// Default is 4.
/// With the default `step_dt`, this means 1 second of simulation.
#[inline]
pub fn with_max_steps(mut self, max_steps: u64) -> Self {
self.max_steps = max_steps;
self
}

/// Set the time delta for a single [`Harness::step`].
///
/// Default is 1.0 / 4.0 (4fps).
/// The default is low so we don't waste cpu waiting for animations.
#[inline]
pub fn with_step_dt(mut self, step_dt: f32) -> Self {
self.step_dt = step_dt;
self
}

/// Set the [`TestRenderer`] to use for rendering.
///
/// By default, a [`LazyRenderer`] is used.
Expand Down
Loading

0 comments on commit 52060c0

Please sign in to comment.