grouped runtime reads and waits

selector modes
This commit is contained in:
Harivansh Rathi 2026-03-25 20:57:13 -04:00
parent cc8f8e548a
commit f87ac61790
11 changed files with 1285 additions and 67 deletions

View file

@ -218,3 +218,7 @@ pub fn successful_json_response(output: Output) -> Result<serde_json::Value> {
serde_json::from_slice(&output.stdout).context("Failed to parse JSON output from deskctl")
}
pub fn json_response(output: &Output) -> Result<serde_json::Value> {
serde_json::from_slice(&output.stdout).context("Failed to parse JSON output from deskctl")
}

View file

@ -8,7 +8,7 @@ use deskctl::core::doctor;
use deskctl::core::protocol::Request;
use self::support::{
deskctl_tmp_screenshot_count, env_lock, successful_json_response, FixtureWindow,
deskctl_tmp_screenshot_count, env_lock, json_response, successful_json_response, FixtureWindow,
SessionEnvGuard, TestSession,
};
@ -113,3 +113,123 @@ fn daemon_start_recovers_from_stale_socket() -> Result<()> {
Ok(())
}
#[test]
fn wait_window_returns_matched_window_payload() -> Result<()> {
let _guard = env_lock().lock().unwrap();
let Some(_env) = SessionEnvGuard::prepare() else {
eprintln!("Skipping X11 integration test because DISPLAY is not set");
return Ok(());
};
let title = "deskctl wait window test";
let _window = FixtureWindow::create(title, "DeskctlWait")?;
let session = TestSession::new("wait-window-success")?;
let response = successful_json_response(session.run_cli([
"--json",
"wait",
"window",
"--selector",
&format!("title={title}"),
"--timeout",
"1",
"--poll-ms",
"50",
])?)?;
let window = response
.get("data")
.and_then(|data| data.get("window"))
.expect("wait window should return a matched window");
assert_eq!(
window.get("title").and_then(|value| value.as_str()),
Some(title)
);
assert_eq!(
response
.get("data")
.and_then(|data| data.get("wait"))
.and_then(|value| value.as_str()),
Some("window")
);
Ok(())
}
#[test]
fn ambiguous_fuzzy_selector_returns_candidates() -> Result<()> {
let _guard = env_lock().lock().unwrap();
let Some(_env) = SessionEnvGuard::prepare() else {
eprintln!("Skipping X11 integration test because DISPLAY is not set");
return Ok(());
};
let _window_one = FixtureWindow::create("deskctl ambiguity alpha", "DeskctlAmbiguous")?;
let _window_two = FixtureWindow::create("deskctl ambiguity beta", "DeskctlAmbiguous")?;
let session = TestSession::new("selector-ambiguity")?;
let output = session.run_cli(["--json", "focus", "ambiguity"])?;
let response = json_response(&output)?;
assert!(!output.status.success());
assert_eq!(
response.get("success").and_then(|value| value.as_bool()),
Some(false)
);
assert_eq!(
response
.get("data")
.and_then(|data| data.get("kind"))
.and_then(|value| value.as_str()),
Some("selector_ambiguous")
);
assert!(response
.get("data")
.and_then(|data| data.get("candidates"))
.and_then(|value| value.as_array())
.map(|candidates| candidates.len() >= 2)
.unwrap_or(false));
Ok(())
}
#[test]
fn wait_focus_timeout_is_structured() -> Result<()> {
let _guard = env_lock().lock().unwrap();
let Some(_env) = SessionEnvGuard::prepare() else {
eprintln!("Skipping X11 integration test because DISPLAY is not set");
return Ok(());
};
let session = TestSession::new("wait-focus-timeout")?;
let output = session.run_cli([
"--json",
"wait",
"focus",
"--selector",
"title=missing-window-for-wait-focus",
"--timeout",
"1",
"--poll-ms",
"50",
])?;
let response = json_response(&output)?;
assert!(!output.status.success());
assert_eq!(
response
.get("data")
.and_then(|data| data.get("kind"))
.and_then(|value| value.as_str()),
Some("timeout")
);
assert_eq!(
response
.get("data")
.and_then(|data| data.get("last_observation"))
.and_then(|value| value.get("kind"))
.and_then(|value| value.as_str()),
Some("selector_not_found")
);
Ok(())
}