diff options
| author | har7an <99636919+har7an@users.noreply.github.com> | 2026-01-26 18:05:51 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-26 18:05:51 +0000 |
| commit | bdf20eef50f2d68501be708ec5ee38dbe9366a91 (patch) | |
| tree | e97215a9464d322eb65e416b1662c530e44d57f1 /src/tests/e2e | |
| parent | fix: get "zellij run --session" to also work on sessions that have no attache... (diff) | |
| download | sl0ppij-bdf20eef50f2d68501be708ec5ee38dbe9366a91.tar.gz sl0ppij-bdf20eef50f2d68501be708ec5ee38dbe9366a91.tar.xz sl0ppij-bdf20eef50f2d68501be708ec5ee38dbe9366a91.zip | |
Fix loading short layouts and custom config dirs (#4640)
* test(e2e): Write a regression test to validate behavior
w.r.t. loading and determining the session layout file. Compared to
release v0.43.1, right now there is a problem where `zellij --layout
NAME`, with `NAME` being the filename of a layout in the
`$ZELLIJ_DATA_DIR/layouts/` subfolder, doesn't resolve to the correct
layout file. Instead, zellij will silently fall back to its default
config. It does, however, recognize nonexistent configuration files.
* fix(utils): Treat bare layout names as file paths first
before defaulting to builtin layout names. This restores the behavior
shown by zellij up until 0.43.1, which was altered in a recent extension
of the server-client API.
* fix: Forward client layout information to startup code
and ensure it isn't ignored along the way. Update a bunch of tests to
react to the new function interface and write new tests to catch
deviations in the future.
* test: Fix misconfigured e2e test
to ensure that a custom `--config-dir` is indeed respected during
application startup.
* test: Rewrite config dir test to not use variable metadata
since the `LayoutInfo` object previously dumped into the snapshot
contains information that isn't platform agnostic, including an absolute
file path and a timestamp.
* docs(CHANGELOG): Mention PR #4640
in the list of changes for the next release.
* fix: Handle bare layouts with name "default" correctly
and assume a "default" layout if no layout name is given during layout
resolution. "default" may not always be the builtin default layout,
since users can write their own "default.kdl" that takes effect when
placed in the layout directory an no other layouts are explicitly
specified.
Diffstat (limited to 'src/tests/e2e')
| -rw-r--r-- | src/tests/e2e/cases.rs | 34 | ||||
| -rw-r--r-- | src/tests/e2e/remote_runner.rs | 58 | ||||
| -rw-r--r-- | src/tests/e2e/snapshots/zellij__tests__e2e__cases__use_custom_layout_with_relative_path.snap | 28 |
3 files changed, 120 insertions, 0 deletions
diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index f7d9ea0d..96fb9c12 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -2898,3 +2898,37 @@ pub fn override_layout_from_default_to_compact() { let last_snapshot = account_for_races_in_snapshot(last_snapshot); assert_snapshot!(last_snapshot); } + +#[test] +#[ignore] +pub fn use_custom_layout_with_relative_path() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; + // Should resolve to $fixtures/layouts/upside-down.kdl + let config_dir_name = "e2e-upside-down"; + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + let mut runner = RemoteRunner::new_with_config_dir(fake_win_size, config_dir_name); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { + name: "Wait for app to start", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let lines = remote_terminal.lines(); + lines.len() > 2 + && lines[0].trim().starts_with("Ctrl +") + && lines[1].trim().starts_with("Tip:") + }, + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; + let last_snapshot = account_for_races_in_snapshot(last_snapshot); + assert_snapshot!(last_snapshot); +} diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs index 1fa5d703..483e605d 100644 --- a/src/tests/e2e/remote_runner.rs +++ b/src/tests/e2e/remote_runner.rs @@ -20,6 +20,7 @@ use std::rc::Rc; const ZELLIJ_EXECUTABLE_LOCATION: &str = "/usr/src/zellij/x86_64-unknown-linux-musl/release/zellij"; const SET_ENV_VARIABLES: &str = "EDITOR=/usr/bin/vi"; const ZELLIJ_CONFIG_PATH: &str = "/usr/src/zellij/fixtures/configs"; +const ZELLIJ_CONFIG_DIRS_PATH: &str = "/usr/src/zellij/fixtures/config-dirs"; const ZELLIJ_DATA_DIR: &str = "/usr/src/zellij/e2e-data"; const ZELLIJ_FIXTURE_PATH: &str = "/usr/src/zellij/fixtures"; const CONNECTION_STRING: &str = "127.0.0.1:2222"; @@ -91,6 +92,21 @@ fn start_zellij(channel: &mut ssh2::Channel) { std::thread::sleep(std::time::Duration::from_secs(3)); // wait until Zellij stops parsing startup ANSI codes from the terminal STDIN } +fn start_zellij_with_config_dir(channel: &mut ssh2::Channel, config_dir: &str) { + stop_zellij(channel); + channel + .write_all( + format!( + "{} {} --session {} --data-dir {} --config-dir {} options --show-release-notes false --show-startup-tips false\n", + SET_ENV_VARIABLES, ZELLIJ_EXECUTABLE_LOCATION, SESSION_NAME, ZELLIJ_DATA_DIR, format!("{}/{}", ZELLIJ_CONFIG_DIRS_PATH, config_dir) + ) + .as_bytes(), + ) + .unwrap(); + channel.flush().unwrap(); + std::thread::sleep(std::time::Duration::from_secs(3)); // wait until Zellij stops parsing startup ANSI codes from the terminal STDIN +} + fn start_zellij_mirrored_session(channel: &mut ssh2::Channel) { stop_zellij(channel); channel @@ -384,6 +400,10 @@ impl RemoteTerminal { pub fn snapshot_contains(&self, text: &str) -> bool { self.last_snapshot.lock().unwrap().contains(text) } + pub fn lines(&self) -> Vec<String> { + let s = self.last_snapshot.lock().unwrap(); + s.lines().map(|s| s.to_owned()).collect::<Vec<_>>() + } #[allow(unused)] pub fn current_snapshot(&self) -> String { // convenience method for writing tests, @@ -527,6 +547,44 @@ impl RemoteRunner { reader_thread, } } + pub fn new_with_config_dir(win_size: Size, config_dir_name: &str) -> 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, + stacked: None, + is_pinned: false, + logical_position: None, + }; + setup_remote_environment(&mut channel, win_size); + start_zellij_with_config_dir(&mut channel, config_dir_name); + 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 new_mirrored_session(win_size: Size) -> Self { let sess = ssh_connect(); let mut channel = sess.channel_session().unwrap(); diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__use_custom_layout_with_relative_path.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__use_custom_layout_with_relative_path.snap new file mode 100644 index 00000000..ff7b4f51 --- /dev/null +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__use_custom_layout_with_relative_path.snap @@ -0,0 +1,28 @@ +--- +source: src/tests/e2e/cases.rs +expression: last_snapshot +--- + Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SEARCH <o> SESSION <q> QUIT + Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane. +┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│$ █ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + Zellij (e2e-test) Tab #1 |
