aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/e2e
diff options
context:
space:
mode:
authorhar7an <99636919+har7an@users.noreply.github.com>2026-01-26 18:05:51 +0000
committerGitHub <noreply@github.com>2026-01-26 18:05:51 +0000
commitbdf20eef50f2d68501be708ec5ee38dbe9366a91 (patch)
treee97215a9464d322eb65e416b1662c530e44d57f1 /src/tests/e2e
parentfix: get "zellij run --session" to also work on sessions that have no attache... (diff)
downloadsl0ppij-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.rs34
-rw-r--r--src/tests/e2e/remote_runner.rs58
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__use_custom_layout_with_relative_path.snap28
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 