LR-CROP-STRAIGHTEN: the headless harness reports the cursor and the painted text

For the crop tool's rotation pointer tests (#534): Headless::last_cursor
is the pointer cursor the last frame asked for (what a real host would
show), and painted_text lists every text the last frame painted,
tooltips included. An import test already did the latter inline. Both
let UI tests check what a person sees.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nathaniel Ledford
2026-10-09 12:10:44 -04:00
co-authored by Claude Opus 5.5
parent 03b3d606ce
commit ef31741fbb
+27
View File
@@ -145,6 +145,22 @@ impl HeadlessView {
self.frames
}
/// Every piece of text the last frame painted (labels, tooltips, values), in paint order.
pub fn painted_text(&self) -> Vec<String> {
fn texts(shape: &egui::epaint::Shape, out: &mut Vec<String>) {
match shape {
egui::epaint::Shape::Text(shape) => out.push(shape.galley.job.text.clone()),
egui::epaint::Shape::Vec(shapes) => shapes.iter().for_each(|shape| texts(shape, out)),
_ => {}
}
}
let mut out = Vec::new();
for shape in &self.shapes {
texts(&shape.shape, &mut out);
}
out
}
/// Size in pixels of the last frame.
pub fn size_px(&self) -> [usize; 2] {
self.size
@@ -182,6 +198,8 @@ pub struct Headless {
pub window_maximized: bool,
/// Window-management commands the app sent (`StartDrag`, `Maximized`, …), oldest first.
pub window_commands: Vec<ViewportCommand>,
/// The pointer cursor the last frame asked for (what a real host would show).
pub last_cursor: egui::CursorIcon,
}
impl Headless {
@@ -210,6 +228,7 @@ impl Headless {
quit: false,
window_maximized: false,
window_commands: vec![],
last_cursor: egui::CursorIcon::Default,
}
}
@@ -217,6 +236,11 @@ impl Headless {
self.frames
}
/// Every piece of text the last frame painted ([`HeadlessView::painted_text`]).
pub fn painted_text(&self) -> Vec<String> {
self.view.painted_text()
}
/// `app.quit` was requested.
pub fn quit_requested(&self) -> bool {
self.quit
@@ -230,10 +254,13 @@ impl Headless {
raw.max_texture_side = Some(self.max_texture_side);
self.app.raw_input_hook(&mut raw);
let app = &mut self.app;
let mut cursor = egui::CursorIcon::Default;
let commands = self.view.run(raw, |ui| {
app.logic(ui.ctx());
app.ui(ui);
cursor = ui.ctx().output(|output| output.cursor_icon);
});
self.last_cursor = cursor;
self.time += FRAME_DT;
self.frames += 1;
for c in commands {