cueward-adapter-macos 0.5.0

macOS adapter for Cueward with Safari, Notes, Messages, Reminders, Calendar, Screenshot, Clipboard, and OCR integrations.
use std::io::Write;
use std::process::Command;
use std::time::Duration;

#[test]
fn executable_binding_checks_offscreen_fallbacks_ambiguity_and_menu_context() {
    let mut script = tempfile::NamedTempFile::with_suffix(".swift").expect("Swift fixture");
    write!(
        script,
        "{}\n{}\n{}\n{}\n{}\ntestWindowBinding()\n",
        include_str!("ax_elements.swift"),
        include_str!("ax_shared.swift"),
        include_str!("ax_common.swift"),
        include_str!("ax_catalog_tests.swift"),
        include_str!("ax_binding_tests.swift")
    )
    .expect("write fixture");
    for (scenario, error) in [
        ("fallback", None),
        ("deduplicate", None),
        ("menu", None),
        ("missing", Some("0 AX windows")),
        ("ambiguous-ax", Some("2 AX windows")),
        ("ambiguous-catalog", Some("ambiguous in the system catalog")),
        ("other-main", Some("not the verified main window")),
        ("other-focused", Some("not the verified focused window")),
    ] {
        let output = super::process::run_with_timeout(
            Command::new("swift")
                .arg(script.path())
                .args(["123", "7", "Fixture", "-100", "200", "640", "480", scenario]),
            b"",
            Duration::from_secs(40),
        )
        .expect("run binding fixture");
        let stderr = String::from_utf8_lossy(&output.stderr);
        match error {
            Some(message) => {
                assert!(!output.status.success(), "{scenario} should be rejected");
                assert!(stderr.contains(message), "{scenario}: {stderr}");
            }
            None => {
                assert!(output.status.success(), "{scenario}: {stderr}");
                assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "passed");
            }
        }
    }
}

#[test]
fn catalog_binding_matches_snapshot_precision_and_rejects_changed_frames() {
    let mut script = tempfile::NamedTempFile::with_suffix(".swift").expect("Swift fixture");
    write!(
        script,
        "{}\n{}\n{}\n{}\ntestCatalogBounds()\n",
        include_str!("ax_elements.swift"),
        include_str!("ax_shared.swift"),
        include_str!("ax_common.swift"),
        include_str!("ax_catalog_tests.swift")
    )
    .expect("write fixture");
    let output = super::process::run_with_timeout(
        Command::new("swift")
            .arg(script.path())
            .args(["123", "7", "Fixture", "-100", "200", "640", "480"]),
        b"",
        Duration::from_secs(40),
    )
    .expect("run Swift fixture");
    assert!(
        output.status.success(),
        "catalog binding failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "passed");
}

#[test]
fn child_enumeration_distinguishes_leaves_from_failed_reads() {
    let mut script = tempfile::NamedTempFile::with_suffix(".swift").expect("Swift fixture");
    write!(
        script,
        "{}\n{}",
        include_str!("ax_elements.swift"),
        include_str!("ax_elements_tests.swift")
    )
    .expect("write fixture");
    let output = super::process::run_with_timeout(
        Command::new("swift").arg(script.path()),
        b"",
        Duration::from_secs(40),
    )
    .expect("run Swift fixture");
    assert!(
        output.status.success(),
        "AX element decoding failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "passed");
}