test: cover critical tui e2e paths

This commit is contained in:
2026-06-14 14:24:12 +09:00
parent 6cae63fc53
commit b9f49eee1f
6 changed files with 506 additions and 9 deletions
+64
View File
@@ -12,6 +12,7 @@ fn panel_mouse_click_selects_row_without_dispatching_action() -> yoi_e2e::Result
let mut panel = PanelHarness::spawn(fixture.panel_config(binary))?;
panel.expect_mouse_capture_enabled()?;
panel.assert_no_full_drag_mouse_capture()?;
let rows = panel.wait_for_rows(2)?;
assert_no_runtime_or_host_pod_leak(
&fixture,
@@ -38,6 +39,69 @@ fn panel_mouse_click_selects_row_without_dispatching_action() -> yoi_e2e::Result
"mouse selection must not dispatch panel actions; artifacts at {}",
panel.artifacts().dir.display()
);
panel.assert_no_full_drag_mouse_capture()?;
panel.press(KeyPress::CtrlC)?;
let status = panel.expect_exit_within(PanelHarness::default_exit_wait())?;
assert!(status.success(), "panel should exit cleanly with Ctrl+C");
drop(panel);
assert_fixture_cleanup(fixture.cleanup()?);
Ok(())
}
#[test]
fn panel_mouse_wheel_moves_selection_without_full_drag_capture() -> yoi_e2e::Result<()> {
let binary = yoi_binary()?;
let fixture = FixtureWorkspace::new(&binary)?;
assert_fixture_paths_are_isolated(&fixture);
let mut panel = PanelHarness::spawn(fixture.panel_config(binary))?;
panel.expect_mouse_capture_enabled()?;
panel.assert_no_full_drag_mouse_capture()?;
let rows = panel.wait_for_rows(2)?;
assert_no_runtime_or_host_pod_leak(
&fixture,
&rows.rows,
panel.artifacts().dir.display().to_string().as_str(),
);
let selected = rows
.selected
.as_ref()
.expect("fixture should render an initially selected row")
.clone();
let selected_index = rows
.rows
.iter()
.position(|row| row.key == selected)
.expect("selected row should be rendered");
let target_index = (selected_index + 1).min(rows.rows.len() - 1);
assert_ne!(
selected_index, target_index,
"fixture should render a wheel-selectable next row"
);
let source = rows.rows[selected_index].clone();
let target = rows.rows[target_index].clone();
let before_events = panel.events()?.len();
panel.wheel_down(&source)?;
panel.expect_selection(&target.key)?;
panel.assert_no_full_drag_mouse_capture()?;
let events = panel.events()?;
assert!(
events[before_events..]
.iter()
.any(|event| event.event == "mouse_wheel"),
"wheel movement should be visible in e2e events; artifacts at {}",
panel.artifacts().dir.display()
);
assert!(
events[before_events..]
.iter()
.all(|event| event.event != "action_requested"),
"wheel selection must not dispatch panel actions; artifacts at {}",
panel.artifacts().dir.display()
);
panel.press(KeyPress::CtrlC)?;
let status = panel.expect_exit_within(PanelHarness::default_exit_wait())?;
+61
View File
@@ -0,0 +1,61 @@
use std::time::Duration;
use yoi_e2e::{FixtureWorkspace, KeyPress, PanelHarness, yoi_binary};
#[test]
fn single_pod_rewind_picker_applies_without_escape_and_suppresses_duplicate_enter()
-> yoi_e2e::Result<()> {
let binary = yoi_binary()?;
let fixture = FixtureWorkspace::new(&binary)?;
let mut tui = PanelHarness::spawn(fixture.rewind_fixture_config(binary))?;
tui.expect_mouse_capture_enabled()?;
tui.assert_no_full_drag_mouse_capture()?;
tui.expect_event("rewind_fixture_ready", Duration::from_secs(5))?;
tui.press(KeyPress::CtrlR)?;
tui.expect_event("rewind_picker_opened", Duration::from_secs(5))?;
tui.press(KeyPress::Enter)?;
tui.expect_event("rewind_submit_sent", Duration::from_secs(5))?;
let submit_count = tui.count_events("rewind_submit_sent")?;
tui.press(KeyPress::Enter)?;
tui.expect_event("rewind_duplicate_enter_suppressed", Duration::from_secs(5))?;
tui.wait_for_no_additional_events(
"rewind_submit_sent",
submit_count,
Duration::from_millis(250),
)?;
let applied = tui.expect_event("rewind_applied", Duration::from_secs(5))?;
assert_eq!(
applied
.data
.get("composer_text")
.and_then(serde_json::Value::as_str),
Some("revise the plan"),
"rewind should update the visible composer state without Esc/restart; artifacts at {}",
tui.artifacts().dir.display()
);
assert_eq!(
tui.count_events("rewind_submit_sent")?,
submit_count,
"pending Enter must not duplicate destructive rewind submissions; artifacts at {}",
tui.artifacts().dir.display()
);
tui.press(KeyPress::CtrlD)?;
let status = tui.expect_exit_within(PanelHarness::default_exit_wait())?;
assert!(
status.success(),
"single-pod rewind fixture should exit cleanly"
);
drop(tui);
let cleanup = fixture.cleanup()?;
assert!(
cleanup.cleanup_success,
"fixture cleanup failed: {cleanup:?}"
);
Ok(())
}