tests: add more integration tests (#5308)

* test all the things

* consolidate shared harness

* rustfmt
This commit is contained in:
Aram Drevekenin
2026-06-25 17:09:26 +02:00
committed by GitHub
parent ff0925f2a7
commit 27291bea28
85 changed files with 3501 additions and 438 deletions
+26 -2
View File
@@ -109,6 +109,26 @@ pub struct CursorPosition {
pub y: usize,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Coord {
pub col: usize,
pub row: usize,
}
pub fn col(col: usize) -> CoordBuilder {
CoordBuilder { col }
}
pub struct CoordBuilder {
col: usize,
}
impl CoordBuilder {
pub fn row(self, row: usize) -> Coord {
Coord { col: self.col, row }
}
}
#[derive(Clone, Debug)]
pub struct GridSnapshot {
pub text: String,
@@ -119,8 +139,12 @@ impl GridSnapshot {
pub fn contains(&self, needle: &str) -> bool {
self.text.contains(needle)
}
pub fn cursor_is_at(&self, x: usize, y: usize) -> bool {
self.cursor == Some(CursorPosition { x, y })
pub fn cursor_is_at(&self, coord: Coord) -> bool {
self.cursor
== Some(CursorPosition {
x: coord.col,
y: coord.row,
})
}
pub fn status_bar_appears(&self) -> bool {
self.text.contains("Ctrl +") && self.text.contains("LOCK")
+47
View File
@@ -0,0 +1,47 @@
use crate::{col, keys, FakePtyHandle, Size, TestRunner, TestSession};
pub const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
};
pub const PROMPT: &[u8] = b"$ ";
pub fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
}
pub fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(col(3).row(2))
},
);
terminal
}
pub fn split_right_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(63).row(2))
});
terminal
}
pub fn split_down_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('d'));
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("lower terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(13))
});
terminal
}
+10 -52
View File
@@ -1,63 +1,21 @@
const ESC_BYTE: u8 = 0x1b;
const fn ctrl(character: u8) -> [u8; 1] {
[character & 0x1f]
pub const fn ctrl(character: char) -> [u8; 1] {
[(character as u8) & 0x1f]
}
const fn alt(character: u8) -> [u8; 2] {
[ESC_BYTE, character]
pub const fn alt(character: char) -> [u8; 2] {
[ESC_BYTE, character as u8]
}
pub const fn key(character: char) -> [u8; 1] {
[character as u8]
}
pub const QUIT: [u8; 1] = ctrl(b'q');
pub const ESC: [u8; 1] = [ESC_BYTE];
pub const ENTER: [u8; 1] = [b'\r'];
pub const ESC: [u8; 1] = [ESC_BYTE];
pub const SPACE: [u8; 1] = [b' '];
pub const LOCK_MODE: [u8; 1] = ctrl(b'g');
pub const MOVE_FOCUS_LEFT_IN_NORMAL_MODE: [u8; 2] = alt(b'h');
pub const MOVE_FOCUS_RIGHT_IN_NORMAL_MODE: [u8; 2] = alt(b'l');
pub const PANE_MODE: [u8; 1] = ctrl(b'p');
pub const TMUX_MODE: [u8; 1] = ctrl(b'b');
pub const SPAWN_TERMINAL_IN_PANE_MODE: [u8; 1] = [b'n'];
pub const MOVE_FOCUS_IN_PANE_MODE: [u8; 1] = [b'p'];
pub const SPLIT_DOWN_IN_PANE_MODE: [u8; 1] = [b'd'];
pub const SPLIT_RIGHT_IN_PANE_MODE: [u8; 1] = [b'r'];
pub const SPLIT_RIGHT_IN_TMUX_MODE: [u8; 1] = [b'%'];
pub const TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE: [u8; 1] = [b'f'];
pub const TOGGLE_FLOATING_PANES: [u8; 1] = [b'w'];
pub const CLOSE_PANE_IN_PANE_MODE: [u8; 1] = [b'x'];
pub const MOVE_FOCUS_DOWN_IN_PANE_MODE: [u8; 1] = [b'j'];
pub const MOVE_FOCUS_UP_IN_PANE_MODE: [u8; 1] = [b'k'];
pub const MOVE_FOCUS_LEFT_IN_PANE_MODE: [u8; 1] = [b'h'];
pub const MOVE_FOCUS_RIGHT_IN_PANE_MODE: [u8; 1] = [b'l'];
pub const RENAME_PANE_MODE: [u8; 1] = [b'c'];
pub const SCROLL_MODE: [u8; 1] = ctrl(b's');
pub const SCROLL_UP_IN_SCROLL_MODE: [u8; 1] = [b'k'];
pub const SCROLL_DOWN_IN_SCROLL_MODE: [u8; 1] = [b'j'];
pub const SCROLL_PAGE_UP_IN_SCROLL_MODE: [u8; 1] = ctrl(b'b');
pub const SCROLL_PAGE_DOWN_IN_SCROLL_MODE: [u8; 1] = ctrl(b'f');
pub const EDIT_SCROLLBACK: [u8; 1] = [b'e'];
pub const RESIZE_MODE: [u8; 1] = ctrl(b'n');
pub const RESIZE_DOWN_IN_RESIZE_MODE: [u8; 1] = [b'j'];
pub const RESIZE_UP_IN_RESIZE_MODE: [u8; 1] = [b'k'];
pub const RESIZE_LEFT_IN_RESIZE_MODE: [u8; 1] = [b'h'];
pub const RESIZE_RIGHT_IN_RESIZE_MODE: [u8; 1] = [b'l'];
pub const TAB_MODE: [u8; 1] = ctrl(b't');
pub const NEW_TAB_IN_TAB_MODE: [u8; 1] = [b'n'];
pub const SWITCH_NEXT_TAB_IN_TAB_MODE: [u8; 1] = [b'l'];
pub const SWITCH_PREV_TAB_IN_TAB_MODE: [u8; 1] = [b'h'];
pub const CLOSE_TAB_IN_TAB_MODE: [u8; 1] = [b'x'];
pub const RENAME_TAB_MODE: [u8; 1] = [b'r'];
pub const MOVE_TAB_LEFT: [u8; 2] = alt(b'i');
pub const MOVE_TAB_RIGHT: [u8; 2] = alt(b'o');
pub const SESSION_MODE: [u8; 1] = ctrl(b'o');
pub const DETACH_IN_SESSION_MODE: [u8; 1] = [b'd'];
pub const TAB: [u8; 1] = [b'\t'];
pub const BRACKETED_PASTE_START: [u8; 6] = *b"\x1b[200~";
pub const BRACKETED_PASTE_END: [u8; 6] = *b"\x1b[201~";
+6 -1
View File
@@ -4,12 +4,17 @@ pub mod client_screen;
pub mod fake_client_os_api;
pub mod fake_pty;
pub mod fake_server_os_api;
pub mod harness;
pub mod keys;
pub mod runner;
pub mod test_env;
pub use client_screen::{ClientScreen, CursorPosition, GridSnapshot};
pub use client_screen::{col, ClientScreen, Coord, CoordBuilder, CursorPosition, GridSnapshot};
pub use fake_pty::FakePtyHandle;
pub use harness::{
claim_first_terminal_and_wait_for_prompt, split_down_and_wait_for_prompt,
split_right_and_wait_for_prompt, start_zellij, PROMPT, TERMINAL_SIZE,
};
pub use runner::{normalized, TestClient, TestRunner, TestSession};
pub use zellij_utils::data::LayoutInfo;
pub use zellij_utils::pane_size::Size;
+13 -5
View File
@@ -220,7 +220,7 @@ impl TestClient {
}
pub fn quit(mut self) {
self.send_stdin(&keys::QUIT);
self.send_stdin(&keys::ctrl('q'));
self.join();
}
@@ -477,8 +477,8 @@ impl TestSession {
pub fn detach_main_client(&mut self) {
let connected_clients_before_detach = self.fake_server_os_api.connected_client_count();
self.send_stdin(&keys::SESSION_MODE);
self.send_stdin(&keys::DETACH_IN_SESSION_MODE);
self.send_stdin(&keys::ctrl('o'));
self.send_stdin(&keys::key('d'));
self.main_client.join();
self.wait_for_server_to_release_a_client(connected_clients_before_detach);
}
@@ -498,7 +498,7 @@ impl TestSession {
pub fn quit(&mut self) {
if self.main_client.thread.is_some() {
self.send_stdin(&keys::QUIT);
self.send_stdin(&keys::ctrl('q'));
self.main_client.join();
}
if let Some(server_thread) = self.server_thread.lock().unwrap().take() {
@@ -511,7 +511,7 @@ impl TestSession {
.main_client
.fake_client_handle
.stdin_tx
.send(keys::QUIT.to_vec());
.send(keys::ctrl('q').to_vec());
}
}
@@ -526,9 +526,17 @@ impl Drop for TestSession {
pub fn normalized(grid_snapshot: &GridSnapshot) -> String {
let text = replace_unique_session_name(&grid_snapshot.text);
let text = strip_swap_layout_indication(&text);
let text = strip_tip_indication(&text);
strip_trailing_whitespace(&text)
}
fn strip_tip_indication(text: &str) -> String {
regex::Regex::new(r" Tip: [^\n]*")
.unwrap()
.replace_all(text, "")
.to_string()
}
fn replace_unique_session_name(text: &str) -> String {
regex::Regex::new(r"Zellij \(test-\d+\)")
.unwrap()
+8 -43
View File
@@ -1,16 +1,10 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, FakePtyHandle, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized,
split_right_and_wait_for_prompt, Size, TestRunner, PROMPT, TERMINAL_SIZE,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
const RIGHT_PANE_PROMPT_X: usize = 63;
const CHANGED_KEYS_CONFIG: &str = r#"
keybinds clear-defaults=true {
@@ -27,38 +21,12 @@ keybinds clear-defaults=true {
}
"#;
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
}
fn split_right_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
});
terminal
}
#[test]
fn exit_zellij() {
let zellij = TestRunner::new(TERMINAL_SIZE).start();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::QUIT);
zellij.send_stdin(&keys::ctrl('q'));
zellij.wait_until("zellij said goodbye", |grid_snapshot| {
!grid_snapshot.status_bar_appears() && grid_snapshot.contains("Bye from Zellij!")
@@ -86,7 +54,7 @@ fn resize_terminal_window() {
zellij.wait_until("app re-rendered at the new window size", |grid_snapshot| {
grid_snapshot.contains("Ctrl +")
&& grid_snapshot.tab_bar_appears()
&& grid_snapshot.cursor_is_at(53, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(53).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -102,10 +70,7 @@ fn status_bar_loads_custom_keybindings() {
let grid_snapshot = zellij.wait_until(
"status bar reflects the custom keybindings",
|grid_snapshot| {
grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.contains("LOCK")
},
|grid_snapshot| grid_snapshot.cursor_is_at(col(3).row(2)) && grid_snapshot.contains("LOCK"),
);
assert_snapshot!(normalized(&grid_snapshot));
}
@@ -142,8 +107,8 @@ fn edit_scrollback() {
grid_snapshot.contains("SCROLLBACK_MARKER_TWO")
});
zellij.send_stdin(&keys::SCROLL_MODE);
zellij.send_stdin(&keys::EDIT_SCROLLBACK);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('e'));
zellij.expect_pty_spawn();
let grid_snapshot = zellij.wait_until("scrollback editor pane open", |grid_snapshot| {
+9 -51
View File
@@ -1,54 +1,14 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, FakePtyHandle, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized,
split_right_and_wait_for_prompt, start_zellij, FakePtyHandle, TestSession,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
const RIGHT_PANE_PROMPT_X: usize = 63;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
}
fn split_pane_right(zellij: &TestSession) {
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
}
fn split_right_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
split_pane_right(zellij);
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
});
terminal
}
fn resize_focused_pane_left(zellij: &TestSession) {
zellij.send_stdin(&keys::RESIZE_MODE);
zellij.send_stdin(&keys::RESIZE_LEFT_IN_RESIZE_MODE);
zellij.send_stdin(&keys::ctrl('n'));
zellij.send_stdin(&keys::key('h'));
zellij.send_stdin(&keys::ENTER);
}
@@ -63,7 +23,7 @@ fn starts_with_one_terminal() {
let grid_snapshot = zellij.wait_until("steady loaded state", |grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -75,8 +35,7 @@ fn split_terminals_vertically() {
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
let grid_snapshot = zellij.wait_until("split rendered in normal mode", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(63).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -99,7 +58,7 @@ fn resize_pane() {
let cursor_shift_left = (resized_cols.saturating_sub(initial_cols)) as usize;
let grid_snapshot = zellij.wait_until("resized layout in normal mode", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X - cursor_shift_left, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(63 - cursor_shift_left).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -120,8 +79,7 @@ fn command_pane_closes_on_exit() {
zellij.wait_until(
"right terminal closed, focus back on first",
|grid_snapshot| {
!grid_snapshot.contains("about to exit")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
!grid_snapshot.contains("about to exit") && grid_snapshot.cursor_is_at(col(3).row(2))
},
);
zellij.quit();
+7 -28
View File
@@ -1,30 +1,10 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, FakePtyHandle, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized, start_zellij, PROMPT,
TERMINAL_SIZE,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("first terminal prompt rendered", |grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
});
terminal
}
#[test]
fn override_layout_from_default_to_compact() {
@@ -95,8 +75,7 @@ fn send_blocking_command_through_the_cli() {
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(FIRST_PANE_PROMPT_X, PROMPT_ROW)
!grid_snapshot.contains("PIN") && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -116,15 +95,15 @@ fn watcher_client_functionality() {
grid_snapshot.status_bar_appears() && grid_snapshot.contains("WATCHER_OUTPUT_1")
});
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
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::TAB_MODE, keys::NEW_TAB_IN_TAB_MODE].concat();
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();
+31 -48
View File
@@ -2,34 +2,12 @@
use insta::assert_snapshot;
use zellij_integration_tests::{
keys, normalized, FakePtyHandle, GridSnapshot, Size, TestRunner, TestSession,
claim_first_terminal_and_wait_for_prompt, col, keys, normalized, start_zellij, GridSnapshot,
TestRunner, PROMPT, TERMINAL_SIZE,
};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
const RIGHT_PANE_PROMPT_X: usize = 63;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
fn session_name_rendered(grid_snapshot: &GridSnapshot) -> bool {
grid_snapshot.contains("(test-")
}
#[test]
@@ -43,19 +21,20 @@ fn mirrored_sessions() {
second_client.wait_until("second client loaded on the first tab", |grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
second_client.send_stdin(&keys::PANE_MODE);
second_client.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
second_client.send_stdin(&keys::ctrl('p'));
second_client.send_stdin(&keys::key('r'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
let mirror_focused_right_pane = |grid_snapshot: &GridSnapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Pane #2")
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(63).row(2))
};
let main_grid = zellij.wait_until(
"main client follows the second client's focus into the split it never asked for",
@@ -84,17 +63,19 @@ fn multiple_users_in_same_pane_and_tab() {
let second_grid =
second_client.wait_until("second client shares the focused pane", |grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("MY FOCUS")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
let main_grid = zellij.wait_until(
"main client shows the shared-focus indicator",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("MY FOCUS")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
},
);
assert_snapshot!(normalized(&main_grid));
@@ -110,12 +91,11 @@ fn multiple_users_in_different_panes_and_same_tab() {
let second_client = zellij.attach_client(TERMINAL_SIZE);
second_client.wait_until("second client loaded on the first tab", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
second_client.send_stdin(&keys::PANE_MODE);
second_client.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
second_client.send_stdin(&keys::ctrl('p'));
second_client.send_stdin(&keys::key('r'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
@@ -123,17 +103,19 @@ fn multiple_users_in_different_panes_and_same_tab() {
"second client focused the new right pane",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(63).row(2))
},
);
let main_grid = zellij.wait_until(
"main client sees the second client's split while staying on the left pane",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.contains("Pane #2")
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
},
);
assert_snapshot!(normalized(&main_grid));
@@ -149,29 +131,30 @@ fn multiple_users_in_different_tabs() {
let second_client = zellij.attach_client(TERMINAL_SIZE);
second_client.wait_until("second client loaded on the first tab", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
second_client.send_stdin(&keys::TAB_MODE);
second_client.send_stdin(&keys::NEW_TAB_IN_TAB_MODE);
second_client.send_stdin(&keys::ctrl('t'));
second_client.send_stdin(&keys::key('n'));
let second_tab_terminal = zellij.expect_pty_spawn();
second_tab_terminal.output(PROMPT);
let second_grid =
second_client.wait_until("second client moved to the new tab", |grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
let main_grid = zellij.wait_until(
"main client sees the new tab while staying on the first tab",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
},
);
assert_snapshot!(normalized(&main_grid));
@@ -185,13 +168,12 @@ fn detach_and_attach_session() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(63).row(2))
});
right_terminal.output(b"I am some text");
@@ -206,6 +188,7 @@ fn detach_and_attach_session() {
"reattached client sees the restored split and text",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& session_name_rendered(grid_snapshot)
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Pane #2")
&& grid_snapshot.contains("I am some text")
+136
View File
@@ -0,0 +1,136 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized,
split_right_and_wait_for_prompt, start_zellij,
};
#[test]
fn quit_with_keybinding() {
let zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('q'));
zellij.wait_until("zellij exited after the quit keybinding", |grid_snapshot| {
grid_snapshot.contains("Bye from Zellij!")
});
}
#[test]
fn write_byte_to_focused_pane_via_tmux_mode() {
let mut zellij = start_zellij();
let terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('b'));
zellij.send_stdin(&keys::ctrl('b'));
let stdin_bytes = terminal.wait_for_stdin("ctrl-b byte reached the pane", |stdin_bytes| {
stdin_bytes.contains(&0x02)
});
assert!(stdin_bytes.contains(&0x02));
let grid_snapshot = zellij.wait_until("mode settled back to normal", |grid_snapshot| {
grid_snapshot.status_bar_appears()
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn focus_next_pane_via_tmux_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('b'));
zellij.send_stdin(&keys::key('o'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focus cycled to the other pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_group_marking() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::alt('P'));
let grid_snapshot = zellij.wait_until("group marking engaged", |grid_snapshot| {
grid_snapshot.contains("GROUP ACTIONS")
&& grid_snapshot.contains("SELECTED PANE")
&& grid_snapshot.contains("Follow Focus")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_pane_in_group() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::alt('p'));
let grid_snapshot = zellij.wait_until("pane added to group", |grid_snapshot| {
grid_snapshot.contains("GROUP ACTIONS")
&& grid_snapshot.contains("SELECTED PANE")
&& grid_snapshot.contains("Follow Focus")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn next_swap_layout() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.wait_until("swap layout at base", |grid_snapshot| {
grid_snapshot.contains("BASE")
});
zellij.send_stdin(&keys::alt(']'));
zellij.wait_until("swap layout advanced to vertical", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("VERTICAL")
&& !grid_snapshot.contains("BASE")
});
zellij.send_stdin(&keys::alt(']'));
let grid_snapshot = zellij.wait_until("swap layout advanced to horizontal", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& !grid_snapshot.contains("VERTICAL")
&& grid_snapshot.contains("HORIZONTAL")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn previous_swap_layout() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.wait_until("swap layout at base", |grid_snapshot| {
grid_snapshot.contains("BASE")
});
zellij.send_stdin(&keys::alt('['));
let grid_snapshot =
zellij.wait_until("swap layout moved back to horizontal", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("HORIZONTAL")
&& !grid_snapshot.contains("BASE")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
+152 -40
View File
@@ -1,33 +1,147 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, FakePtyHandle, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized, start_zellij, PROMPT,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
const RIGHT_PANE_PROMPT_X: usize = 63;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
#[test]
fn switch_to_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
let grid_snapshot = zellij.wait_until("pane mode active", |grid_snapshot| {
grid_snapshot.contains("PANE") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
#[test]
fn switch_to_tab_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('t'));
let grid_snapshot = zellij.wait_until("tab mode active", |grid_snapshot| {
grid_snapshot.contains("TAB") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn switch_to_resize_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('n'));
let grid_snapshot = zellij.wait_until("resize mode active", |grid_snapshot| {
grid_snapshot.contains("RESIZE") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn switch_to_move_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('h'));
let grid_snapshot = zellij.wait_until("move mode active", |grid_snapshot| {
grid_snapshot.contains("MOVE") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn switch_to_scroll_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
let grid_snapshot = zellij.wait_until("scroll mode active", |grid_snapshot| {
grid_snapshot.contains("Edit") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn switch_to_session_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('o'));
let grid_snapshot = zellij.wait_until("session mode active", |grid_snapshot| {
grid_snapshot.contains("Detach") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn enter_search_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('s'));
let grid_snapshot = zellij.wait_until("search input mode active", |grid_snapshot| {
grid_snapshot.contains("ENTERING SEARCH TERM") && !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn switch_to_search_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('s'));
zellij.wait_until("search input mode active", |grid_snapshot| {
grid_snapshot.contains("ENTERING SEARCH TERM")
});
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("search navigation mode active", |grid_snapshot| {
grid_snapshot.contains("SEARCHING")
&& grid_snapshot.contains("Case")
&& !grid_snapshot.contains("LOCK")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn return_to_normal_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.wait_until("pane mode active", |grid_snapshot| {
grid_snapshot.contains("PANE") && !grid_snapshot.contains("LOCK")
});
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("returned to normal mode", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
@@ -35,13 +149,13 @@ fn lock_mode() {
let mut zellij = start_zellij();
let terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::LOCK_MODE);
zellij.send_stdin(&keys::ctrl('g'));
zellij.wait_until("interface locked", |grid_snapshot| {
grid_snapshot.contains("LOCK") && !grid_snapshot.contains("PANE")
});
zellij.send_stdin(&keys::TAB_MODE);
zellij.send_stdin(&keys::NEW_TAB_IN_TAB_MODE);
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('n'));
zellij.send_stdin(b"abc");
terminal.wait_for_stdin("forwarded keys reached the pane", |stdin_bytes| {
@@ -55,7 +169,7 @@ fn lock_mode() {
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.send_stdin(&keys::LOCK_MODE);
zellij.send_stdin(&keys::ctrl('g'));
zellij.wait_until("interface unlocked", |grid_snapshot| {
grid_snapshot.contains("PANE")
});
@@ -67,14 +181,13 @@ fn tmux_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::TMUX_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_TMUX_MODE);
zellij.send_stdin(&keys::ctrl('b'));
zellij.send_stdin(&keys::key('%'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
let grid_snapshot = zellij.wait_until("right terminal opened via tmux mode", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(63).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -86,8 +199,8 @@ fn bracketed_paste() {
let terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::BRACKETED_PASTE_START);
zellij.send_stdin(&keys::TAB_MODE);
zellij.send_stdin(&keys::NEW_TAB_IN_TAB_MODE);
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('n'));
zellij.send_stdin(b"abc");
zellij.send_stdin(&keys::BRACKETED_PASTE_END);
@@ -108,13 +221,12 @@ fn scrolling_inside_a_pane() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(63).row(2))
});
for line in 1..=21 {
@@ -124,9 +236,9 @@ fn scrolling_inside_a_pane() {
grid_snapshot.contains("line21")
});
zellij.send_stdin(&keys::SCROLL_MODE);
zellij.send_stdin(&keys::SCROLL_UP_IN_SCROLL_MODE);
zellij.send_stdin(&keys::SCROLL_UP_IN_SCROLL_MODE);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('k'));
zellij.send_stdin(&keys::key('k'));
let grid_snapshot =
zellij.wait_until("scrolled up one line inside the pane", |grid_snapshot| {
+9 -42
View File
@@ -1,16 +1,10 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, FakePtyHandle, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized,
split_right_and_wait_for_prompt, TestRunner, TestSession, PROMPT, TERMINAL_SIZE,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
const RIGHT_PANE_PROMPT_X: usize = 63;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE)
@@ -22,32 +16,6 @@ fn sgr_mouse_report(column: usize, line: usize, button: u8) -> Vec<u8> {
format!("\u{1b}[<{};{};{}M", button, column, line).into_bytes()
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
}
fn split_right_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
});
terminal
}
#[test]
fn focus_pane_with_mouse() {
let mut zellij = start_zellij();
@@ -56,8 +24,7 @@ fn focus_pane_with_mouse() {
zellij.send_stdin(&sgr_mouse_report(2, 5, 0));
let grid_snapshot = zellij.wait_until("focus moved back to the left pane", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -91,8 +58,8 @@ fn pin_floating_panes() {
let mut zellij = start_zellij();
let tiled_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::TOGGLE_FLOATING_PANES);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('w'));
let floating_terminal = zellij.expect_pty_spawn();
floating_terminal.output(PROMPT);
zellij.wait_until("floating pane shows the unpinned button", |grid_snapshot| {
@@ -104,14 +71,14 @@ fn pin_floating_panes() {
grid_snapshot.contains("PIN [+]")
});
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::TOGGLE_FLOATING_PANES);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('w'));
zellij.wait_until(
"focus settled on the tiled pane while the pinned pane stays up",
|grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("PIN [+]")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
},
);
+395 -68
View File
@@ -1,46 +1,11 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, FakePtyHandle, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized,
split_down_and_wait_for_prompt, split_right_and_wait_for_prompt, start_zellij, Coord, Size,
TestRunner, TestSession, PROMPT, TERMINAL_SIZE,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
const RIGHT_PANE_PROMPT_X: usize = 63;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
}
fn split_right_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("right terminal prompt rendered", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
});
terminal
}
#[test]
fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
@@ -48,12 +13,12 @@ fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until("first terminal prompt rendered", |grid_snapshot| {
grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.cursor_is_at(col(3).row(2))
});
let (width_before_split, _) = terminal.wait_for_size("first terminal sized", |_, _| true);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
terminal.output(b"done");
let tab_bar_glyph = '\u{e0b0}';
@@ -79,18 +44,16 @@ fn key_after_mode_switch_is_interpreted_in_new_mode_not_leaked_to_pane() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let second_terminal = zellij.expect_pty_spawn();
second_terminal.output(PROMPT);
zellij.wait_until("split-right interpreted in pane mode", |grid_snapshot| {
grid_snapshot.cursor_is_at(RIGHT_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.cursor_is_at(col(63).row(2))
});
assert!(!first_terminal
.stdin_bytes()
.contains(&keys::SPLIT_RIGHT_IN_PANE_MODE[0]));
assert!(!first_terminal.stdin_bytes().contains(&keys::key('r')[0]));
zellij.quit();
}
@@ -100,11 +63,11 @@ fn toggle_pane_fullscreen() {
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('f'));
let grid_snapshot = zellij.wait_until("focused pane is fullscreen", |grid_snapshot| {
grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.cursor_is_at(col(3).row(2))
&& grid_snapshot.contains("LOCK")
&& grid_snapshot.contains("(FULLSCREEN)")
});
@@ -118,13 +81,12 @@ fn close_pane() {
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::CLOSE_PANE_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('x'));
let grid_snapshot =
zellij.wait_until("right pane closed, focus back on first", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -135,8 +97,8 @@ fn closing_last_pane_exits_zellij() {
let zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::CLOSE_PANE_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('x'));
zellij.wait_until(
"zellij exited after closing the last pane",
@@ -154,8 +116,7 @@ fn pane_closes_when_its_process_exits() {
let grid_snapshot =
zellij.wait_until("right pane closed, focus back on first", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -166,13 +127,13 @@ fn toggle_floating_panes() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::TOGGLE_FLOATING_PANES);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('w'));
let floating_terminal = zellij.expect_pty_spawn();
floating_terminal.output(PROMPT);
let grid_snapshot = zellij.wait_until("floating pane appeared", |grid_snapshot| {
grid_snapshot.cursor_is_at(33, 8)
grid_snapshot.cursor_is_at(col(33).row(8))
&& grid_snapshot.contains("STAGGERED")
&& grid_snapshot.contains("LOCK")
});
@@ -185,8 +146,8 @@ fn undo_rename_pane() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::RENAME_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('c'));
zellij.send_stdin(b"aa");
zellij.send_stdin(&keys::ESC);
zellij.send_stdin(&keys::ESC);
@@ -198,6 +159,370 @@ fn undo_rename_pane() {
zellij.quit();
}
fn spawn_second_pane_and_wait_for_grid(
zellij: &TestSession,
prompt: Coord,
) -> zellij_integration_tests::GridSnapshot {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"second pane spawned and prompt rendered",
move |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Pane #2")
&& grid_snapshot.cursor_is_at(prompt)
},
)
}
fn appears_in_order(
grid_snapshot: &zellij_integration_tests::GridSnapshot,
labels: &[&str],
) -> bool {
let mut search_from = 0;
for label in labels {
match grid_snapshot.text[search_from..].find(label) {
Some(offset) => search_from += offset + label.len(),
None => return false,
}
}
true
}
#[test]
fn move_focus_up_in_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_down_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('k'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focus moved to the upper pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_focus_down_in_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_down_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('k'));
zellij.wait_until("focus moved to the upper pane", |grid_snapshot| {
grid_snapshot.cursor_is_at(col(3).row(2))
});
zellij.send_stdin(&keys::key('j'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focus moved back to the lower pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(13))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_pane_swaps_with_neighbor() {
let mut zellij = start_zellij();
let left_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
left_terminal.output(b"AAA");
right_terminal.output(b"BBB");
zellij.wait_until("both panes labelled left to right", |grid_snapshot| {
appears_in_order(grid_snapshot, &["AAA", "BBB"])
});
zellij.send_stdin(&keys::ctrl('h'));
zellij.send_stdin(&keys::key('n'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focused pane swapped to the left", |grid_snapshot| {
appears_in_order(grid_snapshot, &["BBB", "AAA"]) && grid_snapshot.status_bar_appears()
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_pane_backwards_swaps_with_neighbor() {
let mut zellij = start_zellij();
let left_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
left_terminal.output(b"AAA");
right_terminal.output(b"BBB");
zellij.wait_until("both panes labelled left to right", |grid_snapshot| {
appears_in_order(grid_snapshot, &["AAA", "BBB"])
});
zellij.send_stdin(&keys::ctrl('h'));
zellij.send_stdin(&keys::key('p'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focused pane swapped backwards", |grid_snapshot| {
appears_in_order(grid_snapshot, &["BBB", "AAA"]) && grid_snapshot.status_bar_appears()
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_pane_left() {
let mut zellij = start_zellij();
let left_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
left_terminal.output(b"AAA");
right_terminal.output(b"BBB");
zellij.wait_until("both panes labelled left to right", |grid_snapshot| {
appears_in_order(grid_snapshot, &["AAA", "BBB"])
});
zellij.send_stdin(&keys::ctrl('h'));
zellij.send_stdin(&keys::key('h'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focused pane moved to the left", |grid_snapshot| {
appears_in_order(grid_snapshot, &["BBB", "AAA"]) && grid_snapshot.status_bar_appears()
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_pane_down() {
let mut zellij = start_zellij();
let upper_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
let lower_terminal = split_down_and_wait_for_prompt(&zellij);
upper_terminal.output(b"AAA");
lower_terminal.output(b"BBB");
zellij.wait_until("both panes labelled top to bottom", |grid_snapshot| {
appears_in_order(grid_snapshot, &["AAA", "BBB"])
});
zellij.send_stdin(&keys::ctrl('h'));
zellij.send_stdin(&keys::key('k'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focused pane moved upward", |grid_snapshot| {
appears_in_order(grid_snapshot, &["BBB", "AAA"]) && grid_snapshot.status_bar_appears()
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_pane_embed_or_floating() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('e'));
let grid_snapshot = zellij.wait_until("focused pane became floating", |grid_snapshot| {
grid_snapshot.contains("STAGGERED")
&& grid_snapshot.contains("LOCK")
&& grid_snapshot.cursor_is_at(col(33).row(8))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_pane_pinned() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('w'));
let floating_terminal = zellij.expect_pty_spawn();
floating_terminal.output(PROMPT);
zellij.wait_until("floating pane appeared", |grid_snapshot| {
grid_snapshot.contains("STAGGERED")
});
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('i'));
let grid_snapshot = zellij.wait_until("floating pane pinned", |grid_snapshot| {
grid_snapshot.contains("PIN [+]")
&& grid_snapshot.contains("LOCK")
&& grid_snapshot.cursor_is_at(col(33).row(8))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_focus_or_tab_moves_focus_between_panes() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::alt('h'));
let grid_snapshot = zellij.wait_until("focus moved to the left pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_focus_or_tab_switches_tab_when_single_pane() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
first_terminal.output(b"oneone");
zellij.wait_until("first tab pane labelled", |grid_snapshot| {
grid_snapshot.contains("oneone")
});
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('n'));
let second_terminal = zellij.expect_pty_spawn();
second_terminal.output(PROMPT);
zellij.wait_until("second tab focused, first tab hidden", |grid_snapshot| {
grid_snapshot.contains("Tab #2") && !grid_snapshot.contains("oneone")
});
zellij.send_stdin(&keys::alt('h'));
let grid_snapshot = zellij
.wait_until("focus switched back to the first tab", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.contains("oneone")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn new_pane_in_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('n'));
let grid_snapshot = spawn_second_pane_and_wait_for_grid(&zellij, col(63).row(2));
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn new_pane_in_normal_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::alt('n'));
let grid_snapshot = spawn_second_pane_and_wait_for_grid(&zellij, col(63).row(2));
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn split_pane_downward() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('d'));
let grid_snapshot = spawn_second_pane_and_wait_for_grid(&zellij, col(3).row(13));
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn new_stacked_pane() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('s'));
let grid_snapshot = spawn_second_pane_and_wait_for_grid(&zellij, col(3).row(3));
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_focus_left_in_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('h'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focus moved to the left pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn move_focus_right_in_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('h'));
zellij.wait_until("focus moved to the left pane", |grid_snapshot| {
grid_snapshot.cursor_is_at(col(3).row(2))
});
zellij.send_stdin(&keys::key('l'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focus moved back to the right pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(63).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn switch_focus_in_pane_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('p'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("focus switched to the other pane", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_pane_frames() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('z'));
let grid_snapshot = zellij.wait_until("pane frames removed from both panes", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& !grid_snapshot.contains("Pane #1")
&& !grid_snapshot.contains("Pane #2")
&& grid_snapshot.cursor_is_at(col(62).row(1))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn start_without_pane_frames() {
let mut zellij = TestRunner::new(TERMINAL_SIZE)
@@ -210,18 +535,20 @@ fn start_without_pane_frames() {
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(2, 1)
&& grid_snapshot.cursor_is_at(col(2).row(1))
},
);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let right_terminal = zellij.expect_pty_spawn();
right_terminal.output(PROMPT);
let grid_snapshot = zellij.wait_until(
"right frameless terminal prompt rendered",
|grid_snapshot| grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(62, 1),
|grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.cursor_is_at(col(62).row(1))
},
);
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
+1 -6
View File
@@ -1,12 +1,7 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{normalized, Size, TestRunner};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
};
use zellij_integration_tests::{normalized, TestRunner, TERMINAL_SIZE};
fn load_background_plugin_config() -> String {
let plugin_path = format!(
+277
View File
@@ -0,0 +1,277 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, col, keys, normalized,
split_down_and_wait_for_prompt, split_right_and_wait_for_prompt, start_zellij, FakePtyHandle,
GridSnapshot, TestSession,
};
fn focus_left_pane(zellij: &TestSession) {
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('h'));
zellij.wait_until("focus moved to the left pane", |grid_snapshot| {
grid_snapshot.cursor_is_at(col(3).row(2))
});
}
fn focus_upper_pane(zellij: &TestSession) {
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('k'));
zellij.wait_until("focus moved to the upper pane", |grid_snapshot| {
grid_snapshot.cursor_is_at(col(3).row(2))
});
}
fn resize_in_resize_mode(zellij: &TestSession, key: &[u8]) {
zellij.send_stdin(&keys::ctrl('n'));
zellij.send_stdin(key);
zellij.send_stdin(&keys::ENTER);
}
fn width(terminal: &FakePtyHandle, what: &str) -> u16 {
terminal.wait_for_size(what, |_, _| true).0
}
fn height(terminal: &FakePtyHandle, what: &str) -> u16 {
terminal.wait_for_size(what, |_, _| true).1
}
fn pane_two_header_column(grid_snapshot: &GridSnapshot) -> Option<usize> {
grid_snapshot.lines().into_iter().find_map(|line| {
line.find("Pane #2")
.map(|byte_index| line[..byte_index].chars().count())
})
}
fn pane_two_header_row(grid_snapshot: &GridSnapshot) -> Option<usize> {
grid_snapshot
.lines()
.into_iter()
.position(|line| line.contains("Pane #2"))
}
fn vertical_boundary_column(zellij: &TestSession) -> usize {
pane_two_header_column(&zellij.snapshot()).expect("vertical pane boundary rendered")
}
fn horizontal_boundary_row(zellij: &TestSession) -> usize {
pane_two_header_row(&zellij.snapshot()).expect("horizontal pane boundary rendered")
}
#[test]
fn resize_increase_right() {
let mut zellij = start_zellij();
let left_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
focus_left_pane(&zellij);
let initial_cols = width(&left_terminal, "left terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
resize_in_resize_mode(&zellij, &keys::key('l'));
left_terminal.wait_for_size("left terminal grew rightward", |cols, _| {
cols > initial_cols
});
let grid_snapshot = zellij.wait_until("pane boundary moved right", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column > initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_decrease_left() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
let initial_cols = width(&right_terminal, "right terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
resize_in_resize_mode(&zellij, &keys::key('H'));
right_terminal.wait_for_size("right terminal shrank", |cols, _| cols < initial_cols);
let grid_snapshot = zellij.wait_until("pane boundary moved right", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column > initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_decrease_right() {
let mut zellij = start_zellij();
let left_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
split_right_and_wait_for_prompt(&zellij);
focus_left_pane(&zellij);
let initial_cols = width(&left_terminal, "left terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
resize_in_resize_mode(&zellij, &keys::key('L'));
left_terminal.wait_for_size("left terminal shrank", |cols, _| cols < initial_cols);
let grid_snapshot = zellij.wait_until("pane boundary moved left", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column < initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_increase_down() {
let mut zellij = start_zellij();
let upper_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
split_down_and_wait_for_prompt(&zellij);
focus_upper_pane(&zellij);
let initial_rows = height(&upper_terminal, "upper terminal initial height");
let initial_boundary = horizontal_boundary_row(&zellij);
resize_in_resize_mode(&zellij, &keys::key('j'));
upper_terminal.wait_for_size("upper terminal grew downward", |_, rows| {
rows > initial_rows
});
let grid_snapshot = zellij.wait_until("pane boundary moved down", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_row(grid_snapshot).is_some_and(|row| row > initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_increase_up() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let lower_terminal = split_down_and_wait_for_prompt(&zellij);
let initial_rows = height(&lower_terminal, "lower terminal initial height");
let initial_boundary = horizontal_boundary_row(&zellij);
resize_in_resize_mode(&zellij, &keys::key('k'));
lower_terminal.wait_for_size("lower terminal grew upward", |_, rows| rows > initial_rows);
let grid_snapshot = zellij.wait_until("pane boundary moved up", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_row(grid_snapshot).is_some_and(|row| row < initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_decrease_down() {
let mut zellij = start_zellij();
let upper_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
split_down_and_wait_for_prompt(&zellij);
focus_upper_pane(&zellij);
let initial_rows = height(&upper_terminal, "upper terminal initial height");
let initial_boundary = horizontal_boundary_row(&zellij);
resize_in_resize_mode(&zellij, &keys::key('J'));
upper_terminal.wait_for_size("upper terminal shrank", |_, rows| rows < initial_rows);
let grid_snapshot = zellij.wait_until("pane boundary moved up", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_row(grid_snapshot).is_some_and(|row| row < initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_decrease_up() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let lower_terminal = split_down_and_wait_for_prompt(&zellij);
let initial_rows = height(&lower_terminal, "lower terminal initial height");
let initial_boundary = horizontal_boundary_row(&zellij);
resize_in_resize_mode(&zellij, &keys::key('K'));
lower_terminal.wait_for_size("lower terminal shrank", |_, rows| rows < initial_rows);
let grid_snapshot = zellij.wait_until("pane boundary moved down", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_row(grid_snapshot).is_some_and(|row| row > initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_increase_in_resize_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
let initial_cols = width(&right_terminal, "right terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
resize_in_resize_mode(&zellij, &keys::key('='));
right_terminal.wait_for_size("right terminal grew", |cols, _| cols > initial_cols);
let grid_snapshot = zellij.wait_until("pane boundary moved left", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column < initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_decrease_in_resize_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
let initial_cols = width(&right_terminal, "right terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
resize_in_resize_mode(&zellij, &keys::key('-'));
right_terminal.wait_for_size("right terminal shrank", |cols, _| cols < initial_cols);
let grid_snapshot = zellij.wait_until("pane boundary moved right", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column > initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_increase_in_normal_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
let initial_cols = width(&right_terminal, "right terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
zellij.send_stdin(&keys::alt('='));
right_terminal.wait_for_size("right terminal grew", |cols, _| cols > initial_cols);
let grid_snapshot = zellij.wait_until("pane boundary moved left", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column < initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn resize_decrease_in_normal_mode() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
let right_terminal = split_right_and_wait_for_prompt(&zellij);
let initial_cols = width(&right_terminal, "right terminal initial width");
let initial_boundary = vertical_boundary_column(&zellij);
zellij.send_stdin(&keys::alt('-'));
right_terminal.wait_for_size("right terminal shrank", |cols, _| cols < initial_cols);
let grid_snapshot = zellij.wait_until("pane boundary moved right", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& pane_two_header_column(grid_snapshot).is_some_and(|column| column > initial_boundary)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
@@ -1,13 +1,9 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{keys, normalized, LayoutInfo, Size, TestRunner, TestSession};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
use zellij_integration_tests::{
keys, normalized, LayoutInfo, TestRunner, TestSession, PROMPT, TERMINAL_SIZE,
};
const PROMPT: &[u8] = b"$ ";
const RESURRECT_LAYOUT: &str = r#"
layout {
@@ -49,8 +45,8 @@ fn quit_and_resurrect_session() {
let mut zellij = start_serializing_session("");
wait_for_layout_loaded(&zellij);
zellij.send_stdin(&keys::PANE_MODE);
zellij.send_stdin(&keys::SPLIT_RIGHT_IN_PANE_MODE);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('r'));
let new_pane = zellij.expect_pty_spawn();
new_pane.output(PROMPT);
zellij.wait_until("new pane opened before serialization", |grid_snapshot| {
+134
View File
@@ -0,0 +1,134 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, keys, normalized, start_zellij, FakePtyHandle,
TestSession,
};
const LAST_LINE: &str = "line40";
fn fill_pane_past_viewport(zellij: &TestSession) -> FakePtyHandle {
let terminal = claim_first_terminal_and_wait_for_prompt(zellij);
for line in 1..=40 {
terminal.output(format!("line{:02}\r\n", line).as_bytes());
}
zellij.wait_until("pane filled past its viewport", |grid_snapshot| {
grid_snapshot.contains(LAST_LINE)
});
terminal
}
#[test]
fn page_scroll_up() {
let mut zellij = start_zellij();
fill_pane_past_viewport(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::ctrl('b'));
let grid_snapshot = zellij.wait_until("scrolled up by a page", |grid_snapshot| {
grid_snapshot.contains("PgDn|PgUp") && !grid_snapshot.contains(LAST_LINE)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn page_scroll_down() {
let mut zellij = start_zellij();
fill_pane_past_viewport(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::ctrl('b'));
zellij.wait_until("scrolled up by a page", |grid_snapshot| {
grid_snapshot.contains("PgDn|PgUp") && !grid_snapshot.contains(LAST_LINE)
});
zellij.send_stdin(&keys::ctrl('f'));
let grid_snapshot = zellij
.wait_until("scrolled back down toward the bottom", |grid_snapshot| {
grid_snapshot.contains("line39") && grid_snapshot.contains("PgDn|PgUp")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn half_page_scroll_up() {
let mut zellij = start_zellij();
fill_pane_past_viewport(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('u'));
let grid_snapshot = zellij.wait_until("scrolled up by half a page", |grid_snapshot| {
grid_snapshot.contains("PgDn|PgUp") && !grid_snapshot.contains(LAST_LINE)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn half_page_scroll_down() {
let mut zellij = start_zellij();
fill_pane_past_viewport(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('u'));
zellij.wait_until("scrolled up by half a page", |grid_snapshot| {
grid_snapshot.contains("PgDn|PgUp") && !grid_snapshot.contains(LAST_LINE)
});
zellij.send_stdin(&keys::key('d'));
let grid_snapshot = zellij
.wait_until("scrolled back down toward the bottom", |grid_snapshot| {
grid_snapshot.contains("line39") && grid_snapshot.contains("PgDn|PgUp")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn scroll_down_one_line() {
let mut zellij = start_zellij();
fill_pane_past_viewport(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('k'));
zellij.send_stdin(&keys::key('k'));
zellij.wait_until("scrolled up two lines", |grid_snapshot| {
grid_snapshot.contains("SCROLL: 2/")
});
zellij.send_stdin(&keys::key('j'));
let grid_snapshot = zellij.wait_until("scrolled back down one line", |grid_snapshot| {
grid_snapshot.contains("SCROLL: 1/") && grid_snapshot.contains("PgDn|PgUp")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn scroll_to_bottom() {
let mut zellij = start_zellij();
fill_pane_past_viewport(&zellij);
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::ctrl('b'));
zellij.wait_until("scrolled up by a page", |grid_snapshot| {
grid_snapshot.contains("PgDn|PgUp") && !grid_snapshot.contains(LAST_LINE)
});
zellij.send_stdin(&keys::ctrl('c'));
let grid_snapshot = zellij
.wait_until("returned to the bottom in normal mode", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.contains(LAST_LINE)
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
+161
View File
@@ -0,0 +1,161 @@
#![cfg(unix)]
use insta::assert_snapshot;
use zellij_integration_tests::{
claim_first_terminal_and_wait_for_prompt, keys, normalized, start_zellij, FakePtyHandle,
TestSession,
};
fn fill_pane_with_two_matches(zellij: &TestSession) -> FakePtyHandle {
let terminal = claim_first_terminal_and_wait_for_prompt(zellij);
for line in 1..=40 {
let content = match line {
5 => "line05 NEEDLE upper\r\n".to_string(),
35 => "line35 NEEDLE lower\r\n".to_string(),
other => format!("line{:02}\r\n", other),
};
terminal.output(content.as_bytes());
}
zellij.wait_until(
"pane filled with the lower match visible",
|grid_snapshot| {
grid_snapshot.contains("NEEDLE lower") && !grid_snapshot.contains("NEEDLE upper")
},
);
terminal
}
fn enter_search_for_needle(zellij: &TestSession) {
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('s'));
zellij.wait_until("search input mode active", |grid_snapshot| {
grid_snapshot.contains("ENTERING SEARCH TERM")
});
zellij.send_stdin(b"NEEDLE");
zellij.send_stdin(&keys::ENTER);
zellij.wait_until("search navigation mode active", |grid_snapshot| {
grid_snapshot.contains("PgDn|PgUp")
});
}
fn enter_search_on_visible_match(zellij: &TestSession) {
let terminal = claim_first_terminal_and_wait_for_prompt(zellij);
terminal.output(b"NEEDLE on screen\r\n");
zellij.wait_until("match visible on screen", |grid_snapshot| {
grid_snapshot.contains("NEEDLE on screen")
});
enter_search_for_needle(zellij);
}
#[test]
fn search_input_jumps_to_a_match() {
let mut zellij = start_zellij();
let terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
for line in 1..=40 {
let content = if line == 5 {
"line05 NEEDLE\r\n".to_string()
} else {
format!("line{:02}\r\n", line)
};
terminal.output(content.as_bytes());
}
zellij.wait_until("upper match initially off screen", |grid_snapshot| {
grid_snapshot.contains("line40") && !grid_snapshot.contains("line05")
});
zellij.send_stdin(&keys::ctrl('s'));
zellij.send_stdin(&keys::key('s'));
zellij.wait_until("search input mode active", |grid_snapshot| {
grid_snapshot.contains("ENTERING SEARCH TERM")
});
zellij.send_stdin(b"NEEDLE");
let grid_snapshot = zellij.wait_until("scrolled to the typed match", |grid_snapshot| {
grid_snapshot.contains("line05") && grid_snapshot.contains("ENTERING SEARCH TERM")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn search_up_to_previous_match() {
let mut zellij = start_zellij();
fill_pane_with_two_matches(&zellij);
enter_search_for_needle(&zellij);
zellij.send_stdin(&keys::key('p'));
zellij.send_stdin(&keys::key('p'));
let grid_snapshot =
zellij.wait_until("upper match revealed by searching up", |grid_snapshot| {
grid_snapshot.contains("NEEDLE upper") && grid_snapshot.contains("PgDn|PgUp")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn search_down_to_next_match() {
let mut zellij = start_zellij();
fill_pane_with_two_matches(&zellij);
enter_search_for_needle(&zellij);
zellij.send_stdin(&keys::key('p'));
zellij.send_stdin(&keys::key('p'));
zellij.wait_until("upper match revealed by searching up", |grid_snapshot| {
grid_snapshot.contains("NEEDLE upper")
});
zellij.send_stdin(&keys::key('n'));
let grid_snapshot =
zellij.wait_until("lower match revealed by searching down", |grid_snapshot| {
grid_snapshot.contains("NEEDLE lower")
&& !grid_snapshot.contains("NEEDLE upper")
&& grid_snapshot.contains("PgDn|PgUp")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn search_toggle_case_sensitivity() {
let mut zellij = start_zellij();
enter_search_on_visible_match(&zellij);
zellij.send_stdin(&keys::key('c'));
let grid_snapshot = zellij.wait_until("case sensitivity toggled on", |grid_snapshot| {
grid_snapshot.contains("[c]")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn search_toggle_wrap() {
let mut zellij = start_zellij();
enter_search_on_visible_match(&zellij);
zellij.send_stdin(&keys::key('w'));
let grid_snapshot = zellij.wait_until("wrap toggled on", |grid_snapshot| {
grid_snapshot.contains("[w]")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn search_toggle_whole_word() {
let mut zellij = start_zellij();
enter_search_on_visible_match(&zellij);
zellij.send_stdin(&keys::key('o'));
let grid_snapshot = zellij.wait_until("whole word toggled on", |grid_snapshot| {
grid_snapshot.contains("[o]")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
+31
View File
@@ -0,0 +1,31 @@
#![cfg(unix)]
use zellij_integration_tests::{claim_first_terminal_and_wait_for_prompt, keys, start_zellij};
#[test]
fn launch_session_manager_plugin() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('o'));
zellij.send_stdin(&keys::key('w'));
zellij.wait_until("session manager plugin opened", |grid_snapshot| {
grid_snapshot.contains("Session Manager") && grid_snapshot.status_bar_appears()
});
zellij.quit();
}
#[test]
fn launch_about_plugin() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('o'));
zellij.send_stdin(&keys::key('a'));
zellij.wait_until("about plugin opened", |grid_snapshot| {
grid_snapshot.contains("About Zellij") && grid_snapshot.status_bar_appears()
});
zellij.quit();
}
@@ -3,7 +3,6 @@ source: zellij-integration-tests/tests/app.rs
expression: normalized(&grid_snapshot)
---
Tip: UNBOUND => open new pane. UNBOUND => navigate between panes. UNBOUND => increase/decrease pane size.
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/misc.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ █ ││$ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/misc.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/misc.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/misc.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ┌ Multiple Pane Select ────────────────────────┐ ││ │
│ │<ESC> - cancel, <TAB> - move │ ││ │
│ │ │ ││ │
│ │GROUP ACTIONS (1 SELECTED PANE) │ ││ │
│ │<b> - break out, <s> - stack, <c> - close │ ││ │
│ │<l> - break left, <r> - break right │ ││ │
│ │<e> - embed, <f> - float │ ││ │
│ │ │ ││ │
│ │Alt +  <p> Toggle  <Shift p> Follow Focus │ ││ │
│ └──────────────────────────────────────────────┘ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/misc.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ┌ Multiple Pane Select ────────────────────────┐ ││ │
│ │<ESC> - cancel, <TAB> - move │ ││ │
│ │ │ ││ │
│ │GROUP ACTIONS (1 SELECTED PANE) │ ││ │
│ │<b> - break out, <s> - stack, <c> - close │ ││ │
│ │<l> - break left, <r> - break right │ ││ │
│ │<e> - embed, <f> - float │ ││ │
│ │ │ ││ │
│ │Alt +  <p> Toggle  <Shift p> Follow Focus │ ││ │
│ └──────────────────────────────────────────────┘ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/misc.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Enter search... ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
ENTERING SEARCH TERM   ENTER  When done 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <h> MOVE   ←↓↑→  Switch Location  ENTER  When done 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <p> PANE   n  New  ←↓↑→  Move  x  Close  c  Rename  f  Fullscreen  Alt f  Floating  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <n> RESIZE   +|-  Increase/Decrease  ←↓↑→  Increase  HJKL  Decrease  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
SEARCHING   ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  n  Down  p  Up  c  Case  w  Wrap  o  Whole 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <o> SESSION   d  Detach  w  Manager  s  Share  c  Config  l  Layouts  p  Plugins  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/modes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <t> TAB   n  New  ←→  Move  x  Close  r  Rename  s  Sync  b  Break out  []  Break  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ █ ││$ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ █ ││$ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ oneone█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #2 ─────────────────────────────────────────────────┐┌ Pane #1 ─────────────────────────────────────────────────┐
│$ BBB█ ││$ AAA │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ BBB█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ AAA │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #2 ─────────────────────────────────────────────────┐┌ Pane #1 ─────────────────────────────────────────────────┐
│$ BBB█ ││$ AAA │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #2 ─────────────────────────────────────────────────┐┌ Pane #1 ─────────────────────────────────────────────────┐
│$ BBB█ ││$ AAA │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ █ ││$ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ ┌ Pane #2 ──────────────────────────────────────── PIN [ ] ┐ │
│ │$ █ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
$ │$ █
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/panes.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ ┌ Pane #2 ──────────────────────────────────────── PIN [+] ┐ │
│ │$ █ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────┐┌ Pane #2 ─────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────────────────────────────────────────┘└──────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────┐┌ Pane #2 ─────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────────────────────────────────────────┘└──────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ───────────────────────────────────────────────────────┐┌ Pane #2 ───────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└────────────────────────────────────────────────────────────────┘└────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ───────────────────────────────────────────┐┌ Pane #2 ───────────────────────────────────────────────────────┐
│$ █ ││$ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└────────────────────────────────────────────────────┘└────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────┐┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────┘└──────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────┐┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────┘└──────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ───────────────────────────────────────────────────────┐┌ Pane #2 ───────────────────────────────────────────┐
│$ █ ││$ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└────────────────────────────────────────────────────────────────┘└────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/resize.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/scroll.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ────────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 0/21 ┐
│line22 │
│line23 │
│line24 │
│line25 │
│line26 │
│line27 │
│line28 │
│line29 │
│line30 │
│line31 │
│line32 │
│line33 │
│line34 │
│line35 │
│line36 │
│line37 │
│line38 │
│line39 │
│line40 │
│█ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/scroll.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ───────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 10/21 ┐
│line12 │
│line13 │
│line14 │
│line15 │
│line16 │
│line17 │
│line18 │
│line19 │
│line20 │
│line21 │
│line22 │
│line23 │
│line24 │
│line25 │
│line26 │
│line27 │
│line28 │
│line29 │
│line30 │
│█ine31 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/scroll.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ────────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 1/21 ┐
│line21 │
│line22 │
│line23 │
│line24 │
│line25 │
│line26 │
│line27 │
│line28 │
│line29 │
│line30 │
│line31 │
│line32 │
│line33 │
│line34 │
│line35 │
│line36 │
│line37 │
│line38 │
│line39 │
│█ine40 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/scroll.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ───────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 21/21 ┐
│$ line01 │
│line02 │
│line03 │
│line04 │
│line05 │
│line06 │
│line07 │
│line08 │
│line09 │
│line10 │
│line11 │
│line12 │
│line13 │
│line14 │
│line15 │
│line16 │
│line17 │
│line18 │
│line19 │
│█ine20 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/scroll.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ────────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 1/21 ┐
│line21 │
│line22 │
│line23 │
│line24 │
│line25 │
│line26 │
│line27 │
│line28 │
│line29 │
│line30 │
│line31 │
│line32 │
│line33 │
│line34 │
│line35 │
│line36 │
│line37 │
│line38 │
│line39 │
│█ine40 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/scroll.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ────────────────────────────────────────────────────────────────────────────────────────────── SCROLL: 0/21 ┐
│line22 │
│line23 │
│line24 │
│line25 │
│line26 │
│line27 │
│line28 │
│line29 │
│line30 │
│line31 │
│line32 │
│line33 │
│line34 │
│line35 │
│line36 │
│line37 │
│line38 │
│line39 │
│line40 │
│█ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/search.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ SEARCHING: NEEDLE ──────────────────────────────────────────────────────────────────────────────────── SCROLL: 6/21 ┐
│line16 │
│line17 │
│line18 │
│line19 │
│line20 │
│line21 │
│line22 │
│line23 │
│line24 │
│line25 │
│line26 │
│line27 │
│line28 │
│line29 │
│line30 │
│line31 │
│line32 │
│line33 │
│line34 │
│█ine35 NEEDLE lower │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
SEARCHING   ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  n  Down  p  Up  c  Case  w  Wrap  o  Whole 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/search.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ SEARCHING: NEEDLE ─────────────────────────────────────────────────────────────────────────────────── SCROLL: 17/21 ┐
│line05 NEEDLE │
│line06 │
│line07 │
│line08 │
│line09 │
│line10 │
│line11 │
│line12 │
│line13 │
│line14 │
│line15 │
│line16 │
│line17 │
│line18 │
│line19 │
│line20 │
│line21 │
│line22 │
│line23 │
│█ine24 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
ENTERING SEARCH TERM   ENTER  When done 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/search.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ SEARCHING: NEEDLE [c] ───────────────────────────────────────────────────────────────────────────────────────────────┐
│$ NEEDLE on screen │
│█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
SEARCHING   ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  n  Down  p  Up  c  Case  w  Wrap  o  Whole 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/search.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ SEARCHING: NEEDLE [o] ───────────────────────────────────────────────────────────────────────────────────────────────┐
│$ NEEDLE on screen │
│█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
SEARCHING   ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  n  Down  p  Up  c  Case  w  Wrap  o  Whole 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/search.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ SEARCHING: NEEDLE [w] ───────────────────────────────────────────────────────────────────────────────────────────────┐
│$ NEEDLE on screen │
│█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
SEARCHING   ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  n  Down  p  Up  c  Case  w  Wrap  o  Whole 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/search.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ SEARCHING: NEEDLE ─────────────────────────────────────────────────────────────────────────────────── SCROLL: 17/21 ┐
│line05 NEEDLE upper │
│line06 │
│line07 │
│line08 │
│line09 │
│line10 │
│line11 │
│line12 │
│line13 │
│line14 │
│line15 │
│line16 │
│line17 │
│line18 │
│line19 │
│line20 │
│line21 │
│line22 │
│line23 │
│█ine24 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
SEARCHING   ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  n  Down  p  Up  c  Case  w  Wrap  o  Whole 
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ █ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #1 ─────────────────────────────────────────────────┐
│$ alpha ││$ beta█ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ gamma ││$ beta█ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ twotwo█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ oneone█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ oneone█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1 (SYNC) 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐
│$ ││$ █ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
@@ -0,0 +1,28 @@
---
source: zellij-integration-tests/tests/tabs.rs
expression: normalized(&grid_snapshot)
---
Zellij (test)  Tab #1  Tab #2 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ oneone█ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  ...
+252 -43
View File
@@ -2,35 +2,10 @@
use insta::assert_snapshot;
use zellij_integration_tests::{
keys, normalized, FakePtyHandle, GridSnapshot, Size, TestRunner, TestSession,
claim_first_terminal_and_wait_for_prompt, col, keys, normalized, start_zellij, FakePtyHandle,
GridSnapshot, TestSession, PROMPT,
};
const TERMINAL_SIZE: Size = Size {
cols: 120,
rows: 24,
};
const PROMPT: &[u8] = b"$ ";
const PROMPT_ROW: usize = 2;
const FIRST_PANE_PROMPT_X: usize = 3;
fn start_zellij() -> TestSession {
TestRunner::new(TERMINAL_SIZE).start()
}
fn claim_first_terminal_and_wait_for_prompt(zellij: &TestSession) -> FakePtyHandle {
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
zellij.wait_until(
"first terminal prompt rendered in loaded app",
|grid_snapshot| {
grid_snapshot.tab_bar_appears()
&& grid_snapshot.status_bar_appears()
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
},
);
terminal
}
fn tabs_in_order(grid_snapshot: &GridSnapshot, labels: &[&str]) -> bool {
let mut search_from = 0;
for label in labels {
@@ -43,19 +18,253 @@ fn tabs_in_order(grid_snapshot: &GridSnapshot, labels: &[&str]) -> bool {
}
fn open_new_tab_and_wait_for_prompt(zellij: &TestSession, expected_tab: &str) -> FakePtyHandle {
zellij.send_stdin(&keys::TAB_MODE);
zellij.send_stdin(&keys::NEW_TAB_IN_TAB_MODE);
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('n'));
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
let expected_tab = expected_tab.to_owned();
zellij.wait_until("new tab opened with prompt", move |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains(&expected_tab)
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
terminal
}
fn label_first_tab_pane(zellij: &TestSession, terminal: &FakePtyHandle, marker: &str) {
terminal.output(marker.as_bytes());
let marker = marker.to_owned();
zellij.wait_until("first tab pane labelled", move |grid_snapshot| {
grid_snapshot.contains(&marker)
});
}
fn open_marked_tab(zellij: &TestSession, expected_tab: &str, marker: &str) -> FakePtyHandle {
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('n'));
let terminal = zellij.expect_pty_spawn();
terminal.output(PROMPT);
terminal.output(marker.as_bytes());
let expected_tab = expected_tab.to_owned();
let marker = marker.to_owned();
zellij.wait_until("new marked tab opened", move |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains(&expected_tab)
&& grid_snapshot.contains(&marker)
});
terminal
}
#[test]
fn go_to_previous_tab() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
label_first_tab_pane(&zellij, &first_terminal, "oneone");
open_marked_tab(&zellij, "Tab #2", "twotwo");
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('h'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("previous tab focused", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.contains("oneone")
&& !grid_snapshot.contains("twotwo")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn go_to_next_tab() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
label_first_tab_pane(&zellij, &first_terminal, "oneone");
open_marked_tab(&zellij, "Tab #2", "twotwo");
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('h'));
zellij.wait_until("previous tab focused", |grid_snapshot| {
grid_snapshot.contains("oneone") && !grid_snapshot.contains("twotwo")
});
zellij.send_stdin(&keys::key('l'));
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("next tab focused again", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.contains("twotwo")
&& !grid_snapshot.contains("oneone")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn go_to_tab_by_number() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
label_first_tab_pane(&zellij, &first_terminal, "oneone");
open_marked_tab(&zellij, "Tab #2", "twotwo");
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('1'));
let grid_snapshot = zellij.wait_until("first tab focused by number", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("oneone")
&& !grid_snapshot.contains("twotwo")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_tab_returns_to_last_used() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
label_first_tab_pane(&zellij, &first_terminal, "oneone");
open_marked_tab(&zellij, "Tab #2", "twotwo");
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::TAB);
zellij.send_stdin(&keys::ENTER);
let grid_snapshot = zellij.wait_until("toggled back to the first tab", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.contains("oneone")
&& !grid_snapshot.contains("twotwo")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn toggle_active_sync_tab() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('n'));
let second_terminal = zellij.expect_pty_spawn();
second_terminal.output(PROMPT);
zellij.wait_until("second pane spawned in first tab", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.contains("Pane #2")
});
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('s'));
let grid_snapshot = zellij.wait_until("tab marked as syncing", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.contains("SYNC")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.send_stdin(&keys::ENTER);
zellij.send_stdin(b"synced-input");
let first_stdin = first_terminal.wait_for_stdin("synced input reached first pane", |stdin| {
stdin.windows(12).any(|window| window == b"synced-input")
});
let second_stdin = second_terminal
.wait_for_stdin("synced input reached second pane", |stdin| {
stdin.windows(12).any(|window| window == b"synced-input")
});
assert!(first_stdin
.windows(12)
.any(|window| window == b"synced-input"));
assert!(second_stdin
.windows(12)
.any(|window| window == b"synced-input"));
zellij.quit();
}
#[test]
fn break_pane_into_new_tab() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('n'));
let second_terminal = zellij.expect_pty_spawn();
second_terminal.output(PROMPT);
zellij.wait_until("second pane spawned in first tab", |grid_snapshot| {
grid_snapshot.status_bar_appears() && grid_snapshot.contains("Pane #2")
});
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('b'));
let grid_snapshot = zellij.wait_until("focused pane broken into a new tab", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.contains("Pane #2")
&& !grid_snapshot.contains("Pane #1")
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn break_pane_to_the_right() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
label_first_tab_pane(&zellij, &first_terminal, "alpha");
zellij.send_stdin(&keys::ctrl('p'));
zellij.send_stdin(&keys::key('n'));
let beta_terminal = zellij.expect_pty_spawn();
beta_terminal.output(PROMPT);
beta_terminal.output(b"beta");
zellij.wait_until("second pane spawned in first tab", |grid_snapshot| {
grid_snapshot.contains("beta") && grid_snapshot.contains("Pane #2")
});
open_marked_tab(&zellij, "Tab #2", "gamma");
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('h'));
zellij.wait_until("back on the first tab with its panes", |grid_snapshot| {
grid_snapshot.contains("beta") && !grid_snapshot.contains("gamma")
});
zellij.send_stdin(&keys::key(']'));
let grid_snapshot = zellij.wait_until("beta pane moved into the right tab", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("beta")
&& grid_snapshot.contains("gamma")
&& !grid_snapshot.contains("alpha")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn break_pane_to_the_left() {
let mut zellij = start_zellij();
let first_terminal = claim_first_terminal_and_wait_for_prompt(&zellij);
label_first_tab_pane(&zellij, &first_terminal, "alpha");
open_marked_tab(&zellij, "Tab #2", "beta");
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('['));
let grid_snapshot = zellij.wait_until("beta pane moved into the left tab", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("alpha")
&& grid_snapshot.contains("beta")
&& !grid_snapshot.contains("Tab #2")
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
}
#[test]
fn open_new_tab() {
let mut zellij = start_zellij();
@@ -64,7 +273,7 @@ fn open_new_tab() {
let grid_snapshot = zellij.wait_until("second tab steady in normal mode", |grid_snapshot| {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #2")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
});
assert_snapshot!(normalized(&grid_snapshot));
zellij.quit();
@@ -76,8 +285,8 @@ fn close_tab() {
claim_first_terminal_and_wait_for_prompt(&zellij);
open_new_tab_and_wait_for_prompt(&zellij, "Tab #2");
zellij.send_stdin(&keys::TAB_MODE);
zellij.send_stdin(&keys::CLOSE_TAB_IN_TAB_MODE);
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('x'));
let grid_snapshot = zellij.wait_until(
"second tab closed, only first tab remains",
@@ -85,7 +294,7 @@ fn close_tab() {
grid_snapshot.status_bar_appears()
&& grid_snapshot.contains("Tab #1")
&& !grid_snapshot.contains("Tab #2")
&& grid_snapshot.cursor_is_at(FIRST_PANE_PROMPT_X, PROMPT_ROW)
&& grid_snapshot.cursor_is_at(col(3).row(2))
},
);
assert_snapshot!(normalized(&grid_snapshot));
@@ -97,8 +306,8 @@ fn undo_rename_tab() {
let mut zellij = start_zellij();
claim_first_terminal_and_wait_for_prompt(&zellij);
zellij.send_stdin(&keys::TAB_MODE);
zellij.send_stdin(&keys::RENAME_TAB_MODE);
zellij.send_stdin(&keys::ctrl('t'));
zellij.send_stdin(&keys::key('r'));
zellij.send_stdin(b"aa");
zellij.send_stdin(&keys::ESC);
zellij.send_stdin(&keys::ESC);
@@ -117,7 +326,7 @@ fn move_tab_to_left() {
open_new_tab_and_wait_for_prompt(&zellij, "Tab #2");
open_new_tab_and_wait_for_prompt(&zellij, "Tab #3");
zellij.send_stdin(&keys::MOVE_TAB_LEFT);
zellij.send_stdin(&keys::alt('i'));
let grid_snapshot = zellij.wait_until("third tab moved one position left", |grid_snapshot| {
tabs_in_order(grid_snapshot, &["Tab #1", "Tab #3", "Tab #2"])
@@ -133,8 +342,8 @@ fn move_tab_to_right() {
open_new_tab_and_wait_for_prompt(&zellij, "Tab #2");
open_new_tab_and_wait_for_prompt(&zellij, "Tab #3");
zellij.send_stdin(&keys::MOVE_FOCUS_LEFT_IN_NORMAL_MODE);
zellij.send_stdin(&keys::MOVE_TAB_RIGHT);
zellij.send_stdin(&keys::alt('h'));
zellij.send_stdin(&keys::alt('o'));
let grid_snapshot = zellij.wait_until("second tab moved one position right", |grid_snapshot| {
tabs_in_order(grid_snapshot, &["Tab #1", "Tab #3", "Tab #2"])
@@ -150,15 +359,15 @@ fn move_tab_to_left_until_it_wraps_around() {
open_new_tab_and_wait_for_prompt(&zellij, "Tab #2");
open_new_tab_and_wait_for_prompt(&zellij, "Tab #3");
zellij.send_stdin(&keys::MOVE_TAB_LEFT);
zellij.send_stdin(&keys::alt('i'));
zellij.wait_until("third tab moved one position left", |grid_snapshot| {
tabs_in_order(grid_snapshot, &["Tab #1", "Tab #3", "Tab #2"])
});
zellij.send_stdin(&keys::MOVE_TAB_LEFT);
zellij.send_stdin(&keys::alt('i'));
zellij.wait_until("third tab moved to the beginning", |grid_snapshot| {
tabs_in_order(grid_snapshot, &["Tab #3", "Tab #1", "Tab #2"])
});
zellij.send_stdin(&keys::MOVE_TAB_LEFT);
zellij.send_stdin(&keys::alt('i'));
let grid_snapshot = zellij.wait_until("third tab wrapped to the end", |grid_snapshot| {
tabs_in_order(grid_snapshot, &["Tab #1", "Tab #2", "Tab #3"])
@@ -174,7 +383,7 @@ fn move_tab_to_right_until_it_wraps_around() {
open_new_tab_and_wait_for_prompt(&zellij, "Tab #2");
open_new_tab_and_wait_for_prompt(&zellij, "Tab #3");
zellij.send_stdin(&keys::MOVE_TAB_RIGHT);
zellij.send_stdin(&keys::alt('o'));
let grid_snapshot = zellij.wait_until("third tab wrapped to the beginning", |grid_snapshot| {
tabs_in_order(grid_snapshot, &["Tab #3", "Tab #1", "Tab #2"])