### Example: Building a Basic Harness with Context (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Shows how to build a basic egui test harness using a context-based closure. This example configures the harness size and provides a simple UI with a label, demonstrating the setup for testing egui components. ```rust # use egui::CentralPanel; # use egui_kittest::{Harness, kittest::Queryable}; let mut harness = Harness::builder() .with_size(egui::Vec2::new(300.0, 200.0)) .build(|ctx| { CentralPanel::default().show(ctx, |ui| { ui.label("Hello, world!"); }); }); ``` -------------------------------- ### Create New Harness with UI Closure in egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Initializes a `Harness` instance using a UI closure, which is immediately executed to create the initial UI. This method is suitable for simpler cases where only direct UI elements need to be defined, without the need for creating separate windows or panels. For more complex setups or UI customization, `Harness::builder` is recommended. ```rust pub fn new_ui(app: impl FnMut(&mut egui::Ui) + 'a) -> Self { Self::builder().build_ui(app) } ``` -------------------------------- ### Example: Testing egui Checkbox with Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Demonstrates how to use the `Harness::new_state` method to create a test environment for an egui application. It shows how to interact with UI elements like checkboxes and assert the final state of the application. ```rust # use egui::CentralPanel; # use egui_kittest::{Harness, kittest::Queryable}; let mut checked = false; let mut harness = Harness::new_state(|ctx, checked| { CentralPanel::default().show(ctx, |ui| { ui.checkbox(checked, "Check me!"); }); }, checked); harness.get_by_label("Check me!").click(); harness.run(); assert_eq!(*harness.state(), true); ``` -------------------------------- ### WgpuTestRenderer Constructor: from_setup() Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/wgpu/struct Creates a new WgpuTestRenderer instance using a provided WgpuSetup configuration. This allows for customization of the underlying wgpu setup. ```rust pub fn from_setup(setup: WgpuSetup) -> Self ``` -------------------------------- ### Example: Building a Basic Harness with UI Closure (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Demonstrates building a simple egui test harness using a UI closure. This example sets the harness size and defines a UI element (a label) directly within the closure, suitable for basic UI testing scenarios. ```rust # use egui_kittest::{Harness, kittest::Queryable}; let mut harness = Harness::builder() .with_size(egui::Vec2::new(300.0, 200.0)) .build_ui(|ui| { ui.label("Hello, world!"); }); ``` -------------------------------- ### Example: Testing egui Checkbox with UI Closure (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Illustrates the usage of `Harness::new_ui_state` for testing egui UIs. This example focuses on directly manipulating the UI and verifying the state changes, similar to the `new_state` example but using the UI-centric constructor. ```rust # use egui_kittest::{Harness, kittest::Queryable}; let mut checked = false; let mut harness = Harness::new_ui_state(|ui, checked| { ui.checkbox(checked, "Check me!"); }, checked); harness.get_by_label("Check me!").click(); harness.run(); assert_eq!(*harness.state(), true); ``` -------------------------------- ### Example: Building a Stateful Harness with App Logic (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Illustrates creating a stateful test harness by providing an application closure that manages state. The example sets the harness size and uses a checkbox within a `CentralPanel` to modify the application's state, asserting the final state. ```rust # use egui::CentralPanel; # use egui_kittest::{Harness, kittest::Queryable}; let checked = false; let mut harness = Harness::builder() .with_size(egui::Vec2::new(300.0, 200.0)) .build_state(|ctx, checked| { CentralPanel::default().show(ctx, |ui| { ui.checkbox(checked, "Check me!"); }); }, checked); harness.get_by_label("Check me!").click(); harness.run(); assert_eq!(*harness.state(), true); ``` -------------------------------- ### Enable WGPU Rendering with Custom Setup in Rust Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Enables WGPU rendering for the harness using a provided [`egui_wgpu::WgpuSetup`]. This allows for fine-grained control over the WGPU initialization process for testing purposes. ```rust impl HarnessBuilder { /// Enable wgpu rendering with the given setup. #[cfg(feature = "wgpu")] pub fn wgpu_setup(self, setup: egui_wgpu::WgpuSetup) -> Self { // Implementation would typically involve creating a WgpuTestRenderer with the provided setup // and then calling self.renderer(...) with it. // Placeholder for actual implementation: self.renderer(crate::wgpu::WgpuTestRenderer::new(setup)) } } ``` -------------------------------- ### Default WGPU Setup Configuration Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/wgpu Configures default WGPU settings, prioritizing certain backends and device types. It explicitly removes browser WebGPU support and sorts adapters to prefer CPU, then discrete GPUs. This setup is used for creating a new render state. ```rust pub fn default_wgpu_setup() -> egui_wgpu::WgpuSetup { let mut setup = egui_wgpu::WgpuSetupCreateNew::default(); // WebGPU not supported yet since we rely on blocking screenshots. setup .instance_descriptor .backends .remove(wgpu::Backends::BROWSER_WEBGPU); // Prefer software rasterizers. setup.native_adapter_selector = Some(Arc::new(|adapters, _surface| { let mut adapters = adapters.iter().collect::>(); // Adapters are already sorted by preferred backend by wgpu, but let's be explicit. adapters.sort_by_key(|a| match a.get_info().backend { wgpu::Backend::Metal => 0, wgpu::Backend::Vulkan => 1, wgpu::Backend::Dx12 => 2, wgpu::Backend::Gl => 4, wgpu::Backend::BrowserWebGpu => 6, wgpu::Backend::Noop => 7, }); // Prefer CPU adapters, otherwise if we can't, prefer discrete GPU over integrated GPU. adapters.sort_by_key(|a| match a.get_info().device_type { wgpu::DeviceType::Cpu => 0, // CPU is the best for our purposes! wgpu::DeviceType::DiscreteGpu => 1, wgpu::DeviceType::Other | wgpu::DeviceType::IntegratedGpu | wgpu::DeviceType::VirtualGpu => 2, }); adapters .first() .map(|a| (*a).clone()) .ok_or("No adapter found".to_owned()) })); egui_wgpu::WgpuSetup::CreateNew(setup) } ``` -------------------------------- ### Set Harness Pixels Per Point (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Configures the `pixels_per_point` ratio for the Harness's context. This affects the scaling of UI elements. For initial setup, use `HarnessBuilder::with_pixels_per_point`. ```rust # use egui::Context; pub fn set_pixels_per_point(&mut self, pixels_per_point: f32) -> &mut Self { self.ctx.set_pixels_per_point(pixels_per_point); self } ``` -------------------------------- ### Example Usage of egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/index Demonstrates how to use the egui_kittest harness to interact with and test an egui UI. It shows how to find UI elements by label, simulate clicks, and assert state changes. Dependencies include `egui` and `egui_kittest`. ```rust use egui::accesskit::Toggled; use egui_kittest::{Harness, kittest::{Queryable, NodeT}}; fn main() { let mut checked = false; let app = |ui: &mut egui::Ui| { ui.checkbox(&mut checked, "Check me!"); }; let mut harness = Harness::new_ui(app); let checkbox = harness.get_by_label("Check me!"); assert_eq!(checkbox.accesskit_node().toggled(), Some(Toggled::False)); checkbox.click(); harness.run(); let checkbox = harness.get_by_label("Check me!"); assert_eq!(checkbox.accesskit_node().toggled(), Some(Toggled::True)); // Shrink the window size to the smallest size possible harness.fit_contents(); // You can even render the ui and do image snapshot tests #[cfg(all(feature = "wgpu", feature = "snapshot"))] harness.snapshot("readme_example"); } ``` -------------------------------- ### WgpuTestRenderer Constructor: new() Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/wgpu/struct Creates a new instance of WgpuTestRenderer with the default setup. This is a convenient constructor for basic usage without custom configuration. ```rust pub fn new() -> Self ``` -------------------------------- ### Create New Harness with App Closure in egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Constructs a new `Harness` instance by immediately running the provided application closure once to generate the initial UI. This is the standard way to initialize the harness for applications that utilize windows or panels. Customizations like window size can be achieved via `Harness::builder`. ```rust pub fn new(app: impl FnMut(&egui::Context) + 'a) -> Self { Self::builder().build(app) } ``` -------------------------------- ### Get Root Viewpoint Output in egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Retrieves the `egui::ViewportOutput` for the root viewport. This is a private helper method that expects the root viewport to exist and will panic if it's missing. It's used internally for accessing the primary viewport's output data. ```rust fn root_viewport_output(&self) -> &egui::ViewportOutput { self.output .viewport_output .get(&ViewportId::ROOT) .expect("Missing root viewport") } ``` -------------------------------- ### Enable WGPU Rendering with Default Setup in Rust Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Enables WGPU rendering for the harness by setting the renderer to a default [`WgpuTestRenderer`]. This feature requires the 'wgpu' feature to be enabled. ```rust impl HarnessBuilder { /// Enable wgpu rendering with a default setup suitable for testing. /// /// This sets up a [`crate::wgpu::WgpuTestRenderer`] with the default setup. #[cfg(feature = "wgpu")] pub fn wgpu(self) -> Self { self.renderer(crate::wgpu::WgpuTestRenderer::default()) } } ``` -------------------------------- ### Create Harness with State Initialization (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Initializes a new Harness with a given application closure that receives both the egui context and a mutable state, and an initial state value. This is useful when your application's logic is directly tied to a specific state object. ```rust pub fn new_state(app: impl FnMut(&egui::Context, &mut State) + 'a, state: State) -> Self { Self::builder().build_state(app, state) } ``` -------------------------------- ### Run a Specific Number of Steps in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Executes a specified number of steps by repeatedly calling the `step` method. This is useful for simulating a sequence of actions within the harness. It takes the number of steps as a `usize` argument. ```rust pub fn run_steps(&mut self, steps: usize) { for _ in 0..steps { self.step(); } } ``` -------------------------------- ### Harness Initialization from Builder (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Initializes the `Harness` struct from a `HarnessBuilder`. This function sets up the egui context, input, and initial state, ensuring that AccessKit is enabled and specific egui style options like disabled cursor blinking and scroll animations are applied. It also runs egui for a single frame to initialize the AccessKit state. ```Rust impl<'a, State> Harness<'a, State> { pub(crate) fn from_builder( builder: HarnessBuilder, mut app: AppKind<'a, State>, mut state: State, ctx: Option, ) -> Self { let HarnessBuilder { .. } = builder; let ctx = ctx.unwrap_or_default(); ctx.set_theme(theme); ctx.set_os(os); ctx.enable_accesskit(); ctx.all_styles_mut(|style| { style.visuals.text_cursor.blink = false; style.scroll_animation = ScrollAnimation::none(); style.animation_time = 0.0; }); let mut input = egui::RawInput { screen_rect: Some(screen_rect), ..Default::default() }; let viewport = input.viewports.get_mut(&ViewportId::ROOT).unwrap(); viewport.native_pixels_per_point = Some(pixels_per_point); let mut response = None; let mut output = ctx.run(input.clone(), |ctx| { response = app.run(ctx, &mut state, false); }); renderer.handle_delta(&output.textures_delta); let mut harness = Self { app, ctx, input, kittest: kittest::State::new( output .platform_output .accesskit_update .take() .expect("AccessKit was disabled"), ), output, response, state, renderer, max_steps, step_dt, }; harness } } ``` -------------------------------- ### Get Root Node for Test Harness Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides access to the root `Node` of the test harness's accessibility tree. This node represents the top-level element and allows querying of the accessibility tree structure and events. It returns a `Node` containing the `accesskit_node` and a queue for queued events. ```rust pub fn root(&self) -> Node<'_> { Node { accesskit_node: self.kittest.root(), queue: &self.queued_events, } } ``` -------------------------------- ### Example: Building a Stateful Harness with UI Checkbox (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Demonstrates building a stateful test harness for an egui application. It sets the harness size, defines a UI closure that includes a checkbox, and then simulates a click on the checkbox to test state changes. ```rust # use egui_kittest::{Harness, kittest::Queryable}; let mut checked = false; let mut harness = Harness::builder() .with_size(egui::Vec2::new(300.0, 200.0)) .build_ui_state(|ui, checked| { ui.checkbox(checked, "Check me!"); }, checked); harness.get_by_label("Check me!").click(); harness.run(); assert_eq!(*harness.state(), true); ``` -------------------------------- ### Simulate Key Combination in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates pressing and releasing a sequence of keys. It first presses each key in the provided slice and then releases them in reverse order. This is useful for testing typing of multi-character inputs. ```rust pub fn key_combination(&self, keys: &[Key]) { for key in keys { self.key_down(*key); } for key in keys.iter().rev() { self.key_up(*key); } } ``` -------------------------------- ### Access egui FullOutput in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides read-only access to the `egui::FullOutput` from the last frame. This allows inspection of the rendered output and UI state. It returns a reference to the `FullOutput` struct. ```rust pub fn output(&self) -> &egui::FullOutput { &self.output } ``` -------------------------------- ### Create Harness with UI and State Initialization (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Creates a new Harness using a UI closure that directly interacts with an egui::Ui and a mutable state, along with an initial state value. This method is suitable for scenarios where you primarily need to define the UI elements and their interaction with the state. ```rust pub fn new_ui_state(app: impl FnMut(&mut egui::Ui, &mut State) + 'a, state: State) -> Self { Self::builder().build_ui_state(app, state) } ``` -------------------------------- ### WgpuTestRenderer Initialization and Usage Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/wgpu Defines the `WgpuTestRenderer` for testing egui applications with WGPU. It provides methods to create a renderer with default settings, custom setups, or from an existing `RenderState`. It also includes logic for handling texture deltas during rendering. ```rust /// Utility to render snapshots from a [`crate::Harness`] using [`egui_wgpu`]. pub struct WgpuTestRenderer { render_state: RenderState, } impl Default for WgpuTestRenderer { fn default() -> Self { Self::new() } } impl WgpuTestRenderer { /// Create a new [`WgpuTestRenderer`] with the default setup. pub fn new() -> Self { Self { render_state: create_render_state(default_wgpu_setup()), } } /// Create a new [`WgpuTestRenderer`] with the given setup. pub fn from_setup(setup: WgpuSetup) -> Self { Self { render_state: create_render_state(setup), } } /// Create a new [`WgpuTestRenderer`] from an existing [`RenderState`]. /// /// # Panics /// Panics if the [`RenderState`] has been used before. pub fn from_render_state(render_state: RenderState) -> Self { assert!( render_state .renderer .read() .texture(&egui::epaint::TextureId::Managed(0)) .is_none(), "The RenderState passed in has been used before, pass in a fresh RenderState instead." ); Self { render_state } } } impl crate::TestRenderer for WgpuTestRenderer { #[cfg(feature = "eframe")] fn setup_eframe(&self, cc: &mut eframe::CreationContext<'_>, frame: &mut eframe::Frame) { cc.wgpu_render_state = Some(self.render_state.clone()); frame.wgpu_render_state = Some(self.render_state.clone()); } fn handle_delta(&mut self, delta: &TexturesDelta) { let mut renderer = self.render_state.renderer.write(); for (id, image) in &delta.set { renderer.update_texture( &self.render_state.device, &self.render_state.queue, *id, image, ); } } } ``` -------------------------------- ### Access General State in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides read-only access to the general `State` of the harness. This allows inspection of the overall harness state. It returns a reference to the `State` struct. ```rust pub fn state(&self) -> &State { &self.state } ``` -------------------------------- ### Run Harness Frame for Queued Events (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Processes all queued events for the Harness, running a frame for each event. If no events are present, it executes a single frame. This method is crucial for simulating user interactions and application updates over time. ```rust pub fn step(&mut self) { let events = std::mem::take(&mut *self.queued_events.lock()); if events.is_empty() { self._step(false); } for event in events { match event { EventType::Event(event) => { self.input.events.push(event); } EventType::Modifiers(modifiers) => { self.input.modifiers = modifiers; } } self._step(false); } } ``` -------------------------------- ### Run Realtime Steps in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Executes the harness in realtime, returning the number of steps run. It can return an error if the maximum number of steps is exceeded. This method relies on an internal `_try_run` method. ```rust pub fn try_run_realtime(&mut self) -> Result { self._try_run(true) } ``` -------------------------------- ### Set Harness Window Size (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Sets the size of the Harness window. This method modifies the input screen rectangle directly. For initial size configuration, `HarnessBuilder::with_size` is preferred. ```rust # use egui::{Vec2, Rect, Pos2}; pub fn set_size(&mut self, size: Vec2) -> &mut Self { self.input.screen_rect = Some(Rect::from_min_size(Pos2::ZERO, size)); self } ``` -------------------------------- ### Render Output to Image with wgpu or snapshot feature Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Renders the last output of the egui context to an `image::RgbaImage`. This functionality is conditional and requires either the `wgpu` or `snapshot` feature to be enabled. It returns a `Result` which is `Ok` with the image data on success or `Err` with a string describing the failure. ```rust #[cfg(any(feature = "wgpu", feature = "snapshot"))] pub fn render(&mut self) -> Result { self.renderer.render(&self.ctx, &self.output) } ``` -------------------------------- ### Access KittTest State in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides read-only access to the internal `kittest::State`. This allows inspection of the state specific to the kittest framework. It returns a reference to the `State` struct. ```rust pub fn kittest_state(&self) -> &kittest::State { &self.kittest } ``` -------------------------------- ### Access egui RawInput in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides read-only access to the `egui::RawInput` for the current frame. This allows inspection of input events and state. It returns a reference to the `RawInput` struct. ```rust pub fn input(&self) -> &egui::RawInput { &self.input } ``` -------------------------------- ### Simulate Key Up Event in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates a key release event for a given `egui::Key` without any modifiers. It queues an `egui::Event::Key` with `pressed` set to false. This complements `key_down` for complete key event simulation. ```rust pub fn key_up(&self, key: egui::Key) { self.event(egui::Event::Key { key, pressed: false, modifiers: Modifiers::default(), repeat: false, physical_key: None, }); } ``` -------------------------------- ### Run Test Safely (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Runs the test harness until completion, similar to `try_run`, but returns an `Option`. It returns `Some(steps)` if the test completes within the maximum step limit, and `None` if the maximum number of steps is exceeded. This is useful for tests that might have long-running or potentially infinite loops. ```Rust pub fn run_ok(&mut self) -> Option { self.try_run().ok() } ``` -------------------------------- ### Simulate Key Combination with Modifiers in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates pressing and releasing a sequence of keys while holding down specified modifiers. It first applies the modifiers, then presses keys, and finally releases them, including the modifiers. This is vital for testing shortcuts involving multiple keys. ```rust pub fn key_combination_modifiers(&self, modifiers: Modifiers, keys: &[Key]) { self.modifiers(modifiers); for pressed in [true, false] { for key in keys { self.event(egui::Event::Key { key: *key, pressed, modifiers, repeat: false, physical_key: None, }); } } } ``` -------------------------------- ### Queue Event with Modifiers in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Queues an `egui::Event` along with associated `Modifiers`. It first pushes the specified modifiers, then the event, and finally resets modifiers. This is useful for simulating shortcuts or key combinations involving modifier keys. ```rust pub fn event_modifiers(&self, event: egui::Event, modifiers: Modifiers) { let mut queue = self.queued_events.lock(); queue.push(EventType::Modifiers(modifiers)); queue.push(EventType::Event(event)); queue.push(EventType::Modifiers(Modifiers::default())); } ``` -------------------------------- ### Run Test Until Completion (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Executes the test harness until all animations are finished and no more repaints are requested. This function is a convenience wrapper around `try_run` that panics if the maximum number of steps is exceeded. It returns the total number of steps executed. ```Rust #[track_caller] pub fn run(&mut self) -> u64 { match self.try_run() { Ok(steps) => steps, Err(err) => { panic!("{err}"); } } } ``` -------------------------------- ### Simulate Key Down Event in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates a key press event for a given `egui::Key` without any modifiers. It queues an `egui::Event::Key` with `pressed` set to true. This is a basic way to trigger key actions. ```rust pub fn key_down(&self, key: egui::Key) { self.event(egui::Event::Key { key, pressed: true, modifiers: Modifiers::default(), repeat: false, physical_key: None, }); } ``` -------------------------------- ### Access General State Mutably in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides mutable access to the general `State` of the harness. This allows modification of the harness state. It returns a mutable reference to the `State` struct. ```rust pub fn state_mut(&mut self) -> &mut State { &mut self.state } ``` -------------------------------- ### Simulate Key Up with Modifiers in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates a key release event for a given `egui::Key` along with specified `Modifiers`. It utilizes `event_modifiers` to manage the modifier state correctly during the release. Essential for testing complex key interactions. ```rust pub fn key_up_modifiers(&self, modifiers: Modifiers, key: egui::Key) { self.event_modifiers( egui::Event::Key { key, pressed: false, modifiers, repeat: false, physical_key: None, }, modifiers, ); } ``` -------------------------------- ### Rust: Try Snapshot with Default Options Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/snapshot Renders an image using the harness's default setup and compares it against a snapshot. This function utilizes options configured via `HarnessBuilder::with_options` and saves snapshot artifacts to `tests/snapshots/`. It returns a `SnapshotResult`, yielding a `SnapshotError` on failure. ```rust pub fn try_snapshot(&mut self, name: impl Into) -> SnapshotResult { let image = self .render() .map_err(|err| SnapshotError::RenderError { err })?; try_image_snapshot_options(&image, name.into(), &self.default_snapshot_options) } ``` -------------------------------- ### Simulate Key Press with egui::Key Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates a key press event by calling `key_combination`. This method first creates a key down event and then a key up event for the specified key. It does not involve any modifier keys. ```rust pub fn key_press(&self, key: egui::Key) { self.key_combination(&[key]); } ``` -------------------------------- ### Simulate Key Down with Modifiers in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates a key press event for a given `egui::Key` along with specified `Modifiers`. It uses `event_modifiers` to ensure modifiers are correctly applied and released. This is crucial for testing shortcuts. ```rust pub fn key_down_modifiers(&self, modifiers: Modifiers, key: egui::Key) { self.event_modifiers( egui::Event::Key { key, pressed: true, modifiers, repeat: false, physical_key: None, }, modifiers, ); } ``` -------------------------------- ### Queue egui Event in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Queues a standard `egui::Event` to be processed in the next frame. This is used for simulating user input like mouse clicks or key presses without modifiers. The event is added to a locked queue. ```rust pub fn event(&self, event: egui::Event) { self.queued_events.lock().push(EventType::Event(event)); } ``` -------------------------------- ### Fit Contents to UI Size (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Resizes the test harness window to precisely fit its UI contents, including any popups or tooltips. This function is intended for use when creating the Harness via specific `new_ui` or `build_ui` methods. It calls internal step and compute functions, then sets the harness size based on the calculated total rect. ```Rust pub fn fit_contents(&mut self) { self._step(true); // Calculate size including all content (main UI + popups + tooltips) if let Some(rect) = self.compute_total_rect_with_popups() { self.set_size(rect.size()); } self.run_ok(); } ``` -------------------------------- ### Access egui RawInput Mutably in Harness (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Provides mutable access to the `egui::RawInput` for the current frame. This allows modification of input events and state before processing. It returns a mutable reference to the `RawInput` struct. ```rust pub fn input_mut(&mut self) -> &mut egui::RawInput { &mut self.input } ``` -------------------------------- ### Calculate Total Rect with Popups and Tooltips (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Calculates the bounding rectangle that encompasses the main UI response and all visible popups and tooltips. It iterates through visible layers, excluding the background, and combines their rectangular areas with the initial response rectangle. Returns None if no initial response is available. ```Rust fn compute_total_rect_with_popups(&self) -> Option { // Start with the standard response rect let mut used = if let Some(response) = self.response.as_ref() { response.rect } else { return None; }; // Add all visible areas from other orders (popups, tooltips, etc.) self.ctx.memory(|mem| { mem.areas() .visible_layer_ids() .into_iter() .filter(|layer_id| layer_id.order != egui::Order::Background) .filter_map(|layer_id| mem.area_rect(layer_id.id)) .for_each(|area_rect| used |= area_rect); }); Some(used) } ``` -------------------------------- ### Display Error for ExceededMaxStepsError (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Implements the `Display` trait for `ExceededMaxStepsError` to provide a user-friendly error message when a test harness exceeds the maximum allowed steps. This helps in debugging by showing the number of steps and the reasons for repainting. ```Rust #[derive(Debug, Clone)] pub struct ExceededMaxStepsError { pub max_steps: u64, pub repaint_causes: Vec, } impl Display for ExceededMaxStepsError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, "Harness::run exceeded max_steps ({}). If your expect your ui to keep repainting \ (e.g. when showing a spinner) call Harness::step or Harness::run_steps instead.\ \nRepaint causes: {:#?}", self.max_steps, self.repaint_causes, ) } } ``` -------------------------------- ### Simulate Key Press with Modifiers in egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Simulates a key press event along with specified modifiers. This function first sets the modifiers, then triggers key down and key up events for the given key, and finally resets the modifiers. It's useful for testing shortcuts or key combinations. ```rust pub fn key_press_modifiers(&self, modifiers: Modifiers, key: egui::Key) { self.key_combination_modifiers(modifiers, &[key]); } ``` -------------------------------- ### Attempt to Run Test Iterations (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Attempts to run the test harness until animations complete, no more repaints are needed, or the maximum step count is reached. It takes a boolean `sleep` parameter to control whether thread sleeping occurs between steps. Returns a `Result` containing the number of steps or an `ExceededMaxStepsError`. ```Rust fn _try_run(&mut self, sleep: bool) -> Result { let mut steps = 0; loop { steps += 1; self.step(); let wait_for_images = self.wait_for_pending_images && self.ctx.has_pending_images(); // We only care about immediate repaints if self.root_viewport_output().repaint_delay != Duration::ZERO && !wait_for_images { break; } else if sleep || wait_for_images { std::thread::sleep(Duration::from_secs_f32(self.step_dt)); } if steps > self.max_steps { return Err(ExceededMaxStepsError { max_steps: self.max_steps, repaint_causes: self.ctx.repaint_causes(), }); } } Ok(steps) } ``` -------------------------------- ### Try Run Test with Max Steps Check (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Executes the test harness until animations are done, no more repaints are requested, and the maximum number of steps is not exceeded. This function returns the number of steps executed or an error if the maximum step limit is hit. It's designed for scenarios where exceeding the step limit should be treated as an error. ```Rust pub fn try_run(&mut self) -> Result { self._try_run(false) } ``` -------------------------------- ### Remove Cursor Event in egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Removes the cursor from the screen by firing a `egui::Event::PointerGone` event. This is particularly useful in snapshot tests to ensure that elements are not perceived as hovered after an interaction, for example, after clicking a button. ```rust pub fn remove_cursor(&self) { self.event(egui::Event::PointerGone); } ``` -------------------------------- ### Snapshot Testing with egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest Explains how to enable and use the snapshot testing feature in egui_kittest, which requires the 'snapshot' and 'wgpu' features. It details how to generate and update snapshots using environment variables. ```rust #[cfg(all(feature = "wgpu", feature = "snapshot"))] harness.snapshot("readme_example"); ``` -------------------------------- ### TestRenderer::setup_eframe() Implementation for WgpuTestRenderer Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/wgpu/struct Configures the eframe::Frame with the necessary wgpu render state from the WgpuTestRenderer. This is crucial for integrating wgpu rendering within the eframe application lifecycle. ```rust fn setup_eframe(&self, cc: &mut CreationContext<'_>, frame: &mut Frame) ``` -------------------------------- ### Snapshot Testing Configuration and Usage Source: https://docs.rs/egui_kittest/0.33.1/index Explains how to enable and use snapshot testing with egui_kittest, requiring the `snapshot` and `wgpu` features. It covers updating snapshots using environment variables like `UPDATE_SNAPSHOTS=true` or `UPDATE_SNAPSHOTS=force`, and suggests `.gitignore` entries for snapshot files. ```rust #[cfg(all(feature = "wgpu", feature = "snapshot"))] harness.snapshot("readme_example"); ``` ```bash UPDATE_SNAPSHOTS=true cargo test UPDATE_SNAPSHOTS=force cargo test ``` ```text **/tests/snapshots/**/*.diff.png **/tests/snapshots/**/*.new.png ``` -------------------------------- ### Build Harness with Context Closure (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Creates a new Harness with a context-based application closure. This closure is called once to set up the initial UI. It's suitable for simpler egui applications where direct interaction with the `egui::Context` is needed. ```rust pub fn build<'a>(self, app: impl FnMut(&egui::Context) + 'a) -> Harness<'a> { Harness::from_builder(self, AppKind::Context(Box::new(app)), (), None) } ``` -------------------------------- ### Get Node Properties (Rect, Value, Focus) in egui Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/node Retrieves properties of an egui node, including its bounding rectangle, accessibility value, and focus state. These methods interact with the underlying `AccessKitNode`. ```rust pub fn rect(&self) -> egui::Rect { let rect = self .accesskit_node .bounding_box() .expect("Every egui node should have a rect"); egui::Rect { min: Pos2::new(rect.x0 as f32, rect.y0 as f32), max: Pos2::new(rect.x1 as f32, rect.y1 as f32), } } pub fn value(&self) -> Option { self.accesskit_node.value() } pub fn is_focused(&self) -> bool { self.accesskit_node.is_focused() } ``` -------------------------------- ### Create WGPU Render State Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/wgpu Initializes and returns a `egui_wgpu::RenderState` using the provided `WgpuSetup`. This function handles the asynchronous creation of the WGPU instance and render state, blocking until completion. ```rust pub fn create_render_state(setup: WgpuSetup) -> egui_wgpu::RenderState { let instance = pollster::block_on(setup.new_instance()); pollster::block_on(egui_wgpu::RenderState::create( &egui_wgpu::WgpuConfiguration { wgpu_setup: setup, ..Default::default() }, &instance, None, egui_wgpu::RendererOptions::PREDICTABLE, )) .expect("Failed to create render state") } ``` -------------------------------- ### Build Stateful Harness with UI Closure (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Creates a new Harness with a stateful UI closure and an initial state. The UI closure is called once to create the initial UI. Use this when your application logic is primarily within the UI rendering, and you need to manage state. ```rust pub fn build_ui_state<'a>( self, app: impl FnMut(&mut egui::Ui, &mut State) + 'a, state: State, ) -> Harness<'a, State> { Harness::from_builder(self, AppKind::UiState(Box::new(app)), state, None) } ``` -------------------------------- ### Create Image Snapshot with Custom Options Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/snapshot A public function to create an image snapshot with custom options. It delegates the actual implementation to `try_image_snapshot_options_impl`. Accepts a new image, a name for the snapshot, and snapshot options. ```Rust pub fn try_image_snapshot_options( new: &image::RgbaImage, name: impl Into, options: &SnapshotOptions, ) -> SnapshotResult { try_image_snapshot_options_impl(new, name.into(), options) } ``` -------------------------------- ### Build Harness with UI Closure (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Creates a new Harness with a UI-based application closure. This closure is invoked once to define the initial UI. Use this for straightforward UI definitions without complex state management or context manipulation. ```rust pub fn build_ui<'a>(self, app: impl FnMut(&mut egui::Ui) + 'a) -> Harness<'a> { Harness::from_builder(self, AppKind::Ui(Box::new(app)), (), None) } ``` -------------------------------- ### Build Stateful Harness with App Closure (Rust) Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Creates a new Harness with a stateful application closure and an initial state. The app closure is called once to create the initial UI. This method is suitable when you need to manage application state directly. ```rust pub fn build_state<'a>( self, app: impl FnMut(&egui::Context, &mut State) + 'a, state: State, ) -> Harness<'a, State> { Harness::from_builder(self, AppKind::ContextState(Box::new(app)), state, None) } ``` -------------------------------- ### TestRenderer::setup_eframe Method Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/trait A provided method on the TestRenderer trait used to pass glow/wgpu render state to eframe::Frame. It takes a CreationContext and a Frame as arguments. ```rust fn setup_eframe(&self, _cc: &mut CreationContext<'_>, _frame: &mut Frame) { ... } ``` -------------------------------- ### WgpuTestRenderer Constructor: from_render_state() Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/wgpu/struct Initializes a WgpuTestRenderer from an existing RenderState. This method will panic if the provided RenderState has been used previously, ensuring state integrity. ```rust pub fn from_render_state(render_state: RenderState) -> Self ``` -------------------------------- ### TestRenderer::render() Implementation for WgpuTestRenderer Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/wgpu/struct Renders the crate::Harness content using the WgpuTestRenderer and returns the resulting image as an RgbaImage. Handles potential rendering errors by returning a String. ```rust fn render( &mut self, ctx: &Context, output: &FullOutput, ) -> Result ``` -------------------------------- ### Mask Rectangular Area in egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/lib Adds a `RectShape` filled with magenta to the output shapes for the current frame. This method is intended to be called after `Self::run` and before `Self::snapshot` to mask specific areas, commonly used in snapshot testing. The mask will be overwritten on the next `Self::run` call. ```rust pub fn mask(&mut self, rect: Rect) { self.output.shapes.push(ClippedShape { clip_rect: Rect::EVERYTHING, shape: Shape::Rect(RectShape::filled(rect, 0.0, Color32::MAGENTA)), }); } ``` -------------------------------- ### Try Image Snapshot Options with Custom Settings Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/fn Performs an image snapshot test with custom options. It saves the snapshot, new image, and optionally a diff or old image based on environment variables and matching status. Returns a SnapshotError on failure. ```rust pub fn try_image_snapshot_options( new: &RgbaImage, name: impl Into, options: &SnapshotOptions, ) -> SnapshotResult ``` -------------------------------- ### HarnessBuilder Default Configuration in Rust Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/builder Defines the default settings for HarnessBuilder, including screen dimensions, pixel density, theme, OS, simulation step parameters, and image waiting behavior. It also initializes a LazyRenderer by default. ```rust impl Default for HarnessBuilder { fn default() -> Self { Self { screen_rect: Rect::from_min_size(Pos2::ZERO, Vec2::new(800.0, 600.0)), pixels_per_point: 1.0, theme: egui::Theme::Dark, state: PhantomData, renderer: Box::new(LazyRenderer::default()), max_steps: 4, step_dt: 1.0 / 4.0, wait_for_pending_images: true, os: egui::os::OperatingSystem::Nix, #[cfg(feature = "snapshot")] default_snapshot_options: crate::SnapshotOptions::default(), } } } ``` -------------------------------- ### Rust: SnapshotResults Methods Overview Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/struct Provides an overview of key methods available for the SnapshotResults struct in Rust. These methods allow for creating, adding results, checking for errors, and converting results into different formats. ```rust // Create a new SnapshotResults instance let mut results = SnapshotResults::new(); // Add a snapshot result (assuming SnapshotResult is defined elsewhere) // results.add(snapshot_result); // Check if there are any errors let has_errors = results.has_errors(); // Convert to a Result, handling errors gracefully let result: Result<(), SnapshotResults> = results.into_result(); // Consume and get the raw vector of errors let errors: Vec = results.into_inner(); // Force a panic if there are errors (use with caution) // results.unwrap(); ``` -------------------------------- ### Define Snapshot Options for egui_kittest Source: https://docs.rs/egui_kittest/0.33.1/src/egui_kittest/snapshot The `SnapshotOptions` struct allows customization of snapshot test behavior. It includes a `threshold` for image comparison sensitivity, `failed_pixel_count_threshold` to specify the maximum number of differing pixels, and `output_path` for saving snapshot images. Defaults are provided for convenience. ```rust pub struct SnapshotOptions { /// The threshold for the image comparison. /// The default is `0.6` (which is enough for most egui tests to pass across different /// wgpu backends). pub threshold: f32, /// The number of pixels that can differ before the snapshot is considered a failure. /// Preferably, you should use `threshold` to control the sensitivity of the image comparison. /// As a last resort, you can use this to allow a certain number of pixels to differ. /// If `None`, the default is `0` (meaning no pixels can differ). /// If `Some`, the value can be set per OS pub failed_pixel_count_threshold: usize, /// The path where the snapshots will be saved. /// The default is `tests/snapshots`. pub output_path: PathBuf, } impl Default for SnapshotOptions { fn default() -> Self { Self { threshold: 0.6, output_path: PathBuf::from("tests/snapshots"), failed_pixel_count_threshold: 0, // Default is 0, meaning no pixels can differ } } } impl SnapshotOptions { /// Create a new [`SnapshotOptions`] with the default values. pub fn new() -> Self { Default::default() } /// Change the threshold for the image comparison. /// The default is `0.6` (which is enough for most egui tests to pass across different /// wgpu backends). #[inline] pub fn threshold(mut self, threshold: impl Into) -> Self { self.threshold = threshold.into(); self } /// Change the path where the snapshots will be saved. /// The default is `tests/snapshots`. #[inline] pub fn output_path(mut self, output_path: impl Into) -> Self { self.output_path = output_path.into(); self } /// Change the number of pixels that can differ before the snapshot is considered a failure. /// /// Preferably, you should use [`Self::threshold`] to control the sensitivity of the image comparison. ``` -------------------------------- ### Rust: Initialize and Use SnapshotResults Source: https://docs.rs/egui_kittest/0.33.1/egui_kittest/struct Demonstrates how to create a SnapshotResults instance, add snapshot test results to it, and how it handles errors upon being dropped. It's essential for managing snapshot testing outcomes. ```rust use egui_kittest::SnapshotResults; // Assume 'harness' is a pre-constructed Harness object // let mut harness = Harness::new(...); let mut results = SnapshotResults::new(); // Add results from snapshot tests // results.add(harness.try_snapshot("my_test")); // When 'results' is dropped, it will panic if any errors occurred. // To handle errors explicitly, use into_result() or into_inner(). ```