diff options
| author | Aram Drevekenin <aram@poor.dev> | 2026-06-25 17:09:26 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-06-25 17:09:26 +0200 |
| commit | 27291bea2893589b3274d5da7c81d80b3f487d26 (patch) | |
| tree | e71e46925f236b55ef73fd4f0ff7c6c3092eed32 | |
| parent | hotfix: fix flaky ci tests (diff) | |
| download | sl0ppij-27291bea2893589b3274d5da7c81d80b3f487d26.tar.gz sl0ppij-27291bea2893589b3274d5da7c81d80b3f487d26.tar.xz sl0ppij-27291bea2893589b3274d5da7c81d80b3f487d26.zip | |
tests: add more integration tests (#5308)
* test all the things
* consolidate shared harness
* rustfmt
85 files changed, 3501 insertions, 438 deletions
diff --git a/zellij-integration-tests/src/client_screen.rs b/zellij-integration-tests/src/client_screen.rs index 3bddfa07..479c9b56 100644 --- a/zellij-integration-tests/src/client_screen.rs +++ b/zellij-integration-tests/src/client_screen.rs @@ -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") diff --git a/zellij-integration-tests/src/harness.rs b/zellij-integration-tests/src/harness.rs new file mode 100644 index 00000000..eb860f8f --- /dev/null +++ b/zellij-integration-tests/src/harness.rs @@ -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 +} diff --git a/zellij-integration-tests/src/keys.rs b/zellij-integration-tests/src/keys.rs index fe54b42d..e2cef994 100644 --- a/zellij-integration-tests/src/keys.rs +++ b/zellij-integration-tests/src/keys.rs @@ -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~"; diff --git a/zellij-integration-tests/src/lib.rs b/zellij-integration-tests/src/lib.rs index 15afe865..18f652fb 100644 --- a/zellij-integration-tests/src/lib.rs +++ b/zellij-integration-tests/src/lib.rs @@ -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; diff --git a/zellij-integration-tests/src/runner.rs b/zellij-integration-tests/src/runner.rs index 26b59014..c430f94b 100644 --- a/zellij-integration-tests/src/runner.rs +++ b/zellij-integration-tests/src/runner.rs @@ -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() diff --git a/zellij-integration-tests/tests/app.rs b/zellij-integration-tests/tests/app.rs index 70fd3a64..74ed11e4 100644 --- a/zellij-integration-tests/tests/app.rs +++ b/zellij-integration-tests/tests/app.rs @@ -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| { diff --git a/zellij-integration-tests/tests/basic.rs b/zellij-integration-tests/tests/basic.rs index 1b12316b..e72cd1c6 100644 --- a/zellij-integration-tests/tests/basic.rs +++ b/zellij-integration-tests/tests/basic.rs @@ -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(); diff --git a/zellij-integration-tests/tests/cli.rs b/zellij-integration-tests/tests/cli.rs index 50440f2f..75c3ce4a 100644 --- a/zellij-integration-tests/tests/cli.rs +++ b/zellij-integration-tests/tests/cli.rs @@ -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(); diff --git a/zellij-integration-tests/tests/clients.rs b/zellij-integration-tests/tests/clients.rs index 09db9941..669e5aa3 100644 --- a/zellij-integration-tests/tests/clients.rs +++ b/zellij-integration-tests/tests/clients.rs @@ -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") diff --git a/zellij-integration-tests/tests/misc.rs b/zellij-integration-tests/tests/misc.rs new file mode 100644 index 00000000..83a02878 --- /dev/null +++ b/zellij-integration-tests/tests/misc.rs @@ -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(); +} diff --git a/zellij-integration-tests/tests/modes.rs b/zellij-integration-tests/tests/modes.rs index c564be70..0fc093be 100644 --- a/zellij-integration-tests/tests/modes.rs +++ b/zellij-integration-tests/tests/modes.rs @@ -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(); +} + +#[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(); } -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_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| { diff --git a/zellij-integration-tests/tests/mouse.rs b/zellij-integration-tests/tests/mouse.rs index 40562a12..e4aa038c 100644 --- a/zellij-integration-tests/tests/mouse.rs +++ b/zellij-integration-tests/tests/mouse.rs @@ -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)) }, ); diff --git a/zellij-integration-tests/tests/panes.rs b/zellij-integration-tests/tests/panes.rs index 5e14b103..9defe5f2 100644 --- a/zellij-integration-tests/tests/panes.rs +++ b/zellij-integration-tests/tests/panes.rs @@ -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(); diff --git a/zellij-integration-tests/tests/plugins.rs b/zellij-integration-tests/tests/plugins.rs index e39c1af3..5b14c633 100644 --- a/zellij-integration-tests/tests/plugins.rs +++ b/zellij-integration-tests/tests/plugins.rs @@ -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!( diff --git a/zellij-integration-tests/tests/resize.rs b/zellij-integration-tests/tests/resize.rs new file mode 100644 index 00000000..bf1263c3 --- /dev/null +++ b/zellij-integration-tests/tests/resize.rs @@ -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(); +} diff --git a/zellij-integration-tests/tests/resurrection.rs b/zellij-integration-tests/tests/resurrection.rs index 55df5b32..7f6a10b0 100644 --- a/zellij-integration-tests/tests/resurrection.rs +++ b/zellij-integration-tests/tests/resurrection.rs @@ -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| { diff --git a/zellij-integration-tests/tests/scroll.rs b/zellij-integration-tests/tests/scroll.rs new file mode 100644 index 00000000..35316957 --- /dev/null +++ b/zellij-integration-tests/tests/scroll.rs @@ -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(); +} diff --git a/zellij-integration-tests/tests/search.rs b/zellij-integration-tests/tests/search.rs new file mode 100644 index 00000000..c15fe76e --- /dev/null +++ b/zellij-integration-tests/tests/search.rs @@ -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(); +} diff --git a/zellij-integration-tests/tests/session.rs b/zellij-integration-tests/tests/session.rs new file mode 100644 index 00000000..97ca0d01 --- /dev/null +++ b/zellij-integration-tests/tests/session.rs @@ -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(); +} diff --git a/zellij-integration-tests/tests/snapshots/app__use_custom_layout_with_relative_path.snap b/zellij-integration-tests/tests/snapshots/app__use_custom_layout_with_relative_path.snap index a60604ea..03d134ea 100644 --- a/zellij-integration-tests/tests/snapshots/app__use_custom_layout_with_relative_path.snap +++ b/zellij-integration-tests/tests/snapshots/app__use_custom_layout_with_relative_path.snap @@ -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 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │$ █ │ │ │ diff --git a/zellij-integration-tests/tests/snapshots/misc__focus_next_pane_via_tmux_mode.snap b/zellij-integration-tests/tests/snapshots/misc__focus_next_pane_via_tmux_mode.snap new file mode 100644 index 00000000..a114ffc5 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/misc__focus_next_pane_via_tmux_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/misc__next_swap_layout.snap b/zellij-integration-tests/tests/snapshots/misc__next_swap_layout.snap new file mode 100644 index 00000000..8e954ab9 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/misc__next_swap_layout.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/misc__previous_swap_layout.snap b/zellij-integration-tests/tests/snapshots/misc__previous_swap_layout.snap new file mode 100644 index 00000000..8e954ab9 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/misc__previous_swap_layout.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/misc__toggle_group_marking.snap b/zellij-integration-tests/tests/snapshots/misc__toggle_group_marking.snap new file mode 100644 index 00000000..9932251c --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/misc__toggle_group_marking.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/misc__toggle_pane_in_group.snap b/zellij-integration-tests/tests/snapshots/misc__toggle_pane_in_group.snap new file mode 100644 index 00000000..9932251c --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/misc__toggle_pane_in_group.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/misc__write_byte_to_focused_pane_via_tmux_mode.snap b/zellij-integration-tests/tests/snapshots/misc__write_byte_to_focused_pane_via_tmux_mode.snap new file mode 100644 index 00000000..29857afc --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/misc__write_byte_to_focused_pane_via_tmux_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/modes__enter_search_mode.snap b/zellij-integration-tests/tests/snapshots/modes__enter_search_mode.snap new file mode 100644 index 00000000..e2170783 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__enter_search_mode.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/modes__return_to_normal_mode.snap b/zellij-integration-tests/tests/snapshots/modes__return_to_normal_mode.snap new file mode 100644 index 00000000..b8e8dc2c --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__return_to_normal_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_move_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_move_mode.snap new file mode 100644 index 00000000..2c38ca5b --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_move_mode.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_pane_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_pane_mode.snap new file mode 100644 index 00000000..77a3a87a --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_resize_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_resize_mode.snap new file mode 100644 index 00000000..934b93fa --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_resize_mode.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_scroll_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_scroll_mode.snap new file mode 100644 index 00000000..bb92c9f8 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_scroll_mode.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_search_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_search_mode.snap new file mode 100644 index 00000000..9e647b1a --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_search_mode.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_session_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_session_mode.snap new file mode 100644 index 00000000..df752793 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_session_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/modes__switch_to_tab_mode.snap b/zellij-integration-tests/tests/snapshots/modes__switch_to_tab_mode.snap new file mode 100644 index 00000000..0bd07696 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/modes__switch_to_tab_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_focus_down_in_pane_mode.snap b/zellij-integration-tests/tests/snapshots/panes__move_focus_down_in_pane_mode.snap new file mode 100644 index 00000000..bf220375 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_focus_down_in_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_focus_left_in_pane_mode.snap b/zellij-integration-tests/tests/snapshots/panes__move_focus_left_in_pane_mode.snap new file mode 100644 index 00000000..fbbe4940 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_focus_left_in_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_focus_or_tab_moves_focus_between_panes.snap b/zellij-integration-tests/tests/snapshots/panes__move_focus_or_tab_moves_focus_between_panes.snap new file mode 100644 index 00000000..fbbe4940 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_focus_or_tab_moves_focus_between_panes.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_focus_or_tab_switches_tab_when_single_pane.snap b/zellij-integration-tests/tests/snapshots/panes__move_focus_or_tab_switches_tab_when_single_pane.snap new file mode 100644 index 00000000..f0254ce4 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_focus_or_tab_switches_tab_when_single_pane.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_focus_right_in_pane_mode.snap b/zellij-integration-tests/tests/snapshots/panes__move_focus_right_in_pane_mode.snap new file mode 100644 index 00000000..f68a25e2 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_focus_right_in_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_focus_up_in_pane_mode.snap b/zellij-integration-tests/tests/snapshots/panes__move_focus_up_in_pane_mode.snap new file mode 100644 index 00000000..1bf6e70d --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_focus_up_in_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_pane_backwards_swaps_with_neighbor.snap b/zellij-integration-tests/tests/snapshots/panes__move_pane_backwards_swaps_with_neighbor.snap new file mode 100644 index 00000000..a5ec291c --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_pane_backwards_swaps_with_neighbor.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_pane_down.snap b/zellij-integration-tests/tests/snapshots/panes__move_pane_down.snap new file mode 100644 index 00000000..3efaa27f --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_pane_down.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_pane_left.snap b/zellij-integration-tests/tests/snapshots/panes__move_pane_left.snap new file mode 100644 index 00000000..a5ec291c --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_pane_left.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__move_pane_swaps_with_neighbor.snap b/zellij-integration-tests/tests/snapshots/panes__move_pane_swaps_with_neighbor.snap new file mode 100644 index 00000000..a5ec291c --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__move_pane_swaps_with_neighbor.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__new_pane_in_normal_mode.snap b/zellij-integration-tests/tests/snapshots/panes__new_pane_in_normal_mode.snap new file mode 100644 index 00000000..f68a25e2 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__new_pane_in_normal_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__new_pane_in_pane_mode.snap b/zellij-integration-tests/tests/snapshots/panes__new_pane_in_pane_mode.snap new file mode 100644 index 00000000..f68a25e2 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__new_pane_in_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__new_stacked_pane.snap b/zellij-integration-tests/tests/snapshots/panes__new_stacked_pane.snap new file mode 100644 index 00000000..64abb7f3 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__new_stacked_pane.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__split_pane_downward.snap b/zellij-integration-tests/tests/snapshots/panes__split_pane_downward.snap new file mode 100644 index 00000000..bf220375 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__split_pane_downward.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__switch_focus_in_pane_mode.snap b/zellij-integration-tests/tests/snapshots/panes__switch_focus_in_pane_mode.snap new file mode 100644 index 00000000..fbbe4940 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__switch_focus_in_pane_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__toggle_pane_embed_or_floating.snap b/zellij-integration-tests/tests/snapshots/panes__toggle_pane_embed_or_floating.snap new file mode 100644 index 00000000..3a4e1240 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__toggle_pane_embed_or_floating.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__toggle_pane_frames.snap b/zellij-integration-tests/tests/snapshots/panes__toggle_pane_frames.snap new file mode 100644 index 00000000..e58b8c3e --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__toggle_pane_frames.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/panes__toggle_pane_pinned.snap b/zellij-integration-tests/tests/snapshots/panes__toggle_pane_pinned.snap new file mode 100644 index 00000000..858b2446 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/panes__toggle_pane_pinned.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_decrease_down.snap b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_down.snap new file mode 100644 index 00000000..6bb097ff --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_down.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_decrease_in_normal_mode.snap b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_in_normal_mode.snap new file mode 100644 index 00000000..6d94b5be --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_in_normal_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_decrease_in_resize_mode.snap b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_in_resize_mode.snap new file mode 100644 index 00000000..6d94b5be --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_in_resize_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_decrease_left.snap b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_left.snap new file mode 100644 index 00000000..31a95ba2 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_left.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_decrease_right.snap b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_right.snap new file mode 100644 index 00000000..8071443e --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_right.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_decrease_up.snap b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_up.snap new file mode 100644 index 00000000..f60a7abc --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_decrease_up.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_increase_down.snap b/zellij-integration-tests/tests/snapshots/resize__resize_increase_down.snap new file mode 100644 index 00000000..b04b511a --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_increase_down.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_increase_in_normal_mode.snap b/zellij-integration-tests/tests/snapshots/resize__resize_increase_in_normal_mode.snap new file mode 100644 index 00000000..1da118af --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_increase_in_normal_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_increase_in_resize_mode.snap b/zellij-integration-tests/tests/snapshots/resize__resize_increase_in_resize_mode.snap new file mode 100644 index 00000000..1da118af --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_increase_in_resize_mode.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_increase_right.snap b/zellij-integration-tests/tests/snapshots/resize__resize_increase_right.snap new file mode 100644 index 00000000..fca16a54 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_increase_right.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/resize__resize_increase_up.snap b/zellij-integration-tests/tests/snapshots/resize__resize_increase_up.snap new file mode 100644 index 00000000..5ff0c7aa --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/resize__resize_increase_up.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/scroll__half_page_scroll_down.snap b/zellij-integration-tests/tests/snapshots/scroll__half_page_scroll_down.snap new file mode 100644 index 00000000..2ce2743f --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/scroll__half_page_scroll_down.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/scroll__half_page_scroll_up.snap b/zellij-integration-tests/tests/snapshots/scroll__half_page_scroll_up.snap new file mode 100644 index 00000000..4adb7c17 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/scroll__half_page_scroll_up.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/scroll__page_scroll_down.snap b/zellij-integration-tests/tests/snapshots/scroll__page_scroll_down.snap new file mode 100644 index 00000000..6b3cec51 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/scroll__page_scroll_down.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/scroll__page_scroll_up.snap b/zellij-integration-tests/tests/snapshots/scroll__page_scroll_up.snap new file mode 100644 index 00000000..d742f0d3 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/scroll__page_scroll_up.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/scroll__scroll_down_one_line.snap b/zellij-integration-tests/tests/snapshots/scroll__scroll_down_one_line.snap new file mode 100644 index 00000000..6b3cec51 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/scroll__scroll_down_one_line.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/scroll__scroll_to_bottom.snap b/zellij-integration-tests/tests/snapshots/scroll__scroll_to_bottom.snap new file mode 100644 index 00000000..4e486cc2 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/scroll__scroll_to_bottom.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/search__search_down_to_next_match.snap b/zellij-integration-tests/tests/snapshots/search__search_down_to_next_match.snap new file mode 100644 index 00000000..7f89ceaa --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/search__search_down_to_next_match.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/search__search_input_jumps_to_a_match.snap b/zellij-integration-tests/tests/snapshots/search__search_input_jumps_to_a_match.snap new file mode 100644 index 00000000..d3c4a72d --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/search__search_input_jumps_to_a_match.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/search__search_toggle_case_sensitivity.snap b/zellij-integration-tests/tests/snapshots/search__search_toggle_case_sensitivity.snap new file mode 100644 index 00000000..8fab3747 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/search__search_toggle_case_sensitivity.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/search__search_toggle_whole_word.snap b/zellij-integration-tests/tests/snapshots/search__search_toggle_whole_word.snap new file mode 100644 index 00000000..a611c034 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/search__search_toggle_whole_word.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/search__search_toggle_wrap.snap b/zellij-integration-tests/tests/snapshots/search__search_toggle_wrap.snap new file mode 100644 index 00000000..42903ace --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/search__search_toggle_wrap.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/search__search_up_to_previous_match.snap b/zellij-integration-tests/tests/snapshots/search__search_up_to_previous_match.snap new file mode 100644 index 00000000..c113cdad --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/search__search_up_to_previous_match.snap @@ -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 diff --git a/zellij-integration-tests/tests/snapshots/tabs__break_pane_into_new_tab.snap b/zellij-integration-tests/tests/snapshots/tabs__break_pane_into_new_tab.snap new file mode 100644 index 00000000..83ddbab4 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__break_pane_into_new_tab.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__break_pane_to_the_left.snap b/zellij-integration-tests/tests/snapshots/tabs__break_pane_to_the_left.snap new file mode 100644 index 00000000..f64e72ee --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__break_pane_to_the_left.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__break_pane_to_the_right.snap b/zellij-integration-tests/tests/snapshots/tabs__break_pane_to_the_right.snap new file mode 100644 index 00000000..db5fb026 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__break_pane_to_the_right.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__go_to_next_tab.snap b/zellij-integration-tests/tests/snapshots/tabs__go_to_next_tab.snap new file mode 100644 index 00000000..9441a9b1 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__go_to_next_tab.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__go_to_previous_tab.snap b/zellij-integration-tests/tests/snapshots/tabs__go_to_previous_tab.snap new file mode 100644 index 00000000..e60935a0 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__go_to_previous_tab.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__go_to_tab_by_number.snap b/zellij-integration-tests/tests/snapshots/tabs__go_to_tab_by_number.snap new file mode 100644 index 00000000..e60935a0 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__go_to_tab_by_number.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__toggle_active_sync_tab.snap b/zellij-integration-tests/tests/snapshots/tabs__toggle_active_sync_tab.snap new file mode 100644 index 00000000..f34fad73 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__toggle_active_sync_tab.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/snapshots/tabs__toggle_tab_returns_to_last_used.snap b/zellij-integration-tests/tests/snapshots/tabs__toggle_tab_returns_to_last_used.snap new file mode 100644 index 00000000..e60935a0 --- /dev/null +++ b/zellij-integration-tests/tests/snapshots/tabs__toggle_tab_returns_to_last_used.snap @@ -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 ... diff --git a/zellij-integration-tests/tests/tabs.rs b/zellij-integration-tests/tests/tabs.rs index fedaf9f1..7ba3194a 100644 --- a/zellij-integration-tests/tests/tabs.rs +++ b/zellij-integration-tests/tests/tabs.rs @@ -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"]) |
