waterui_cli/workflows/
capture.rs1use std::path::{Path, PathBuf};
6
7use eyre::eyre;
8use jiff::Timestamp;
9
10use crate::device::Device;
11use crate::toolchain::Host;
12use crate::{android, apple};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum DevicePlatform {
17 Ios,
19 Android,
21}
22
23#[must_use]
28pub fn detect_platform(device_id: &str) -> DevicePlatform {
29 let parts: Vec<&str> = device_id.split('-').collect();
30 if parts.len() == 5
31 && parts[0].len() == 8
32 && parts[1].len() == 4
33 && parts[2].len() == 4
34 && parts[3].len() == 4
35 && parts[4].len() == 12
36 && device_id.chars().all(|c| c.is_ascii_hexdigit() || c == '-')
37 {
38 return DevicePlatform::Ios;
39 }
40
41 DevicePlatform::Android
42}
43
44#[must_use]
48pub fn generate_screenshot_filename() -> PathBuf {
49 let filename = format!(
50 "screenshot_{}.png",
51 Timestamp::now().strftime("%Y-%m-%d_%H%M%S")
52 );
53 PathBuf::from(filename)
54}
55
56pub async fn screenshot(host: &Host, device_id: &str, output: &Path) -> eyre::Result<()> {
61 match detect_platform(device_id) {
62 DevicePlatform::Ios => apple::device::screenshot(host, device_id, output).await,
63 DevicePlatform::Android => android::device::screenshot(host, device_id, output).await,
64 }
65}
66
67pub async fn verify_device(host: &Host, device_id: &str) -> eyre::Result<DevicePlatform> {
72 let platform = detect_platform(device_id);
73
74 match platform {
75 DevicePlatform::Ios => {
76 let simulators = apple::device::AppleSimulator::scan(host).await?;
77 if simulators.iter().any(|s| s.udid == device_id) {
78 Ok(DevicePlatform::Ios)
79 } else {
80 Err(eyre!("iOS simulator with UDID '{}' not found", device_id))
81 }
82 }
83 DevicePlatform::Android => {
84 let devices = android::device::AndroidDevice::scan(host).await?;
85 if devices.iter().any(|d| d.identifier() == device_id) {
86 Ok(DevicePlatform::Android)
87 } else {
88 Err(eyre!("Android device '{}' not found", device_id))
89 }
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn detects_ios_udid() {
100 assert_eq!(
101 detect_platform("12345678-1234-1234-1234-123456789ABC"),
102 DevicePlatform::Ios
103 );
104 assert_eq!(
105 detect_platform("ABCDEF12-3456-7890-ABCD-EF1234567890"),
106 DevicePlatform::Ios
107 );
108 }
109
110 #[test]
111 fn detects_android_device() {
112 assert_eq!(detect_platform("emulator-5554"), DevicePlatform::Android);
113 assert_eq!(detect_platform("ABCD1234"), DevicePlatform::Android);
114 assert_eq!(
115 detect_platform("192.168.1.100:5555"),
116 DevicePlatform::Android
117 );
118 }
119
120 #[test]
121 fn generates_valid_filename() {
122 let filename = generate_screenshot_filename();
123 let name = filename.to_string_lossy();
124 assert!(name.starts_with("screenshot_"));
125 assert!(name.ends_with(".png"));
126 }
127}