aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/e2e
diff options
context:
space:
mode:
authorThomas Linford <tlinford@users.noreply.github.com>2021-07-02 16:40:50 +0200
committerGitHub <noreply@github.com>2021-07-02 16:40:50 +0200
commitf93308f211565fae527f9b1e5788e12d0ea887c4 (patch)
treeedb915be32a81c1caae2c7218398c96344a29bd0 /src/tests/e2e
parentchore(changelog): Add run-command option #596 (diff)
downloadsl0ppij-f93308f211565fae527f9b1e5788e12d0ea887c4.tar.gz
sl0ppij-f93308f211565fae527f9b1e5788e12d0ea887c4.tar.xz
sl0ppij-f93308f211565fae527f9b1e5788e12d0ea887c4.zip
feat(ui): initial mouse support (#448)
* Initial mouse support * enable mouse support (termion MouseTerminal) * handle scroll up and down events * Allow enabling/disabling of mouse reporting Store the mouse terminal on OsInputOutput * WIP: switch pane focus with mouse * testing to get mouse character selection * wip mouse selection * wip: mouse selection - initial handling of mouse events for text selection within a pane - wide characters currently problematic - selection is not highlighted * highlight currently selected text * improve get currently selected text from TerminalPane * copy selection to clipboard (wayland only for now) * Add missing set_should_render on selection update * Improve text selection - Strip whitespace from end of lines - Insert newlines when selection spans multiple lines * Simplify selection logic - Remove Range struct - Selection is not an Option anymore, it's empty when start == end * copy selection to clipboard with OSC-52 sequence * Improve text selection with multiple panes - Constrain mouse hold and release events to currently active pane - Fix calculation of columns with side by side panes * fix for PositionAndSize changes * Fix mouse selection with full screen pane. - Transform mouse event positions to relative when passing to pane. * Move selection to grid, rework highlighting. - Mark selected lines for update in grid output buffer, for now in the simplest way possible, but can be made more efficient by calculating changed lines only. - Clear selection on pane resize. - Re-add logic to forward mouse hold and release events only to currently active pane. * Tidy up selection - add method to get selection line range - add method to sort the current selection * Grid: move current selection up/down when scrolling - Make the selection work with lines in lines_above and lines_below - Todo: update selection end when scrolling with mouse button being held - Todo: figure out how to move selection when new characters are added. * Grid: move selection when new lines are added * Keep track of selection being active - Handle the selection growing/shrinking when scrolling with mouse button held down but not yet released. * Improve selection end with multiple panes * Tidying up - remove logging statements, unused code * Add some unit tests for selection, move position to zellij-utils * Change Position::new to take i32 for line * Grid: add unit tests for copy from selection * add basic integration test for mouse pane focus * Add basic integration test for mouse scroll * Use color from palette for selection rendering * Improve performance of selection render - Try to minimize lines to update on selection start/update/end * fixes for updated start method * fix lines not in viewport being marked for rendering - the previous optimization to grid selection rendering was always adding the lines at the extremes of previous selection, causing problems when scrolling up or down - make sure to only add lines in viewport * Disable mouse mode on exit * use saturating_sub for usize subtractions * copy selection to clipboard on mouse release * disable mouse on exit after error * remove left-over comments * remove copy keybinding * add default impl for selection methods in Pane - remove the useless methods from Impl Pane in PluginPane * move line diff between selections to selection * add option to disable mouse mode * Allow scrolling with mouse while selecting. * move action repeater to os_input_output, change timeout to 10ms - change repeater to take an action instead of a position with hardcoded action * replace mouse mode integration tests with e2e tests * cleanup * cleanup * check if mouse mode is disabled from merged options * fix missing changes in tests, cleanup
Diffstat (limited to 'src/tests/e2e')
-rw-r--r--src/tests/e2e/cases.rs154
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_pane_with_mouse.snap29
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane_with_mouse.snap29
3 files changed, 211 insertions, 1 deletions
diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs
index 69233f25..8d41d44f 100644
--- a/src/tests/e2e/cases.rs
+++ b/src/tests/e2e/cases.rs
@@ -1,7 +1,7 @@
#![allow(unused)]
use ::insta::assert_snapshot;
-use zellij_utils::pane_size::PositionAndSize;
+use zellij_utils::{pane_size::PositionAndSize, position::Position};
use rand::Rng;
@@ -54,6 +54,17 @@ pub const BRACKETED_PASTE_START: [u8; 6] = [27, 91, 50, 48, 48, 126]; // \u{1b}[
pub const BRACKETED_PASTE_END: [u8; 6] = [27, 91, 50, 48, 49, 126]; // \u{1b}[201
pub const SLEEP: [u8; 0] = [];
+// simplified, slighty adapted version of alacritty mouse reporting code
+pub fn normal_mouse_report(position: Position, button: u8) -> Vec<u8> {
+ let Position { line, column } = position;
+
+ let mut command = vec![b'\x1b', b'[', b'M', 32 + button];
+ command.push(32 + 1 + column.0 as u8);
+ command.push(32 + 1 + line.0 as u8);
+
+ command
+}
+
// All the E2E tests are marked as "ignored" so that they can be run separately from the normal
// tests
@@ -785,3 +796,144 @@ pub fn accepts_basic_layout() {
.run_all_steps();
assert_snapshot!(last_snapshot);
}
+
+#[test]
+#[ignore]
+fn focus_pane_with_mouse() {
+ let fake_win_size = PositionAndSize {
+ cols: 120,
+ rows: 24,
+ x: 0,
+ y: 0,
+ ..Default::default()
+ };
+
+ let last_snapshot = RemoteRunner::new("split_terminals_vertically", fake_win_size, None)
+ .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(2, 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: "Click left 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() {
+ remote_terminal.send_key(&normal_mouse_report(Position::new(5, 2), 0));
+ step_is_complete = true;
+ }
+ step_is_complete
+ },
+ })
+ .add_step(Step {
+ name: "Wait for left pane to be focused",
+ instruction: |remote_terminal: RemoteTerminal| -> bool {
+ let mut step_is_complete = false;
+ if remote_terminal.cursor_position_is(2, 2) && remote_terminal.tip_appears() {
+ // cursor is in the newly opened second pane
+ step_is_complete = true;
+ }
+ step_is_complete
+ },
+ })
+ .run_all_steps();
+ assert_snapshot!(last_snapshot);
+}
+
+#[test]
+#[ignore]
+pub fn scrolling_inside_a_pane_with_mouse() {
+ let fake_win_size = PositionAndSize {
+ cols: 120,
+ rows: 24,
+ x: 0,
+ y: 0,
+ ..Default::default()
+ };
+ let last_snapshot =
+ RemoteRunner::new("scrolling_inside_a_pane_with_mouse", fake_win_size, None)
+ .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(2, 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
+ remote_terminal.send_key(&format!("{:0<57}", "line1 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line2 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line3 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line4 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line5 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line6 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line7 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line8 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line9 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line10 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line11 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line12 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line13 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line14 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line15 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line16 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line17 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line18 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<59}", "line19 ").as_bytes());
+ remote_terminal.send_key(&format!("{:0<58}", "line20 ").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(119, 20) {
+ // all lines have been written to the pane
+ remote_terminal.send_key(&normal_mouse_report(Position::new(2, 64), 64));
+ step_is_complete = true;
+ }
+ step_is_complete
+ },
+ })
+ .add_step(Step {
+ name: "Wait for scroll to finish",
+ instruction: |remote_terminal: RemoteTerminal| -> bool {
+ let mut step_is_complete = false;
+ if remote_terminal.cursor_position_is(119, 20)
+ && remote_terminal.snapshot_contains("line1 ")
+ {
+ // scrolled up one line
+ step_is_complete = true;
+ }
+ step_is_complete
+ },
+ })
+ .run_all_steps();
+ assert_snapshot!(last_snapshot);
+}
diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_pane_with_mouse.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_pane_with_mouse.snap
new file mode 100644
index 00000000..79e84810
--- /dev/null
+++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_pane_with_mouse.snap
@@ -0,0 +1,29 @@
+---
+source: src/tests/e2e/cases.rs
+expression: last_snapshot
+
+---
+ Zellij  Tab #1 
+
+$ █ │$
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+ │
+
+ Ctrl + <g> LOCK  <p> PANE  <t> TAB  <r> RESIZE  <s> SCROLL  <o> SESSION  <q> QUIT 
+ Tip: Alt + n => open new pane. Alt + [] or hjkl => navigate between panes.
diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane_with_mouse.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane_with_mouse.snap
new file mode 100644
index 00000000..bff40376
--- /dev/null
+++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane_with_mouse.snap
@@ -0,0 +1,29 @@
+---
+source: src/tests/e2e/cases.rs
+expression: last_snapshot
+
+---
+ Zellij  Tab #1 
+
+$ │$ line1 000000000000000000000000000000000000000000000000000
+ │line2 00000000000000000000000000000000000000000000000000000
+ │line3 00000000000000000000000000000000000000000000000000000
+ │line4 00000000000000000000000000000000000000000000000000000
+ │line5 00000000000000000000000000000000000000000000000000000
+ │line6 00000000000000000000000000000000000000000000000000000
+ │line7 00000000000000000000000000000000000000000000000000000
+ │line8 00000000000000000000000000000000000000000000000000000
+ │line9 00000000000000000000000000000000000000000000000000000
+ │line10 0000000000000000000000000000000000000000000000000000
+ │line11 0000000000000000000000000000000000000000000000000000
+ │line12 0000000000000000000000000000000000000000000000000000
+ │line13 0000000000000000000000000000000000000000000000000000
+ │line14 0000000000000000000000000000000000000000000000000000
+ │line15 0000000000000000000000000000000000000000000000000000
+ │line16 0000000000000000000000000000000000000000000000000000
+ │line17 0000000000000000000000000000000000000000000000000000
+ │line18 0000000000000000000000000000000000000000000000000000
+ │line19 000000000000000000000000000000000000000000000000000█
+
+ Ctrl + <g> LOCK  <p> PANE  <t> TAB  <r> RESIZE  <s> SCROLL  <o> SESSION  <q> QUIT 
+ Tip: Alt + n => open new pane. Alt + [] or hjkl => navigate between panes.