use browsing::browser::{Browser, BrowserProfile};
use browsing::dom::service::DomService;
use browsing::error::{BrowsingError, Result};
use browsing::tools::service::Tools;
use serde_json::json;
use std::error::Error;
#[test]
fn test_error_variants() {
let errors = [
BrowsingError::Config("Invalid configuration".to_string()),
BrowsingError::Io(std::io::Error::new(
std::io::ErrorKind::NotFound,
"File not found",
)),
BrowsingError::Browser("Browser startup failed".to_string()),
BrowsingError::Cdp("CDP connection lost".to_string()),
BrowsingError::Llm("LLM API error".to_string()),
BrowsingError::Agent("Agent execution failed".to_string()),
BrowsingError::Dom("DOM extraction failed".to_string()),
BrowsingError::Tool("Tool execution failed".to_string()),
BrowsingError::Validation("Invalid input".to_string()),
];
for error in errors {
let _ = error.to_string();
}
}
#[test]
fn test_error_display_formatting() {
let error = BrowsingError::Config("Browser profile not found".to_string());
let display_str = format!("{}", error);
assert!(display_str.contains("Configuration error"));
assert!(display_str.contains("Browser profile not found"));
let error = BrowsingError::Tool("Invalid action".to_string());
let display_str = format!("{}", error);
assert!(display_str.contains("Tool error"));
assert!(display_str.contains("Invalid action"));
}
#[test]
fn test_error_chain() {
let io_error = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "Cannot read file");
let browser_error = BrowsingError::Io(io_error);
assert!(browser_error.source().is_some());
let source = browser_error.source().unwrap();
assert!(format!("{}", source).contains("Cannot read file"));
}
#[test]
fn test_result_type_alias() {
fn returns_result() -> Result<String> {
Ok("success".to_string())
}
fn returns_error() -> Result<String> {
Err(BrowsingError::Validation("Invalid input".to_string()))
}
assert!(returns_result().is_ok());
assert!(returns_result().unwrap() == "success");
assert!(returns_error().is_err());
}
#[tokio::test]
async fn test_browser_error_scenarios() {
let mut browser = Browser::new(BrowserProfile::default());
let result = browser.navigate("https://example.com").await;
assert!(result.is_err());
let result = browser.get_page();
assert!(result.is_err());
let result = browser.get_cdp_client();
assert!(result.is_err());
}
#[tokio::test]
async fn test_tools_error_scenarios() {
let _tools = Tools::new(vec![]);
let invalid_action = json!({
"action_type": "invalid_action_type",
"params": {}
});
let action_model: std::result::Result<browsing::tools::views::ActionModel, serde_json::Error> =
serde_json::from_value(invalid_action);
if let Ok(action) = action_model {
assert_eq!(action.action_type, "invalid_action_type");
}
}
#[test]
fn test_dom_service_error_scenarios() {
let _dom_service = DomService::new();
}
#[test]
fn test_error_recovery_patterns() {
let mut attempt_count = 0;
let result: Result<String> = loop {
attempt_count += 1;
if attempt_count == 1 {
continue; }
break Ok("success".to_string());
};
assert!(result.is_ok());
assert_eq!(result.unwrap(), "success");
assert_eq!(attempt_count, 2);
}
#[test]
fn test_error_with_context() {
let base_error = BrowsingError::Cdp("Connection failed".to_string());
let contextual_error = match base_error {
BrowsingError::Cdp(msg) => BrowsingError::Cdp(format!("CDP error during startup: {}", msg)),
other => other,
};
assert!(format!("{}", contextual_error).contains("CDP error during startup"));
}
#[test]
fn test_multiple_error_combinations() {
fn complex_operation(might_fail: bool) -> Result<String> {
if might_fail {
return Err(BrowsingError::Validation(
"Input validation failed".to_string(),
));
}
if false {
return Err(BrowsingError::Tool("Tool execution failed".to_string()));
}
Ok("Operation completed".to_string())
}
let result1 = complex_operation(true);
assert!(result1.is_err());
assert!(matches!(result1.unwrap_err(), BrowsingError::Validation(_)));
}
#[test]
fn test_error_aggregation() {
let mut errors = Vec::new();
for i in 0..3 {
match i {
0 => errors.push(BrowsingError::Config("Config error".to_string())),
1 => errors.push(BrowsingError::Browser("Browser error".to_string())),
2 => errors.push(BrowsingError::Llm("LLM error".to_string())),
_ => unreachable!(),
}
}
let combined_error = format!(
"Multiple errors occurred: {}",
errors
.iter()
.map(|e| e.to_string())
.collect::<Vec<_>>()
.join(", ")
);
assert!(combined_error.contains("Config error"));
assert!(combined_error.contains("Browser error"));
assert!(combined_error.contains("LLM error"));
}
#[test]
fn test_async_error_propagation() {
use tokio::runtime::Runtime;
let rt = Runtime::new().unwrap();
let result: Result<String> = rt.block_on(async {
if true {
return Err(BrowsingError::Agent("Async operation failed".to_string()));
}
Ok("Async success".to_string())
});
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), BrowsingError::Agent(_)));
}