use std::fs;
use std::path::Path;
use unicode_width::UnicodeWidthStr;
mod common;
fn write_fixture_file(path: impl AsRef<Path>, bytes: &[u8]) {
let path = path.as_ref();
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).unwrap();
}
fs::write(path, bytes).unwrap();
}
#[test]
fn tui_once_renders_disk_map_snapshot_for_root() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args(["tui", "--once", "--root", root.to_str().unwrap()])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | map"));
assert!(stdout.contains("Map: workspace"));
assert!(stdout.contains("big"));
assert!(stdout.contains("small.txt"));
assert!(stdout.contains("Status:"));
}
#[test]
fn tui_once_loads_saved_display_preferences() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
let state = temp.path().join("rebecca-state");
fs::create_dir_all(&state).unwrap();
fs::write(
state.join("tui-preferences.json"),
r#"{
"version": 1,
"last_screen": "treemap",
"sort": "files",
"entry_limit": 100,
"scan_backend": "portable-recursive",
"screen_reader": true,
"no_color": true
}
"#,
)
.unwrap();
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args(["tui", "--once", "--root", root.to_str().unwrap()])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | treemap"));
assert!(stdout.contains("sort files"));
assert!(
!stdout.contains("###"),
"screen-reader preference should omit visual bars: {stdout}"
);
}
#[test]
fn tui_once_does_not_write_preferences() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args(["tui", "--once", "--root", root.to_str().unwrap()])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
assert!(
!temp
.path()
.join("rebecca-state")
.join("tui-preferences.json")
.exists()
);
}
#[test]
fn tui_replay_can_scan_current_directory_from_root_picker() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("cache").join("data.bin"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.current_dir(&root)
.args(["i", "--once", "--replay-keys", "enter"])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | map"));
assert!(stdout.contains("Map: workspace"));
assert!(stdout.contains("cache"));
}
#[test]
fn tui_replay_can_change_sort_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"s",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("sort allocated"));
assert!(stdout.contains("Status: Sorted by allocated."));
}
#[test]
fn tui_replay_can_show_type_distribution_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("src").join("main.rs"), b"abc");
write_fixture_file(root.join("docs").join("readme.md"), b"abcde");
write_fixture_file(root.join("LICENSE"), b"xy");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"t",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | types"));
assert!(stdout.contains("Types: file kind distribution"));
assert!(stdout.contains("Files"));
assert!(stdout.contains("Directories"));
}
#[test]
fn tui_replay_can_show_extension_distribution_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("src").join("main.rs"), b"abc");
write_fixture_file(root.join("docs").join("readme.md"), b"abcde");
write_fixture_file(root.join("LICENSE"), b"xy");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"x",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | extensions"));
assert!(stdout.contains("Extensions: suffix distribution"));
assert!(stdout.contains(".md"));
assert!(stdout.contains(".rs"));
assert!(stdout.contains("No extension"));
}
#[test]
fn tui_replay_can_filter_map_from_extension_distribution() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("cache.tmp"), b"abcdef");
write_fixture_file(root.join("notes.txt"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"x enter",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | map"));
assert!(stdout.contains("filter .tmp"));
assert!(stdout.contains("Map: workspace [.tmp]"));
assert!(stdout.contains("cache.tmp"));
assert!(!stdout.contains("notes.txt"));
}
#[test]
fn tui_replay_can_clear_distribution_filter() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("cache.tmp"), b"abcdef");
write_fixture_file(root.join("notes.txt"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"x enter backspace",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | map"));
assert!(stdout.contains("Status: Cleared extension .tmp filter."));
assert!(stdout.contains("cache.tmp"));
assert!(stdout.contains("notes.txt"));
}
#[test]
fn tui_replay_can_show_treemap_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | treemap"));
assert!(stdout.contains("Treemap: workspace"));
assert!(stdout.contains("big"));
assert!(stdout.contains("small.txt"));
}
#[test]
fn tui_replay_click_tile_selects_without_drilling_down() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4 click:tile:0",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Treemap: workspace"));
assert!(stdout.contains("Selected tile: big"));
assert!(stdout.contains("Action: Enter/l opens this scope"));
assert!(stdout.contains("small.txt"));
}
#[test]
fn tui_replay_open_tile_drills_down_and_escape_returns_scope() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let opened = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4 open:tile:0",
])
.output()
.unwrap();
assert!(
opened.status.success(),
"stderr: {}",
common::support::stderr(&opened)
);
let opened_stdout = String::from_utf8_lossy(&opened.stdout);
assert!(opened_stdout.contains("Rebecca TUI | treemap"));
assert!(opened_stdout.contains("Treemap: big"));
assert!(opened_stdout.contains("Breadcrumb: workspace > big"));
assert!(opened_stdout.contains("Zoom depth: 1"));
assert!(opened_stdout.contains("data.bin"));
let returned = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4 open:tile:0 esc",
])
.output()
.unwrap();
assert!(
returned.status.success(),
"stderr: {}",
common::support::stderr(&returned)
);
let returned_stdout = String::from_utf8_lossy(&returned.stdout);
assert!(returned_stdout.contains("Treemap: workspace"));
assert!(returned_stdout.contains("Zoom depth: 0"));
assert!(returned_stdout.contains("Selected tile: big"));
}
#[test]
fn tui_replay_open_file_tile_reports_non_drillable() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("single.bin"), b"abcdef");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4 open:tile:0",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Treemap: workspace"));
assert!(stdout.contains("Drillable: no"));
assert!(stdout.contains("single.bin is a file"));
assert!(stdout.contains("Status: single.bin is a file"));
}
#[test]
fn tui_replay_open_other_tile_reports_aggregate_non_drillable() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
for index in 0..28 {
write_fixture_file(root.join(format!("file-{index:02}.bin")), b"x");
}
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--terminal-width",
"100",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4 open:tile:23",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Treemap: workspace"));
assert!(stdout.contains("Status: Aggregate Other tile cannot be opened"));
}
#[test]
fn tui_replay_tab_reaches_treemap_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abcdef");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"tab",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | treemap"));
assert!(stdout.contains("Treemap: workspace"));
}
#[test]
fn tui_replay_semantic_tab_reaches_treemap_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abcdef");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"click:tab:treemap",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | treemap"));
assert!(stdout.contains("Treemap: workspace"));
}
#[test]
fn tui_replay_semantic_row_selects_visible_map_row() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"click:row:1",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout
.lines()
.any(|line| { line.starts_with('>') && line.contains("small.txt") })
);
assert!(stdout.contains("Status: Selected small.txt."));
}
#[test]
fn tui_replay_semantic_distribution_row_filters_map() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("cache.tmp"), b"abcdef");
write_fixture_file(root.join("notes.txt"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"click:tab:extensions click:row:0",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | map"));
assert!(stdout.contains("filter .tmp"));
assert!(stdout.contains("cache.tmp"));
assert!(!stdout.contains("notes.txt"));
}
#[test]
fn tui_replay_semantic_wheel_moves_visible_selection() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"wheel:down",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout
.lines()
.any(|line| { line.starts_with('>') && line.contains("small.txt") })
);
}
#[test]
fn tui_replay_semantic_treemap_tile_selects_visible_row() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"click:tab:treemap click:tile:0",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | treemap"));
assert!(stdout.contains("Status: Selected "));
}
#[test]
fn tui_replay_double_tab_reaches_type_distribution_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abcdef");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"tab tab",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | types"));
assert!(stdout.contains("Types: file kind distribution"));
}
#[test]
fn tui_screen_reader_extension_distribution_omits_visual_bars() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abcdef");
write_fixture_file(root.join("beta.log"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"x",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | extensions"));
assert!(stdout.contains(".bin"));
assert!(stdout.contains(".log"));
assert!(stdout.contains("%"));
assert!(stdout.contains("file"));
assert!(
!stdout.contains("###"),
"screen-reader extension snapshot should not depend on visual bars: {stdout}"
);
}
#[test]
fn tui_replay_can_patch_refresh_selected_directory_without_scan_restore() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("big").join("data.bin"), b"abcdef");
write_fixture_file(root.join("small.txt"), b"x");
let refreshed = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"r",
])
.output()
.unwrap();
assert!(
refreshed.status.success(),
"stderr: {}",
common::support::stderr(&refreshed)
);
let refreshed_stdout = String::from_utf8_lossy(&refreshed.stdout);
assert!(refreshed_stdout.contains("Map: workspace"));
assert!(refreshed_stdout.contains("big"));
assert!(refreshed_stdout.contains("small.txt"));
assert!(refreshed_stdout.contains("Status: Refresh patched "));
let opened = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"r enter",
])
.output()
.unwrap();
assert!(
opened.status.success(),
"stderr: {}",
common::support::stderr(&opened)
);
let opened_stdout = String::from_utf8_lossy(&opened.stdout);
assert!(opened_stdout.contains("Map: big"));
assert!(opened_stdout.contains("data.bin"));
let no_restore = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"r b",
])
.output()
.unwrap();
assert!(
no_restore.status.success(),
"stderr: {}",
common::support::stderr(&no_restore)
);
let no_restore_stdout = String::from_utf8_lossy(&no_restore.stdout);
assert!(no_restore_stdout.contains("Map: workspace"));
assert!(no_restore_stdout.contains("big"));
assert!(no_restore_stdout.contains("small.txt"));
assert!(no_restore_stdout.contains("Status: Refresh patched "));
}
#[test]
fn tui_replay_can_open_history_without_a_terminal() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"g",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | history"));
assert!(stdout.contains("No cleanup history entries yet."));
}
#[test]
fn tui_screen_reader_treemap_omits_visual_bars() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("alpha.bin"), b"abcdef");
write_fixture_file(root.join("beta.log"), b"abc");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--root",
root.to_str().unwrap(),
"--replay-keys",
"4",
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | treemap"));
assert!(stdout.contains("Treemap: workspace"));
assert!(stdout.contains("alpha.bin"));
assert!(stdout.contains("beta.log"));
assert!(stdout.contains("%"));
assert!(
!stdout.contains("###"),
"screen-reader treemap snapshot should not depend on visual bars: {stdout}"
);
}
#[test]
fn tui_screen_reader_once_omits_visual_bars() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(root.join("cache").join("data.bin"), b"abcdef");
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--screen-reader",
"--root",
root.to_str().unwrap(),
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Rebecca TUI | map"));
assert!(stdout.contains("cache"));
assert!(
!stdout.contains("###"),
"screen-reader snapshot should not depend on visual bars: {stdout}"
);
}
#[test]
fn tui_once_respects_hidden_terminal_width_for_ci() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().join("workspace");
write_fixture_file(
root.join("very-long-directory-name-for-width-testing")
.join("data.bin"),
b"abcdef",
);
let output = common::isolated::isolated_rebecca(&temp)
.args([
"tui",
"--once",
"--terminal-width",
"40",
"--root",
root.to_str().unwrap(),
])
.output()
.unwrap();
assert!(
output.status.success(),
"stderr: {}",
common::support::stderr(&output)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout
.lines()
.all(|line| UnicodeWidthStr::width(line) <= 40)
);
}
#[test]
fn tui_rejects_machine_output_modes() {
let output = common::command::rebecca()
.args(["--format", "json", "tui", "--once"])
.output()
.unwrap();
assert!(!output.status.success());
let stderr = common::support::stderr(&output);
assert!(stderr.contains("requires --format human"));
}
#[test]
fn tui_non_tty_rejects_before_replay_or_scan_setup() {
let output = common::command::rebecca()
.args(["tui", "--replay-keys", "not-a-key"])
.output()
.unwrap();
assert!(!output.status.success());
let stderr = common::support::stderr(&output);
assert!(stderr.contains("requires an interactive terminal"));
assert!(!stderr.contains("unknown tui replay key token"));
}