aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-12 19:07:07 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-12 19:10:09 +0300
commitf7a7da03fc27cc6fe4e6a44dabddcd303f939bb9 (patch)
tree69a00241e4500703bb723b64dd0060cc83730a0b /tests
parent53429206b736aa0fcfb1c5bfc1c0b11dcca3a059 (diff)
fix: stabilize public pane and tab ids
refs #569
Diffstat (limited to 'tests')
-rw-r--r--tests/api_ping.rs86
-rw-r--r--tests/cli_wrapper.rs55
-rw-r--r--tests/live_handoff.rs8
3 files changed, 95 insertions, 54 deletions
diff --git a/tests/api_ping.rs b/tests/api_ping.rs
index df0b5908..7f4271bc 100644
--- a/tests/api_ping.rs
+++ b/tests/api_ping.rs
@@ -406,7 +406,7 @@ fn workspace_list_and_create_round_trip() {
assert_eq!(created["result"]["workspace"]["tab_count"], 1);
assert_eq!(created["result"]["tab"]["tab_id"], active_tab_id);
assert_eq!(created["result"]["root_pane"]["tab_id"], active_tab_id);
- assert_eq!(active_tab_id, format!("{workspace_id}:1"));
+ assert_eq!(active_tab_id, format!("{workspace_id}:t1"));
let listed = send_request(
&socket_path,
@@ -436,6 +436,7 @@ fn workspace_list_and_create_round_trip() {
let pane_id = panes[0]["pane_id"].as_str().unwrap().to_string();
assert_eq!(pane_id, root_pane_id);
assert_eq!(panes[0]["terminal_id"], root_terminal_id);
+ let legacy_pane_id = format!("{workspace_id}-1");
let pane = send_request(
&socket_path,
@@ -451,7 +452,7 @@ fn workspace_list_and_create_round_trip() {
&socket_path,
&format!(
r#"{{"id":"req_8","method":"pane.read","params":{{"pane_id":"{}","source":"visible"}}}}"#,
- pane_id
+ legacy_pane_id
),
);
assert_eq!(read["result"]["read"]["pane_id"], pane_id);
@@ -492,10 +493,12 @@ fn workspace_list_and_create_round_trip() {
&socket_path,
&format!(
r#"{{"id":"req_12","method":"pane.wait_for_output","params":{{"pane_id":"{}","source":"recent","lines":40,"match":{{"type":"substring","value":"gamma"}},"timeout_ms":2000}}}}"#,
- pane_id
+ legacy_pane_id
),
);
assert_eq!(waited["result"]["type"], "output_matched");
+ assert_eq!(waited["result"]["pane_id"], pane_id);
+ assert_eq!(waited["result"]["read"]["pane_id"], pane_id);
assert!(waited["result"]["matched_line"]
.as_str()
.unwrap()
@@ -522,6 +525,8 @@ fn workspace_list_and_create_round_trip() {
),
);
assert_eq!(waited_delta["result"]["type"], "output_matched");
+ assert_eq!(waited_delta["result"]["pane_id"], pane_id);
+ assert_eq!(waited_delta["result"]["read"]["pane_id"], pane_id);
assert!(waited_delta["result"]["matched_line"]
.as_str()
.unwrap()
@@ -535,6 +540,8 @@ fn workspace_list_and_create_round_trip() {
),
);
assert_eq!(waited_regex["result"]["type"], "output_matched");
+ assert_eq!(waited_regex["result"]["pane_id"], pane_id);
+ assert_eq!(waited_regex["result"]["read"]["pane_id"], pane_id);
assert!(waited_regex["result"]["matched_line"]
.as_str()
.unwrap()
@@ -579,7 +586,7 @@ fn tab_methods_round_trip_over_socket() {
.as_str()
.unwrap()
.to_string();
- assert_eq!(first_tab_id, format!("{workspace_id}:1"));
+ assert_eq!(first_tab_id, format!("{workspace_id}:t1"));
let tab_created = send_request(
&socket_path,
@@ -603,7 +610,7 @@ fn tab_methods_round_trip_over_socket() {
.to_string();
assert!(second_root_terminal_id.starts_with("term_"));
assert_ne!(second_root_terminal_id, second_root_pane_id);
- assert_eq!(second_tab_id, format!("{workspace_id}:2"));
+ assert_eq!(second_tab_id, format!("{workspace_id}:t2"));
assert_eq!(tab_created["result"]["tab"]["focused"], true);
assert_eq!(tab_created["result"]["root_pane"]["tab_id"], second_tab_id);
@@ -698,7 +705,6 @@ fn pane_info_reports_foreground_cwd_without_changing_pane_cwd() {
.as_str()
.unwrap()
.to_string();
-
let command = format!(
"/bin/sh -c 'cd {} && printf %s $$ > {} && touch {} && sleep 30'",
foreground.display(),
@@ -1044,7 +1050,7 @@ fn tab_create_with_no_focus_preserves_active_tab() {
.as_str()
.unwrap()
.to_string();
- assert_eq!(second_tab_id, format!("{workspace_id}:2"));
+ assert_eq!(second_tab_id, format!("{workspace_id}:t2"));
assert_eq!(tab_created["result"]["tab"]["focused"], false);
let tab_list = send_request(
@@ -1140,7 +1146,7 @@ fn events_subscribe_streams_workspace_tab_and_agent_events() {
let workspace_focused = event_by_kind(&initial_events, "workspace_focused");
assert_eq!(workspace_focused["data"]["workspace_id"], workspace_id);
- let first_tab_id = format!("{workspace_id}:1");
+ let first_tab_id = format!("{workspace_id}:t1");
let tab_created = event_by_kind(&initial_events, "tab_created");
assert_eq!(tab_created["data"]["tab"]["tab_id"], first_tab_id);
let tab_focused = event_by_kind(&initial_events, "tab_focused");
@@ -1186,7 +1192,7 @@ fn events_subscribe_streams_workspace_tab_and_agent_events() {
.as_str()
.unwrap()
.to_string();
- assert_eq!(second_tab_id, format!("{workspace_id}:2"));
+ assert_eq!(second_tab_id, format!("{workspace_id}:t2"));
let created_tab_event = wait_for_event(&mut reader, "tab_created", Duration::from_secs(2));
assert_eq!(created_tab_event["data"]["tab"]["tab_id"], second_tab_id);
@@ -1227,11 +1233,14 @@ fn events_subscribe_streams_pane_split_and_close_events() {
base.display()
),
);
+ let pane_id = created["result"]["root_pane"]["pane_id"]
+ .as_str()
+ .unwrap()
+ .to_string();
let workspace_id = created["result"]["workspace"]["workspace_id"]
.as_str()
.unwrap()
.to_string();
- let pane_id = format!("{workspace_id}-1");
let mut reader = open_subscription(
&socket_path,
@@ -1265,8 +1274,8 @@ fn events_subscribe_streams_pane_split_and_close_events() {
let closed = send_request(
&socket_path,
&format!(
- r#"{{"id":"req_pc_3","method":"pane.close","params":{{"pane_id":"{}"}}}}"#,
- split_pane_id
+ r#"{{"id":"req_pc_3","method":"pane.close","params":{{"pane_id":"{}-2"}}}}"#,
+ workspace_id
),
);
assert_eq!(closed["result"]["type"], "ok");
@@ -1330,8 +1339,8 @@ fn events_subscribe_streams_tab_and_workspace_close_events() {
let closed_tab = send_request(
&socket_path,
&format!(
- r#"{{"id":"req_tc_3","method":"tab.close","params":{{"tab_id":"{}"}}}}"#,
- second_tab_id
+ r#"{{"id":"req_tc_3","method":"tab.close","params":{{"tab_id":"{}:2"}}}}"#,
+ workspace_id
),
);
assert_eq!(closed_tab["result"]["type"], "ok");
@@ -1355,10 +1364,7 @@ fn events_subscribe_streams_tab_and_workspace_close_events() {
let closed_ws = send_request(
&socket_path,
- &format!(
- r#"{{"id":"req_tc_5","method":"workspace.close","params":{{"workspace_id":"{}"}}}}"#,
- workspace_id
- ),
+ r#"{"id":"req_tc_5","method":"workspace.close","params":{"workspace_id":"1"}}"#,
);
assert_eq!(closed_ws["result"]["type"], "ok");
@@ -1407,10 +1413,10 @@ fn pane_report_agent_updates_effective_state() {
base.display()
),
);
- let pane_id = created["result"]["workspace"]["workspace_id"]
+ let pane_id = created["result"]["root_pane"]["pane_id"]
.as_str()
- .map(|workspace_id| format!("{}-1", workspace_id))
- .unwrap();
+ .unwrap()
+ .to_string();
let send_pi = send_request(
&socket_path,
@@ -1597,10 +1603,10 @@ fn pane_report_agent_accepts_unknown_agent_labels() {
base.display()
),
);
- let pane_id = created["result"]["workspace"]["workspace_id"]
+ let pane_id = created["result"]["root_pane"]["pane_id"]
.as_str()
- .map(|workspace_id| format!("{}-1", workspace_id))
- .unwrap();
+ .unwrap()
+ .to_string();
let hook = send_request(
&socket_path,
@@ -1670,10 +1676,10 @@ fn pane_release_agent_suppresses_reacquire_during_graceful_exit() {
base.display()
),
);
- let pane_id = created["result"]["workspace"]["workspace_id"]
+ let pane_id = created["result"]["root_pane"]["pane_id"]
.as_str()
- .map(|workspace_id| format!("{}-1", workspace_id))
- .unwrap();
+ .unwrap()
+ .to_string();
let send_pi = send_request(
&socket_path,
@@ -1810,10 +1816,10 @@ fn pane_clear_agent_authority_restores_fallback_state() {
base.display()
),
);
- let pane_id = created["result"]["workspace"]["workspace_id"]
+ let pane_id = created["result"]["root_pane"]["pane_id"]
.as_str()
- .map(|workspace_id| format!("{}-1", workspace_id))
- .unwrap();
+ .unwrap()
+ .to_string();
let send_pi = send_request(
&socket_path,
@@ -1935,7 +1941,10 @@ fn events_subscribe_streams_output_and_agent_status_events() {
base.display()
),
);
- assert!(created["result"]["workspace"]["workspace_id"].is_string());
+ let workspace_id = created["result"]["workspace"]["workspace_id"]
+ .as_str()
+ .unwrap()
+ .to_string();
let panes = send_request(
&socket_path,
@@ -1945,12 +1954,13 @@ fn events_subscribe_streams_output_and_agent_status_events() {
.as_str()
.unwrap()
.to_string();
+ let legacy_pane_id = format!("{workspace_id}-1");
let mut reader = open_subscription(
&socket_path,
&format!(
r#"{{"id":"sub_1","method":"events.subscribe","params":{{"subscriptions":[{{"type":"pane.output_matched","pane_id":"{}","source":"recent","lines":40,"match":{{"type":"substring","value":"hello from socket"}}}},{{"type":"pane.agent_status_changed","pane_id":"{}","agent_status":"idle"}}]}}}}"#,
- pane_id, pane_id,
+ legacy_pane_id, legacy_pane_id,
),
);
@@ -1978,6 +1988,7 @@ fn events_subscribe_streams_output_and_agent_status_events() {
let output_event = reader.read_json_line(Duration::from_secs(3));
assert_eq!(output_event["event"], "pane.output_matched");
assert_eq!(output_event["data"]["pane_id"], pane_id);
+ assert_eq!(output_event["data"]["read"]["pane_id"], pane_id);
assert!(output_event["data"]["matched_line"]
.as_str()
.unwrap()
@@ -2062,7 +2073,10 @@ fn pane_info_and_subscriptions_expose_done_agent_status() {
.as_str()
.unwrap()
.to_string();
- let background_pane_id = format!("{}-1", workspace_id);
+ let background_pane_id = created["result"]["root_pane"]["pane_id"]
+ .as_str()
+ .unwrap()
+ .to_string();
let tab_created = send_request(
&socket_path,
@@ -2178,10 +2192,10 @@ fn metadata_status_subscription_filter_and_ttl_expiry_are_observable() {
base.display()
),
);
- let pane_id = created["result"]["workspace"]["workspace_id"]
+ let pane_id = created["result"]["root_pane"]["pane_id"]
.as_str()
- .map(|workspace_id| format!("{}-1", workspace_id))
- .unwrap();
+ .unwrap()
+ .to_string();
let report_agent = send_request(
&socket_path,
diff --git a/tests/cli_wrapper.rs b/tests/cli_wrapper.rs
index 117afe97..287be14b 100644
--- a/tests/cli_wrapper.rs
+++ b/tests/cli_wrapper.rs
@@ -1937,7 +1937,7 @@ fn tab_management_commands_work() {
.as_str()
.unwrap()
.to_string();
- assert_eq!(second_tab_id, format!("{workspace_id}:2"));
+ assert_eq!(second_tab_id, format!("{workspace_id}:t2"));
let listed_tabs = run_cli(&socket_path, &["tab", "list", "--workspace", &workspace_id]);
assert!(listed_tabs.status.success());
@@ -2209,15 +2209,13 @@ fn pane_run_read_and_wait_commands_work() {
let herdr = spawn_herdr(&config_home, &runtime_dir, &socket_path);
wait_for_socket(&socket_path, Duration::from_secs(5));
- let created = send_request(
+ send_request(
&socket_path,
&format!(
r#"{{"id":"req_cli_1","method":"workspace.create","params":{{"cwd":"{}","focus":true}}}}"#,
base.display()
),
);
- assert!(created["result"]["workspace"]["workspace_id"].is_string());
-
let create = run_cli(
&socket_path,
&[
@@ -2461,7 +2459,7 @@ fn closing_workspace_terminates_processes_inside_it() {
}
#[test]
-fn workspace_ids_are_stable_and_pane_numbers_stay_compact() {
+fn workspace_ids_and_public_pane_ids_are_stable() {
let base = unique_test_dir();
let config_home = base.join("config");
let runtime_dir = base.join("runtime");
@@ -2485,7 +2483,7 @@ fn workspace_ids_are_stable_and_pane_numbers_stay_compact() {
);
assert_eq!(
split_12_json["result"]["pane"]["pane_id"],
- format!("{ws1_id}-2")
+ format!("{ws1_id}:p2")
);
let split_13_json = run_cli_json(
@@ -2494,7 +2492,7 @@ fn workspace_ids_are_stable_and_pane_numbers_stay_compact() {
);
assert_eq!(
split_13_json["result"]["pane"]["pane_id"],
- format!("{ws1_id}-3")
+ format!("{ws1_id}:p3")
);
let ws2_json = run_cli_json(
@@ -2520,7 +2518,7 @@ fn workspace_ids_are_stable_and_pane_numbers_stay_compact() {
);
assert_eq!(
ws2_split_json["result"]["pane"]["pane_id"],
- format!("{ws2_id}-2")
+ format!("{ws2_id}:p2")
);
let ws3_json = run_cli_json(
@@ -2565,7 +2563,7 @@ fn workspace_ids_are_stable_and_pane_numbers_stay_compact() {
let ws3_panes_json = run_cli_json(&socket_path, &["pane", "list", "--workspace", &ws3_id]);
assert_eq!(
ws3_panes_json["result"]["panes"][0]["pane_id"],
- format!("{ws3_id}-1")
+ format!("{ws3_id}:p1")
);
let close_middle = run_cli(&socket_path, &["pane", "close", &format!("{ws1_id}-2")]);
@@ -2582,7 +2580,33 @@ fn workspace_ids_are_stable_and_pane_numbers_stay_compact() {
.iter()
.map(|pane| pane["pane_id"].as_str().unwrap().to_string())
.collect();
- assert_eq!(pane_ids, vec![format!("{ws1_id}-1"), format!("{ws1_id}-2")]);
+ assert_eq!(
+ pane_ids,
+ vec![format!("{ws1_id}:p1"), format!("{ws1_id}:p3")]
+ );
+
+ let closed_lookup = run_cli(&socket_path, &["pane", "get", &format!("{ws1_id}:p2")]);
+ assert!(
+ !closed_lookup.status.success(),
+ "closed pane id should not retarget: {}",
+ String::from_utf8_lossy(&closed_lookup.stdout)
+ );
+
+ let split_14_json = run_cli_json(
+ &socket_path,
+ &[
+ "pane",
+ "split",
+ &format!("{ws1_id}:p1"),
+ "--direction",
+ "right",
+ "--no-focus",
+ ],
+ );
+ assert_eq!(
+ split_14_json["result"]["pane"]["pane_id"],
+ format!("{ws1_id}:p4")
+ );
cleanup_spawned_herdr(herdr, base);
}
@@ -2604,7 +2628,10 @@ fn pane_shell_gets_herdr_socket_and_pane_env() {
base.display()
),
);
- assert!(created["result"]["workspace"]["workspace_id"].is_string());
+ let pane_id = created["result"]["root_pane"]["pane_id"]
+ .as_str()
+ .unwrap()
+ .to_string();
let env_capture = base.join("pane-env.txt");
let ran = run_cli(
@@ -2626,7 +2653,7 @@ fn pane_shell_gets_herdr_socket_and_pane_env() {
while Instant::now() < deadline {
if env_capture.exists() {
text = fs::read_to_string(&env_capture).unwrap();
- if text.contains(&socket_path.display().to_string()) && text.contains("p_") {
+ if text.contains(&socket_path.display().to_string()) && text.contains(&pane_id) {
break;
}
}
@@ -2637,7 +2664,7 @@ fn pane_shell_gets_herdr_socket_and_pane_env() {
text.contains(&socket_path.display().to_string()),
"env file was: {text:?}"
);
- assert!(text.contains("p_"), "env file was: {text:?}");
+ assert!(text.contains(&pane_id), "env file was: {text:?}");
cleanup_spawned_herdr(herdr, base);
}
@@ -2734,7 +2761,7 @@ fn wait_agent_status_exits_immediately_when_status_already_matches() {
.as_str()
.unwrap()
.to_string();
- let pane_id = format!("{workspace_id}-1");
+ let pane_id = format!("{workspace_id}:p1");
let reported = send_request(
&socket_path,
diff --git a/tests/live_handoff.rs b/tests/live_handoff.rs
index c56e7c3f..d7ad493d 100644
--- a/tests/live_handoff.rs
+++ b/tests/live_handoff.rs
@@ -895,13 +895,13 @@ pathlib.Path({received:?}).write_text(data.hex())
}
#[test]
-fn live_handoff_accepts_old_pane_id_from_child_env() {
+fn live_handoff_accepts_canonical_pane_id_from_child_env() {
let _lock = test_lock();
let base = unique_test_dir();
let config_home = base.join("config");
let runtime_dir = base.join("runtime");
let api_socket = runtime_dir.join("herdr.sock");
- let pane_id_marker = base.join("old-pane-id");
+ let pane_id_marker = base.join("pane-id");
let spawned = spawn_server(&config_home, &runtime_dir, &api_socket);
wait_for_socket(&api_socket, Duration::from_secs(10));
@@ -927,9 +927,9 @@ fn live_handoff_accepts_old_pane_id_from_child_env() {
"params": {"pane_id": pane_id, "text": format!("printf '%s' \"$HERDR_PANE_ID\" > {}", pane_id_marker.display()), "keys": ["Enter"]}
}),
));
- let old_pane_id = wait_for_file_contains(&pane_id_marker, "p_", Duration::from_secs(5));
+ let old_pane_id = wait_for_file_contains(&pane_id_marker, &pane_id, Duration::from_secs(5));
assert!(
- old_pane_id.starts_with("p_"),
+ old_pane_id == pane_id,
"unexpected pane id from env: {old_pane_id:?}"
);