diff options
Diffstat (limited to 'src/tests')
8 files changed, 524 insertions, 21 deletions
diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index 0585c373b..1457c0a91 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -178,7 +178,6 @@ pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() { name: "Make sure only one pane appears", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - // if remote_terminal.cursor_position_is(3, 2) && remote_terminal.snapshot_contains("...") if remote_terminal.cursor_position_is(3, 2) { // ... is the truncated tip line step_is_complete = true; @@ -928,7 +927,7 @@ pub fn detach_and_attach_session() { let last_snapshot = loop { RemoteRunner::kill_running_sessions(fake_win_size); drop(()); - let mut runner = RemoteRunner::new(fake_win_size) + let mut runner = RemoteRunner::new_mirrored_session(fake_win_size) .add_step(Step { name: "Split pane to the right", instruction: |mut remote_terminal: RemoteTerminal| -> bool { @@ -1261,20 +1260,21 @@ pub fn mirrored_sessions() { // then make sure they were also reflected (mirrored) in the first runner afterwards RemoteRunner::kill_running_sessions(fake_win_size); drop(()); - let mut first_runner = RemoteRunner::new_with_session_name(fake_win_size, session_name) - .dont_panic() - .add_step(Step { - name: "Wait for app to load", - instruction: |mut remote_terminal: RemoteTerminal| -> bool { - let mut step_is_complete = false; - if remote_terminal.status_bar_appears() - && remote_terminal.cursor_position_is(3, 2) - { - step_is_complete = true; - } - step_is_complete - }, - }); + let mut first_runner = + RemoteRunner::new_with_session_name(fake_win_size, session_name, true) + .dont_panic() + .add_step(Step { + name: "Wait for app to load", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + step_is_complete = true; + } + step_is_complete + }, + }); first_runner.run_all_steps(); let mut second_runner = RemoteRunner::new_existing_session(fake_win_size, session_name) @@ -1398,6 +1398,286 @@ pub fn mirrored_sessions() { #[test] #[ignore] +pub fn multiple_users_in_same_pane_and_tab() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; + let mut test_attempts = 10; + let session_name = "multiple_users_in_same_pane_and_tab"; + let (first_runner_snapshot, second_runner_snapshot) = loop { + // here we connect with one runner, then connect with another, perform some actions and + // then make sure they were also reflected (mirrored) in the first runner afterwards + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut first_runner = + RemoteRunner::new_with_session_name(fake_win_size, session_name, false) + .dont_panic() + .add_step(Step { + name: "Wait for app to load", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + step_is_complete = true; + } + step_is_complete + }, + }); + first_runner.run_all_steps(); + + let mut second_runner = RemoteRunner::new_existing_session(fake_win_size, session_name) + .dont_panic() + .add_step(Step { + name: "Wait for app to load", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + step_is_complete = true; + } + step_is_complete + }, + }); + second_runner.run_all_steps(); + + if first_runner.test_timed_out || second_runner.test_timed_out { + test_attempts -= 1; + continue; + } + let second_runner_snapshot = second_runner.take_snapshot_after(Step { + name: "take snapshot after", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(3, 2) + && remote_terminal.snapshot_contains("MY FOCUS") + { + // cursor is back in the first tab + step_is_complete = true; + } + step_is_complete + }, + }); + let first_runner_snapshot = first_runner.take_snapshot_after(Step { + name: "take snapshot after", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(3, 2) + && remote_terminal.snapshot_contains("MY FOCUS") + { + // cursor is back in the first tab + step_is_complete = true; + } + step_is_complete + }, + }); + + if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 { + test_attempts -= 1; + continue; + } else { + break (first_runner_snapshot, second_runner_snapshot); + } + }; + assert_snapshot!(first_runner_snapshot); + assert_snapshot!(second_runner_snapshot); +} + +#[test] +#[ignore] +pub fn multiple_users_in_different_panes_and_same_tab() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; + let mut test_attempts = 10; + let session_name = "multiple_users_in_same_pane_and_tab"; + let (first_runner_snapshot, second_runner_snapshot) = loop { + // here we connect with one runner, then connect with another, perform some actions and + // then make sure they were also reflected (mirrored) in the first runner afterwards + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut first_runner = + RemoteRunner::new_with_session_name(fake_win_size, session_name, false) + .dont_panic() + .add_step(Step { + name: "Wait for app to load", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + step_is_complete = true; + } + step_is_complete + }, + }); + first_runner.run_all_steps(); + + let mut second_runner = RemoteRunner::new_existing_session(fake_win_size, session_name) + .dont_panic() + .add_step(Step { + name: "Split pane to the right", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + remote_terminal.send_key(&PANE_MODE); + remote_terminal.send_key(&SPLIT_RIGHT_IN_PANE_MODE); + // back to normal mode after split + remote_terminal.send_key(&ENTER); + step_is_complete = true; + } + step_is_complete + }, + }); + second_runner.run_all_steps(); + + if first_runner.test_timed_out || second_runner.test_timed_out { + test_attempts -= 1; + continue; + } + + let second_runner_snapshot = second_runner.take_snapshot_after(Step { + name: "take snapshot after", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() { + // cursor is in the newly opened second pane + step_is_complete = true; + } + step_is_complete + }, + }); + + let first_runner_snapshot = first_runner.take_snapshot_after(Step { + name: "take snapshot after", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(3, 2) + && remote_terminal.snapshot_contains("││$") + { + // cursor is back in the first tab + step_is_complete = true; + } + step_is_complete + }, + }); + + if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 { + test_attempts -= 1; + continue; + } else { + break (first_runner_snapshot, second_runner_snapshot); + } + }; + assert_snapshot!(first_runner_snapshot); + assert_snapshot!(second_runner_snapshot); +} + +#[test] +#[ignore] +pub fn multiple_users_in_different_tabs() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; + let mut test_attempts = 10; + let session_name = "multiple_users_in_different_tabs"; + let (first_runner_snapshot, second_runner_snapshot) = loop { + // here we connect with one runner, then connect with another, perform some actions and + // then make sure they were also reflected (mirrored) in the first runner afterwards + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut first_runner = + RemoteRunner::new_with_session_name(fake_win_size, session_name, false) + .dont_panic() + .add_step(Step { + name: "Wait for app to load", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + step_is_complete = true; + } + step_is_complete + }, + }); + first_runner.run_all_steps(); + + let mut second_runner = RemoteRunner::new_existing_session(fake_win_size, session_name) + .dont_panic() + .add_step(Step { + name: "Open new tab", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() { + // cursor is in the newly opened second pane + remote_terminal.send_key(&TAB_MODE); + remote_terminal.send_key(&NEW_TAB_IN_TAB_MODE); + // back to normal mode after split + remote_terminal.send_key(&ENTER); + step_is_complete = true; + } + step_is_complete + }, + }); + second_runner.run_all_steps(); + + if first_runner.test_timed_out || second_runner.test_timed_out { + test_attempts -= 1; + continue; + } + + let second_runner_snapshot = second_runner.take_snapshot_after(Step { + name: "Wait for new tab to open", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(3, 2) + && remote_terminal.tip_appears() + && remote_terminal.snapshot_contains("Tab #2") + && remote_terminal.status_bar_appears() + { + // cursor is in the newly opened second tab + step_is_complete = true; + } + step_is_complete + }, + }); + + let first_runner_snapshot = first_runner.take_snapshot_after(Step { + name: "Wait for new tab to open", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(3, 2) + && remote_terminal.tip_appears() + && remote_terminal.snapshot_contains("Tab #2") + && remote_terminal.status_bar_appears() + { + // cursor is in the newly opened second tab + step_is_complete = true; + } + step_is_complete + }, + }); + + if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 { + test_attempts -= 1; + continue; + } else { + break (first_runner_snapshot, second_runner_snapshot); + } + }; + assert_snapshot!(first_runner_snapshot); + assert_snapshot!(second_runner_snapshot); +} + +#[test] +#[ignore] pub fn bracketed_paste() { let fake_win_size = Size { cols: 120, diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs index 205710f1d..feaeecdac 100644 --- a/src/tests/e2e/remote_runner.rs +++ b/src/tests/e2e/remote_runner.rs @@ -67,13 +67,27 @@ fn start_zellij(channel: &mut ssh2::Channel) { channel.flush().unwrap(); } -fn start_zellij_in_session(channel: &mut ssh2::Channel, session_name: &str) { +fn start_zellij_mirrored_session(channel: &mut ssh2::Channel) { stop_zellij(channel); channel .write_all( format!( - "{} --session {}\n", - ZELLIJ_EXECUTABLE_LOCATION, session_name + "{} --session {} options --mirror-session true\n", + ZELLIJ_EXECUTABLE_LOCATION, SESSION_NAME + ) + .as_bytes(), + ) + .unwrap(); + channel.flush().unwrap(); +} + +fn start_zellij_in_session(channel: &mut ssh2::Channel, session_name: &str, mirrored: bool) { + stop_zellij(channel); + channel + .write_all( + format!( + "{} --session {} options --mirror-session {}\n", + ZELLIJ_EXECUTABLE_LOCATION, session_name, mirrored ) .as_bytes(), ) @@ -333,13 +347,48 @@ impl RemoteRunner { reader_thread, } } + pub fn new_mirrored_session(win_size: Size) -> Self { + let sess = ssh_connect(); + let mut channel = sess.channel_session().unwrap(); + let mut rows = Dimension::fixed(win_size.rows); + let mut cols = Dimension::fixed(win_size.cols); + rows.set_inner(win_size.rows); + cols.set_inner(win_size.cols); + let pane_geom = PaneGeom { + x: 0, + y: 0, + rows, + cols, + }; + setup_remote_environment(&mut channel, win_size); + start_zellij_mirrored_session(&mut channel); + let channel = Arc::new(Mutex::new(channel)); + let last_snapshot = Arc::new(Mutex::new(String::new())); + let cursor_coordinates = Arc::new(Mutex::new((0, 0))); + sess.set_blocking(false); + let reader_thread = + read_from_channel(&channel, &last_snapshot, &cursor_coordinates, &pane_geom); + RemoteRunner { + steps: vec![], + channel, + currently_running_step: None, + current_step_index: 0, + retries_left: RETRIES, + retry_pause_ms: 100, + test_timed_out: false, + panic_on_no_retries_left: true, + last_snapshot, + cursor_coordinates, + reader_thread, + } + } pub fn kill_running_sessions(win_size: Size) { let sess = ssh_connect(); let mut channel = sess.channel_session().unwrap(); setup_remote_environment(&mut channel, win_size); start_zellij(&mut channel); } - pub fn new_with_session_name(win_size: Size, session_name: &str) -> Self { + pub fn new_with_session_name(win_size: Size, session_name: &str, mirrored: bool) -> Self { // notice that this method does not have a timeout, so use with caution! let sess = ssh_connect_without_timeout(); let mut channel = sess.channel_session().unwrap(); @@ -354,7 +403,7 @@ impl RemoteRunner { cols, }; setup_remote_environment(&mut channel, win_size); - start_zellij_in_session(&mut channel, session_name); + start_zellij_in_session(&mut channel, session_name, mirrored); let channel = Arc::new(Mutex::new(channel)); let last_snapshot = Arc::new(Mutex::new(String::new())); let cursor_coordinates = Arc::new(Mutex::new((0, 0))); diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_panes_and_same_tab-2.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_panes_and_same_tab-2.snap new file mode 100644 index 000000000..5868eb441 --- /dev/null +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_panes_and_same_tab-2.snap @@ -0,0 +1,29 @@ +--- +source: src/tests/e2e/cases.rs +expression: second_runner_snapshot + +--- + Zellij (multiple_users_in_same_pane_and_tab) Tab #1 [ ] +┌ Pane #1 ───────────┤ FOCUSED USER: ├───────────────────┐┌ Pane #2 ──────────────┤ MY FOCUS ├───────────────────────┐ +│$ ││$ █ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘ + Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SCROLL <o> SESSION <q> QUIT + Tip: Alt + <n> => new pane. Alt + <[] or hjkl> => navigate. Alt + <+-> => resize pane. diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_panes_and_same_tab.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_panes_and_same_tab.snap new file mode 100644 index 000000000..e9355a449 --- /dev/null +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_panes_and_same_tab.snap @@ -0,0 +1,29 @@ +--- +source: src/tests/e2e/cases.rs +expression: first_runner_snapshot + +--- + Zellij (multiple_users_in_same_pane_and_tab) Tab #1 [ ] +┌ Pane #1 ──────────────┤ MY FOCUS ├───────────────────────┐┌ Pane #2 ───────────┤ FOCUSED USER: ├───────────────────┐ +│$ █ ││$ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘ + Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SCROLL <o> SESSION <q> QUIT + Tip: Alt + <n> => new pane. Alt + <[] or hjkl> => navigate. Alt + <+-> => resize pane. diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_tabs-2.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_tabs-2.snap new file mode 100644 index 000000000..7b983dfdd --- /dev/null +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__multiple_users_in_different_tabs-2.snap @@ -0,0 +1,29 @@ +--- +source: src/tests/e2e/cases.rs +expression: second_runner_snapshot + +--- + Zellij (multiple_users_in_different_tabs) Tab #1 [ ] Tab #2 +┌ Pane #1 ────────────────────────────────────────────┤ MY FOCUS ├─────────────────────────────────────────────────────┐ +│$ █ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ |