use crate::{Desktop, SerializableUIElement, UIElement};
use std::time::Duration;
use tracing::info;
use tracing_subscriber::FmtSubscriber;
#[tokio::test]
#[ignore] async fn test_browser_tree_serialization() -> Result<(), Box<dyn std::error::Error>> {
let subscriber = FmtSubscriber::builder()
.with_max_level(tracing::Level::INFO)
.finish();
let _ = tracing::subscriber::set_global_default(subscriber);
info!("Starting browser serialization test...");
let desktop = Desktop::new(false, false)?;
let url = "https://pages.dataiku.com/guide-to-ai-agents";
info!("Opening URL: {}", url);
let window = desktop.open_url(url, None)?;
let window_name = window.name_or_empty();
tokio::time::sleep(Duration::from_secs(2)).await;
let window = desktop
.locator(format!("name:{window_name}").as_str())
.first(Some(Duration::from_secs(5)))
.await?;
let max_depth = 3;
info!("Capturing UI tree to a max depth of {}...", max_depth);
let tree: SerializableUIElement = window.to_serializable_tree(max_depth);
let json_output = serde_json::to_string_pretty(&tree)?;
info!("Successfully serialized UI tree to JSON.");
println!("--- Serialized UI Tree (JSON) ---\n{json_output}\n---------------------------------");
info!("Validating JSON output...");
assert!(!json_output.is_empty(), "JSON output should not be empty");
let root_value: serde_json::Value = serde_json::from_str(&json_output)?;
assert!(
root_value.get("role").is_some(),
"Root element must have a 'role'"
);
assert!(
root_value.get("name").is_some(),
"Root element must have a 'name'"
);
let window_title = root_value["window_title"].as_str().unwrap_or_default();
assert!(
window_title.contains("GLO CONTENT"),
"Window title is incorrect: {window_title}"
);
assert!(
!json_output.contains(r#""name": """#),
"JSON should not contain empty name fields: {json_output}"
);
assert!(
!json_output.contains(r#""value": """#),
"JSON should not contain empty value fields: {json_output}"
);
assert!(
!json_output.contains(r#""description": """#),
"JSON should not contain empty description fields: {json_output}"
);
info!("Validation successful!");
window.close()?;
info!("Test completed successfully.");
Ok(())
}
#[test]
#[allow(clippy::assertions_on_constants)]
fn test_uielement_serialization() {
assert!(true, "UIElement implements Serialize trait");
}
#[test]
fn test_uielement_deserialization() {
let json = r#"
{
"id": "test-123",
"role": "Button",
"name": "Test Button",
"bounds": [10.0, 20.0, 100.0, 30.0],
"value": "Click me",
"description": "A test button",
"application": "Test App",
"window_title": "Test Window"
}"#;
let result: Result<UIElement, _> = serde_json::from_str(json);
assert!(
result.is_err(),
"Deserialization should fail for non-existent elements or when Desktop is unavailable"
);
let error_msg = result.unwrap_err().to_string();
assert!(
error_msg.contains("Button") || error_msg.contains("Test Button"),
"Error should mention the element role or name"
);
}
#[test]
fn test_uielement_round_trip() {
let json = r#"
{
"id": "round-trip-test",
"role": "TextField",
"name": "Input Field",
"bounds": [50.0, 60.0, 200.0, 25.0],
"value": "Hello World",
"description": "Text input",
"application": "My App",
"window_title": "Main Window"
}"#;
let result: Result<UIElement, _> = serde_json::from_str(json);
assert!(
result.is_err(),
"Deserialization should fail for non-existent elements or when Desktop is unavailable"
);
let error_msg = result.unwrap_err().to_string();
assert!(
error_msg.contains("TextField") || error_msg.contains("Input Field"),
"Error should mention the element role or name"
);
}