mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 14:50:03 -04:00
Add Harness::new_eframe and TestRenderer trait (#5539)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
This commit is contained in:
@@ -93,3 +93,6 @@ rfd = { version = "0.15", optional = true }
|
||||
wasm-bindgen = "=0.2.95"
|
||||
wasm-bindgen-futures.workspace = true
|
||||
web-sys.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
egui_kittest = { workspace = true, features = ["eframe", "snapshot", "wgpu"] }
|
||||
@@ -54,8 +54,9 @@ impl eframe::App for ImageViewer {
|
||||
fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
|
||||
egui::TopBottomPanel::new(TopBottomSide::Top, "url bar").show(ctx, |ui| {
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.label("URI:");
|
||||
ui.text_edit_singleline(&mut self.uri_edit_text);
|
||||
let label = ui.label("URI:");
|
||||
ui.text_edit_singleline(&mut self.uri_edit_text)
|
||||
.labelled_by(label.id);
|
||||
if ui.small_button("✔").clicked() {
|
||||
ctx.forget_image(&self.current_uri);
|
||||
self.uri_edit_text = self.uri_edit_text.trim().to_owned();
|
||||
|
||||
@@ -6,7 +6,7 @@ mod backend_panel;
|
||||
mod frame_history;
|
||||
mod wrap_app;
|
||||
|
||||
pub use wrap_app::WrapApp;
|
||||
pub use wrap_app::{Anchor, WrapApp};
|
||||
|
||||
/// Time of day as seconds since midnight. Used for clock in demo app.
|
||||
pub(crate) fn seconds_since_midnight() -> f64 {
|
||||
|
||||
@@ -38,6 +38,7 @@ impl eframe::App for DemoApp {
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct FractalClockApp {
|
||||
fractal_clock: crate::apps::FractalClock,
|
||||
pub mock_time: Option<f64>,
|
||||
}
|
||||
|
||||
impl eframe::App for FractalClockApp {
|
||||
@@ -46,7 +47,7 @@ impl eframe::App for FractalClockApp {
|
||||
.frame(egui::Frame::dark_canvas(&ctx.style()))
|
||||
.show(ctx, |ui| {
|
||||
self.fractal_clock
|
||||
.ui(ui, Some(crate::seconds_since_midnight()));
|
||||
.ui(ui, self.mock_time.or(Some(crate::seconds_since_midnight())));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -77,7 +78,7 @@ impl eframe::App for ColorTestApp {
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
enum Anchor {
|
||||
pub enum Anchor {
|
||||
Demo,
|
||||
|
||||
EasyMarkEditor,
|
||||
@@ -161,7 +162,7 @@ pub struct State {
|
||||
http: crate::apps::HttpApp,
|
||||
#[cfg(feature = "image_viewer")]
|
||||
image_viewer: crate::apps::ImageViewer,
|
||||
clock: FractalClockApp,
|
||||
pub clock: FractalClockApp,
|
||||
rendering_test: ColorTestApp,
|
||||
|
||||
selected_anchor: Anchor,
|
||||
@@ -170,7 +171,7 @@ pub struct State {
|
||||
|
||||
/// Wraps many demo/test apps into one.
|
||||
pub struct WrapApp {
|
||||
state: State,
|
||||
pub state: State,
|
||||
|
||||
#[cfg(any(feature = "glow", feature = "wgpu"))]
|
||||
custom3d: Option<crate::apps::Custom3d>,
|
||||
@@ -203,7 +204,9 @@ impl WrapApp {
|
||||
slf
|
||||
}
|
||||
|
||||
fn apps_iter_mut(&mut self) -> impl Iterator<Item = (&str, Anchor, &mut dyn eframe::App)> {
|
||||
pub fn apps_iter_mut(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = (&'static str, Anchor, &mut dyn eframe::App)> {
|
||||
let mut vec = vec![
|
||||
(
|
||||
"✨ Demos",
|
||||
|
||||
3
crates/egui_demo_app/tests/snapshots/clock.png
Normal file
3
crates/egui_demo_app/tests/snapshots/clock.png
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c05cc3d48242e46a391af34cb56f72de7933bf2cead009b6cd477c21867a84e
|
||||
size 327802
|
||||
3
crates/egui_demo_app/tests/snapshots/custom3d.png
Normal file
3
crates/egui_demo_app/tests/snapshots/custom3d.png
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:61212e30fe1fecf5891ddad6ac795df510bfad76b21a7a8a13aa024fdad6d05e
|
||||
size 93118
|
||||
3
crates/egui_demo_app/tests/snapshots/easymarkeditor.png
Normal file
3
crates/egui_demo_app/tests/snapshots/easymarkeditor.png
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7bcf6e2977bed682d7bdaa0b6a6786e528662dd0791d2e6f83cf1b4852035838
|
||||
size 182833
|
||||
3
crates/egui_demo_app/tests/snapshots/imageviewer.png
Normal file
3
crates/egui_demo_app/tests/snapshots/imageviewer.png
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e6cc6ff64eb73ddac89ecdacd07c2176f3ab952c0db4593fccf6d11f155ec392
|
||||
size 103100
|
||||
78
crates/egui_demo_app/tests/test_demo_app.rs
Normal file
78
crates/egui_demo_app/tests/test_demo_app.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
use egui::accesskit::Role;
|
||||
use egui::Vec2;
|
||||
use egui_demo_app::{Anchor, WrapApp};
|
||||
use egui_kittest::kittest::Queryable;
|
||||
|
||||
#[test]
|
||||
fn test_demo_app() {
|
||||
let mut harness = egui_kittest::Harness::builder()
|
||||
.with_size(Vec2::new(900.0, 600.0))
|
||||
.wgpu()
|
||||
.build_eframe(|cc| WrapApp::new(cc));
|
||||
|
||||
let app = harness.state_mut();
|
||||
|
||||
// Mock the fractal clock time so snapshots are consistent.
|
||||
app.state.clock.mock_time = Some(36383.0);
|
||||
|
||||
let apps = app
|
||||
.apps_iter_mut()
|
||||
.map(|(name, anchor, _)| (name, anchor))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
#[cfg(feature = "wgpu")]
|
||||
assert!(
|
||||
apps.iter()
|
||||
.any(|(_, anchor)| matches!(anchor, Anchor::Custom3d)),
|
||||
"Expected to find the Custom3d app.",
|
||||
);
|
||||
|
||||
let mut results = vec![];
|
||||
|
||||
for (name, anchor) in apps {
|
||||
harness.get_by_role_and_label(Role::Button, name).click();
|
||||
|
||||
match anchor {
|
||||
// The widget gallery demo shows the current date, so we can't use it for snapshot testing
|
||||
Anchor::Demo => {
|
||||
continue;
|
||||
}
|
||||
// This is already tested extensively elsewhere
|
||||
Anchor::Rendering => {
|
||||
continue;
|
||||
}
|
||||
// We don't want to rely on a network connection for tests
|
||||
#[cfg(feature = "http")]
|
||||
Anchor::Http => {
|
||||
continue;
|
||||
}
|
||||
// Load a local image where we know it exists and loads quickly
|
||||
#[cfg(feature = "image_viewer")]
|
||||
Anchor::ImageViewer => {
|
||||
harness.run();
|
||||
|
||||
harness
|
||||
.get_by_role_and_label(Role::TextInput, "URI:")
|
||||
.focus();
|
||||
harness.press_key_modifiers(egui::Modifiers::COMMAND, egui::Key::A);
|
||||
|
||||
harness
|
||||
.get_by_role_and_label(Role::TextInput, "URI:")
|
||||
.type_text("file://../eframe/data/icon.png");
|
||||
|
||||
harness.get_by_role_and_label(Role::Button, "✔").click();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
harness.run();
|
||||
|
||||
if let Err(e) = harness.try_snapshot(&anchor.to_string()) {
|
||||
results.push(e);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(error) = results.first() {
|
||||
panic!("{error}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user