Files
Aram Drevekenin 5254e4fc1d Fix tab close size (#5444)
* fix: properly resize tabs when closing another tab

* rustfmt
2026-08-05 18:54:59 +02:00

185 lines
6.5 KiB
Rust

#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized, start_zellij, Size, PROMPT,
TERMINAL_SIZE,
};
#[test]
fn override_layout_from_default_to_compact() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.override_layout("compact");
let grid_snapshot =
zellij.wait_until("compact bar rendered with session name", |grid_snapshot| {
grid_snapshot.contains("Zellij (test")
&& grid_snapshot.contains("NORMAL")
&& grid_snapshot.contains("Tab #1")
&& !grid_snapshot.status_bar_appears()
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn send_command_through_the_cli() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.run_suspended_command(&["suspended-command"]);
let command_terminal = zellij.expect_pty_spawn();
zellij.wait_until("suspended command pane waiting to run", |grid_snapshot| {
grid_snapshot.contains("<Ctrl-c>")
});
zellij.send_stdin(&keys::ENTER);
zellij.wait_until("command running", |grid_snapshot| {
!grid_snapshot.contains("<Ctrl-c>")
});
command_terminal.output(b"foo\r\n");
zellij.wait_until("first run printed foo", |grid_snapshot| {
grid_snapshot.contains("foo")
});
command_terminal.exit(Some(0));
zellij.wait_until("command pane held again after exit", |grid_snapshot| {
grid_snapshot.contains("EXIT CODE")
});
zellij.send_stdin(&keys::ENTER);
zellij.wait_until("command re-running", |grid_snapshot| {
!grid_snapshot.contains("EXIT CODE")
});
command_terminal.output(b"foo\r\nfoo\r\n");
let grid_snapshot = zellij.wait_until("command re-ran", |grid_snapshot| {
grid_snapshot.text.matches("foo").count() >= 2
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn send_blocking_command_through_the_cli() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let blocking_command = zellij.run_blocking_floating_command(&["blocking-command"]);
let floating_terminal = zellij.expect_pty_spawn();
zellij.wait_until("floating command pane appeared", |grid_snapshot| {
grid_snapshot.contains("PIN")
});
floating_terminal.exit(Some(42));
assert_eq!(blocking_command.wait_for_exit(), 42);
let grid_snapshot = zellij.wait_until("floating pane closed on exit", |grid_snapshot| {
!grid_snapshot.contains("PIN") && grid_snapshot.cursor_is_at(col(2).row(1))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn watcher_client_functionality() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
first_terminal.output(b"\r\nWATCHER_OUTPUT_1\r\n");
zellij.wait_until("first output line", |grid_snapshot| {
grid_snapshot.contains("WATCHER_OUTPUT_1")
});
let watcher = zellij.attach_watcher(TERMINAL_SIZE);
watcher.wait_until("watcher connected and sees the output", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.contains("WATCHER_OUTPUT_1")
});
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
watcher.wait_until("watcher sees the split", |grid_snapshot| {
grid_snapshot.contains("│")
});
let ignored_new_tab_from_watcher = [keys::ctrl('t'), keys::key('n')].concat();
watcher.send_stdin(&ignored_new_tab_from_watcher);
zellij.detach_main_client();
first_terminal.output(b"WATCHER_OUTPUT_2\r\nWATCHER_OUTPUT_3\r\nWATCHER_DONE\r\n");
watcher.wait_until(
"watcher keeps receiving output while no main client is attached",
|grid_snapshot| {
grid_snapshot.contains("WATCHER_DONE")
&& grid_snapshot.contains("│")
&& !grid_snapshot.contains("Tab #2")
},
);
let main = zellij.attach_client(TERMINAL_SIZE);
let main_snapshot = main.wait_until(
"re-attached main converges on the same state",
|grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("WATCHER_DONE")
&& grid_snapshot.contains("│")
},
);
assert_snapshot!(normalized(&main_snapshot));
let watcher_snapshot =
watcher.wait_until("watcher mirrors the re-attached session", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("WATCHER_DONE")
&& grid_snapshot.contains("│")
&& !grid_snapshot.contains("Tab #2")
});
assert_snapshot!(normalized(&watcher_snapshot));
main.quit();
watcher.quit();
zellij.quit();
}
#[test]
fn watcher_larger_than_the_followed_content_is_padded_to_its_own_size() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
first_terminal.output(b"\r\nWATCHER_PADDING\r\n");
zellij.wait_until("followed client rendered", |grid_snapshot| {
grid_snapshot.contains("WATCHER_PADDING")
});
let followed_size = Size {
cols: TERMINAL_SIZE.cols - 20,
rows: TERMINAL_SIZE.rows - 4,
};
zellij.resize(followed_size);
zellij.wait_until(
"followed client re-rendered at its new size",
move |snapshot| {
snapshot.contains("WATCHER_PADDING") && snapshot.row_count() == followed_size.rows
},
);
let watcher = zellij.attach_watcher(Size {
cols: TERMINAL_SIZE.cols + 20,
rows: TERMINAL_SIZE.rows + 6,
});
watcher.wait_until("watcher connected and sees the output", |grid_snapshot| {
grid_snapshot.contains("Ctrl +") && grid_snapshot.contains("WATCHER_PADDING")
});
let clear_below_content = format!("\u{1b}[{};1H\u{1b}[m\u{1b}[J", followed_size.rows + 1);
let clear_to_end_of_content_line =
format!("\u{1b}[1;{}H\u{1b}[m\u{1b}[K", followed_size.cols + 1);
watcher.wait_until_raw_output("watcher output padded to its own size", move |bytes| {
let output = String::from_utf8_lossy(bytes);
output.contains(&clear_below_content) && output.contains(&clear_to_end_of_content_line)
});
watcher.quit();
zellij.quit();
}