#![cfg(target_os = "macos")]
use std::sync::mpsc;
use std::time::Duration;
use visual_cortex::{list_targets, FrameSource, ScapSource, Target, TargetInfo};
#[tokio::test]
#[ignore = "requires macOS Screen Recording permission and a live display"]
async fn captures_one_display_frame() {
let mut src = ScapSource::new(&Target::display(0), true).expect("start capturer");
let frame = src.capture_frame().await.expect("capture a frame");
assert!(frame.width() > 0 && frame.height() > 0);
}
fn try_window_frame(id: u32) -> Option<(u32, u32)> {
let (tx, rx) = mpsc::channel();
std::thread::spawn(move || {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("runtime");
if let Ok(mut src) = ScapSource::new(&Target::window_id(id), false) {
if let Ok(frame) = rt.block_on(src.capture_frame()) {
let _ = tx.send((frame.width(), frame.height()));
}
}
});
rx.recv_timeout(Duration::from_secs(3)).ok()
}
#[test]
#[ignore = "requires macOS Screen Recording permission and at least one visible window"]
fn captures_one_window_frame() {
let mut candidates: Vec<(u32, String)> = list_targets()
.into_iter()
.filter_map(|t| match t {
TargetInfo::Window { id, title } if !title.is_empty() => Some((id, title)),
_ => None,
})
.collect();
assert!(!candidates.is_empty(), "no windows enumerable");
candidates.sort_by_key(|(_, t)| !(t.contains("Chrome") || t.contains("YouTube")));
for (id, title) in candidates.into_iter().take(10) {
if let Some((w, h)) = try_window_frame(id) {
println!("captured {w}x{h} from window {id} {title:?}");
assert!(w > 0 && h > 0);
return;
}
}
panic!("no candidate window delivered a frame within its timeout");
}