Skip to content

Add tests for layout and visuals of most egui widgets #6752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 16, 2025
Merged
10 changes: 10 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,16 @@ dependencies = [
"wgpu",
]

[[package]]
name = "egui_tests"
version = "0.31.1"
dependencies = [
"egui",
"egui_extras",
"egui_kittest",
"image",
]

[[package]]
name = "ehttp"
version = "0.5.0"
Expand Down
64 changes: 48 additions & 16 deletions crates/egui_kittest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ impl<'a, State> Harness<'a, State> {
///
/// See also:
/// - [`Harness::try_run`].
/// - [`Harness::try_run_realtime`].
/// - [`Harness::run_ok`].
/// - [`Harness::step`].
/// - [`Harness::run_steps`].
Expand All @@ -287,29 +288,16 @@ impl<'a, State> Harness<'a, State> {
}
}

/// Run until
/// - all animations are done
/// - no more repaints are requested
/// - the maximum number of steps is reached (See [`HarnessBuilder::with_max_steps`])
///
/// Returns the number of steps that were run.
///
/// # Errors
/// Returns an error if the maximum number of steps is exceeded.
///
/// See also:
/// - [`Harness::run`].
/// - [`Harness::run_ok`].
/// - [`Harness::step`].
/// - [`Harness::run_steps`].
pub fn try_run(&mut self) -> Result<u64, ExceededMaxStepsError> {
fn _try_run(&mut self, sleep: bool) -> Result<u64, ExceededMaxStepsError> {
let mut steps = 0;
loop {
steps += 1;
self.step();
// We only care about immediate repaints
if self.root_viewport_output().repaint_delay != Duration::ZERO {
break;
} else if sleep {
std::thread::sleep(Duration::from_secs_f32(self.step_dt));
}
if steps > self.max_steps {
return Err(ExceededMaxStepsError {
Expand All @@ -321,6 +309,26 @@ impl<'a, State> Harness<'a, State> {
Ok(steps)
}

/// Run until
/// - all animations are done
/// - no more repaints are requested
/// - the maximum number of steps is reached (See [`HarnessBuilder::with_max_steps`])
///
/// Returns the number of steps that were run.
///
/// # Errors
/// Returns an error if the maximum number of steps is exceeded.
///
/// See also:
/// - [`Harness::run`].
/// - [`Harness::run_ok`].
/// - [`Harness::step`].
/// - [`Harness::run_steps`].
/// - [`Harness::try_run_realtime`].
pub fn try_run(&mut self) -> Result<u64, ExceededMaxStepsError> {
self._try_run(false)
}

/// Run until
/// - all animations are done
/// - no more repaints are requested
Expand All @@ -333,10 +341,34 @@ impl<'a, State> Harness<'a, State> {
/// - [`Harness::try_run`].
/// - [`Harness::step`].
/// - [`Harness::run_steps`].
/// - [`Harness::try_run_realtime`].
pub fn run_ok(&mut self) -> Option<u64> {
self.try_run().ok()
}

/// Run multiple frames, sleeping for [`HarnessBuilder::with_step_dt`] between frames.
///
/// This is useful to e.g. wait for an async operation to complete (e.g. loading of images).
/// Runs until
/// - all animations are done
/// - no more repaints are requested
/// - the maximum number of steps is reached (See [`HarnessBuilder::with_max_steps`])
///
/// Returns the number of steps that were run.
///
/// # Errors
/// Returns an error if the maximum number of steps is exceeded.
///
/// See also:
/// - [`Harness::run`].
/// - [`Harness::run_ok`].
/// - [`Harness::step`].
/// - [`Harness::run_steps`].
/// - [`Harness::try_run`].
pub fn try_run_realtime(&mut self) -> Result<u64, ExceededMaxStepsError> {
self._try_run(true)
}

/// Run a number of steps.
/// Equivalent to calling [`Harness::step`] x times.
pub fn run_steps(&mut self, steps: usize) {
Expand Down
15 changes: 15 additions & 0 deletions tests/egui_tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "egui_tests"
edition.workspace = true
license.workspace = true
rust-version.workspace = true
version.workspace = true

[dev-dependencies]
egui = { workspace = true, default-features = true }
egui_kittest = { workspace = true, features = ["snapshot", "wgpu"] }
egui_extras = { workspace = true, features = ["image"]}
image = { workspace = true, features = ["png"] }

[lints]
workspace = true
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/button_image.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.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/checkbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/checkbox_checked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/drag_value.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/radio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/radio_checked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/selectable_value.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.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/slider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/layout/text_edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/button_image.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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/checkbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/checkbox_checked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/drag_value.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/radio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/radio_checked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/selectable_value.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.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/slider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/egui_tests/tests/snapshots/visuals/text_edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading