use captchaforge::detect::{CaptchaInfo, DetectedCaptcha, DetectorRegistry};
use captchaforge::solver::{CaptchaSolveResult, SolveConfig, SolveMethod};
mod common;
#[test]
fn failure_result_with_max_u64_time() {
let result = CaptchaSolveResult::failure(SolveMethod::BehavioralBypass, u64::MAX);
assert!(!result.success);
assert_eq!(result.time_ms, u64::MAX);
}
#[test]
fn unsolved_result_with_max_u64_time() {
let result = CaptchaSolveResult::unsolved(u64::MAX, None);
assert!(!result.success);
assert_eq!(result.time_ms, u64::MAX);
}
#[test]
fn solve_config_zero_values() {
let cfg = SolveConfig {
checkbox_poll_interval_ms: 0,
checkbox_max_attempts: 0,
token_poll_interval_ms: 0,
token_max_attempts: 0,
audio_button_delay_ms: 0,
audio_submit_delay_ms: 0,
vlm_http_timeout_ms: 0,
client_http_timeout_ms: 0,
};
assert_eq!(cfg.checkbox_poll_interval_ms, 0);
}
#[test]
fn solve_result_empty_solution() {
let result = CaptchaSolveResult {
solution: String::new(),
confidence: 0.0,
method: SolveMethod::BehavioralBypass,
time_ms: 0,
success: true,
screenshot: None,
cookies: Vec::new(),
verified_outcome: None,
};
assert!(result.success);
assert!(result.solution.is_empty());
}
#[test]
fn solve_result_very_long_solution() {
let long = "x".repeat(1_000_000);
let result = CaptchaSolveResult {
solution: long.clone(),
confidence: 1.0,
method: SolveMethod::BehavioralBypass,
time_ms: 1,
success: true,
screenshot: None,
cookies: Vec::new(),
verified_outcome: None,
};
assert_eq!(result.solution.len(), 1_000_000);
}
#[test]
fn serde_rejects_unknown_captcha_kind() {
let bad = r#"{"kind": "unknown_type", "site_key": null}"#;
let result: Result<captchaforge::detect::CaptchaInfo, _> = serde_json::from_str(bad);
assert!(result.is_err());
}
#[test]
fn serde_nan_confidence() {
let result = CaptchaSolveResult {
solution: "test".to_string(),
confidence: f32::NAN,
method: SolveMethod::BehavioralBypass,
time_ms: 100,
success: false,
screenshot: None,
cookies: Vec::new(),
verified_outcome: None,
};
let json = serde_json::to_string(&result);
assert!(json.is_ok());
}
#[test]
fn serde_infinite_confidence() {
let result = CaptchaSolveResult {
solution: "test".to_string(),
confidence: f32::INFINITY,
method: SolveMethod::BehavioralBypass,
time_ms: 100,
success: false,
screenshot: None,
cookies: Vec::new(),
verified_outcome: None,
};
let json = serde_json::to_string(&result);
assert!(json.is_ok());
}
#[tokio::test]
async fn detector_registry_detect_returns_none_for_clean_page() {
let mut browser = common::launch_browser().await;
let page = browser.new_page("about:blank").await.unwrap();
let registry = DetectorRegistry::new();
let result = registry.detect(&page).await.unwrap();
assert!(result.is_none());
browser.close().await.unwrap();
}
#[test]
fn detected_captcha_serde_with_1kb_container_selector() {
let long_selector = "a".repeat(1024);
let info = CaptchaInfo {
kind: DetectedCaptcha::CanvasCaptcha,
site_key: None,
page_url: "https://example.com".to_string(),
container_selector: Some(long_selector.clone()),
};
let json = serde_json::to_string(&info).unwrap();
let back: CaptchaInfo = serde_json::from_str(&json).unwrap();
assert_eq!(back.container_selector, Some(long_selector));
}