captchaforge 0.2.21

Automatic CAPTCHA detection and multi-strategy solving for chromiumoxide-driven headless browsers (Cloudflare Turnstile, reCAPTCHA v2/v3, hCaptcha, image grids, audio, sliders).
Documentation
//! Property-based tests for the frame piercing module.

use proptest::prelude::*;
use proptest::test_runner::TestRunner;

#[test]
fn selector_escaping_balanced_quotes() {
    let mut runner = TestRunner::default();
    runner
        .run(
            &"[a-zA-Z0-9_#.:>+~ \\[\\]\\(\\)=\\'@-]{1,128}",
            |selector| {
                let escaped = selector.replace('"', "\\\"");
                let js = format!(r#"document.querySelector("{}")"#, escaped);
                let quote_count = js.matches('"').count();
                prop_assert_eq!(quote_count % 2, 0, "unbalanced quotes in: {}", js);
                Ok(())
            },
        )
        .unwrap();
}

#[test]
fn token_name_escaping_handles_special_chars() {
    let mut runner = TestRunner::default();
    runner
        .run(&"[a-zA-Z0-9_-]{1,64}", |token_name| {
            let escaped = token_name.replace('"', "\\\"").replace('\'', "\\'");
            prop_assert!(!escaped.contains('"') || escaped.contains("\\\""));
            Ok(())
        })
        .unwrap();
}

#[test]
fn empty_selector_produces_valid_js() {
    let selector = "";
    let escaped = selector.replace('"', "\\\"");
    let js = format!(r#"document.querySelector("{}")"#, escaped);
    assert!(js.contains("\"\""));
}