diff options
-rw-r--r-- | src/tests/e2e/cases.rs | 1458 | ||||
-rw-r--r-- | src/tests/e2e/remote_runner.rs | 412 | ||||
-rw-r--r-- | src/tests/e2e/snapshots/zellij__tests__e2e__cases__cannot_split_terminals_vertically_when_active_terminal_is_too_small.snap | 2 | ||||
-rw-r--r-- | src/tests/e2e/snapshots/zellij__tests__e2e__cases__close_tab.snap | 50 | ||||
-rw-r--r-- | src/tests/e2e/snapshots/zellij__tests__e2e__cases__mirrored_sessions-2.snap | 29 | ||||
-rw-r--r-- | src/tests/e2e/snapshots/zellij__tests__e2e__cases__mirrored_sessions.snap | 8 | ||||
-rw-r--r-- | src/tests/e2e/snapshots/zellij__tests__e2e__cases__typing_exit_closes_pane.snap | 29 | ||||
-rw-r--r-- | zellij-server/src/screen.rs | 107 | ||||
-rw-r--r-- | zellij-server/src/tab.rs | 568 | ||||
-rw-r--r-- | zellij-server/src/unit/tab_tests.rs | 1132 | ||||
-rw-r--r-- | zellij-server/src/wasm_vm.rs | 16 |
11 files changed, 2253 insertions, 1558 deletions
diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index aa8ad34b8..0198adfe0 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -75,8 +75,12 @@ pub fn starts_with_one_terminal() { cols: 120, rows: 24, }; - let last_snapshot = RemoteRunner::new("starts_with_one_terminal", fake_win_size) - .add_step(Step { + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size); + let last_snapshot = runner.take_snapshot_after(Step { name: "Wait for app to load", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -86,8 +90,13 @@ pub fn starts_with_one_terminal() { } step_is_complete }, - }) - .run_all_steps(); + }); + if runner.test_timed_out && test_attempts > 0 { + continue; + } else { + break last_snapshot; + } + }; assert_snapshot!(last_snapshot); } @@ -99,8 +108,11 @@ pub fn split_terminals_vertically() { rows: 24, }; - let last_snapshot = RemoteRunner::new("split_terminals_vertically", fake_win_size) - .add_step(Step { + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size).add_step(Step { name: "Split pane to the right", instruction: |mut remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -114,8 +126,9 @@ pub fn split_terminals_vertically() { } step_is_complete }, - }) - .add_step(Step { + }); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { name: "Wait for new pane to appear", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -125,8 +138,14 @@ pub fn split_terminals_vertically() { } step_is_complete }, - }) - .run_all_steps(); + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; assert_snapshot!(last_snapshot); } @@ -134,49 +153,11 @@ pub fn split_terminals_vertically() { #[ignore] pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() { let fake_win_size = Size { cols: 8, rows: 20 }; - let last_snapshot = RemoteRunner::new( - "cannot_split_terminals_vertically_when_active_terminal_is_too_small", - fake_win_size, - ) - .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 - }, - }) - .add_step(Step { - 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("...") - { - // ... is the truncated tip line - step_is_complete = true; - } - step_is_complete - }, - }) - .run_all_steps(); - assert_snapshot!(last_snapshot); -} - -#[test] -#[ignore] -pub fn scrolling_inside_a_pane() { - let fake_win_size = Size { - cols: 120, - rows: 24, - }; - let last_snapshot = RemoteRunner::new("scrolling_inside_a_pane", fake_win_size) - .add_step(Step { + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size).add_step(Step { name: "Split pane to the right", instruction: |mut remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -190,52 +171,109 @@ pub fn scrolling_inside_a_pane() { } step_is_complete }, - }) - .add_step(Step { - name: "Fill terminal with text", - instruction: |mut 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 - remote_terminal.send_key(format!("{:0<56}", "line1 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line2 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line3 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line4 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line5 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line6 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line7 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line8 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line9 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line10 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line11 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line12 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line13 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line14 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line15 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line16 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line17 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line18 ").as_bytes()); - remote_terminal.send_key(format!("{:0<58}", "line19 ").as_bytes()); - remote_terminal.send_key(format!("{:0<57}", "line20 ").as_bytes()); - step_is_complete = true; - } - step_is_complete - }, - }) - .add_step(Step { - name: "Scroll up inside pane", - instruction: |mut remote_terminal: RemoteTerminal| -> bool { + }); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { + name: "Make sure only one pane appears", + instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(118, 20) { - // all lines have been written to the pane - remote_terminal.send_key(&SCROLL_MODE); - remote_terminal.send_key(&SCROLL_UP_IN_SCROLL_MODE); + // 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; } step_is_complete }, - }) - .add_step(Step { + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; + assert_snapshot!(last_snapshot); +} + +#[test] +#[ignore] +pub fn scrolling_inside_a_pane() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size) + .retry_pause_ms(1000) // we need a longer retry period here because it takes some time to fill the pty buffer + .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 + }, + }) + .add_step(Step { + name: "Fill terminal with text", + instruction: |mut 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 + let mut content_to_send = String::new(); + content_to_send.push_str(&format!("{:0<56}", "line1 ")); + content_to_send.push_str(&format!("{:0<58}", "line2 ")); + content_to_send.push_str(&format!("{:0<58}", "line3 ")); + content_to_send.push_str(&format!("{:0<58}", "line4 ")); + content_to_send.push_str(&format!("{:0<58}", "line5 ")); + content_to_send.push_str(&format!("{:0<58}", "line6 ")); + content_to_send.push_str(&format!("{:0<58}", "line7 ")); + content_to_send.push_str(&format!("{:0<58}", "line8 ")); + content_to_send.push_str(&format!("{:0<58}", "line9 ")); + content_to_send.push_str(&format!("{:0<58}", "line10 ")); + content_to_send.push_str(&format!("{:0<58}", "line11 ")); + content_to_send.push_str(&format!("{:0<58}", "line12 ")); + content_to_send.push_str(&format!("{:0<58}", "line13 ")); + content_to_send.push_str(&format!("{:0<58}", "line14 ")); + content_to_send.push_str(&format!("{:0<58}", "line15 ")); + content_to_send.push_str(&format!("{:0<58}", "line16 ")); + content_to_send.push_str(&format!("{:0<58}", "line17 ")); + content_to_send.push_str(&format!("{:0<58}", "line18 ")); + content_to_send.push_str(&format!("{:0<58}", "line19 ")); + content_to_send.push_str(&format!("{:0<57}", "line20 ")); + + remote_terminal.send_key(content_to_send.as_bytes()); + + step_is_complete = true; + } + step_is_complete + }, + }) + .add_step(Step { + name: "Scroll up inside pane", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(118, 20) { + // all lines have been written to the pane + remote_terminal.send_key(&SCROLL_MODE); + remote_terminal.send_key(&SCROLL_UP_IN_SCROLL_MODE); + step_is_complete = true; + } + step_is_complete + }, + }); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { name: "Wait for scroll to finish", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -247,8 +285,14 @@ pub fn scrolling_inside_a_pane() { } step_is_complete }, - }) - .run_all_steps(); + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; assert_snapshot!(last_snapshot); } @@ -259,38 +303,44 @@ pub fn toggle_pane_fullscreen() { cols: 120, rows: 24, }; - let last_snapshot = RemoteRunner::new("toggle_pane_fullscreen", fake_win_size) - .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 - }, - }) - .add_step(Step { - name: "Change newly opened pane to be fullscreen", - instruction: |mut 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 - remote_terminal.send_key(&PANE_MODE); - remote_terminal.send_key(&TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE); - // back to normal mode after toggling fullscreen - remote_terminal.send_key(&ENTER); - step_is_complete = true; - } - step_is_complete - }, - }) - .add_step(Step { + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size) + .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 + }, + }) + .add_step(Step { + name: "Change newly opened pane to be fullscreen", + instruction: |mut 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 + remote_terminal.send_key(&PANE_MODE); + remote_terminal.send_key(&TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE); + // back to normal mode after toggling fullscreen + remote_terminal.send_key(&ENTER); + step_is_complete = true; + } + step_is_complete + }, + }); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { name: "Wait for pane to become fullscreen", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -300,8 +350,14 @@ pub fn toggle_pane_fullscreen() { } step_is_complete }, - }) - .run_all_steps(); + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; assert_snapshot!(last_snapshot); } @@ -312,38 +368,44 @@ pub fn open_new_tab() { cols: 120, rows: 24, }; - let last_snapshot = RemoteRunner::new("open_new_tab", fake_win_size) - .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 - }, - }) - .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(63, 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 - }, - }) - .add_step(Step { + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size) + .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 + }, + }) + .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(63, 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 + }, + }); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { name: "Wait for new tab to open", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; @@ -357,50 +419,146 @@ pub fn open_new_tab() { } step_is_complete }, - }) - .run_all_steps(); + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; assert_snapshot!(last_snapshot); } #[test] #[ignore] -pub fn close_pane() { +pub fn close_tab() { let fake_win_size = Size { cols: 120, rows: 24, }; - let last_snapshot = RemoteRunner::new("close_pane", fake_win_size) - .add_step(Step { - name: "Split pane to the right", + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + drop(()); + let mut runner = RemoteRunner::new(fake_win_size) + .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 + }, + }) + .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(63, 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 + remote_terminal.send_key(&ENTER); + step_is_complete = true; + } + step_is_complete + }, + }) + .add_step(Step { + name: "Close 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() + && remote_terminal.snapshot_contains("Tab #2") + && remote_terminal.status_bar_appears() + { + // cursor is in the newly opened second tab + remote_terminal.send_key(&TAB_MODE); + remote_terminal.send_key(&CLOSE_TAB_IN_TAB_MODE); + step_is_complete = true; + } + step_is_complete + }, + }); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { + name: "Wait for tab to close", 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) + if remote_terminal.cursor_position_is(3, 2) + && !remote_terminal.snapshot_contains("Tab #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); + // cursor is in the first tab again step_is_complete = true; } step_is_complete }, - }) - .add_step(Step { - name: "Close pane", - instruction: |mut 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 - remote_terminal.send_key(&PANE_MODE); - remote_terminal.send_key(&CLOSE_PANE_IN_PANE_MODE); - // back to normal mode after close - remote_terminal.send_key(&ENTER); - step_is_complete = true; - } - step_is_complete - }, - }) - .add_step(Step { + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; + assert_snapshot!(last_snapshot); +} + +#[test] +#[ignore] +pub fn close_pane() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; |