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
# Testing Guide

## Test Pyramid

captchaforge uses a 5-tier test pyramid:

```
       /│\     Chaos (failure injection)     ~5 tests
      / │ \    ─────────────────────────────────────────
     /  │  \   Integration (real Chrome)      ~8 tests
    /   │   \  ─────────────────────────────────────────
   /    │    \ Property (proptest)            ~40 tests
  /     │     \─────────────────────────────────────────
 /      │      Snapshot (insta)               ~10 tests
/       │       ────────────────────────────────────────
────────┴────── Unit (inline)                 ~40 tests
```

## Running Tests

### Fast tier (~10 seconds)
Unit tests, property tests, snapshot tests, chaos tests — no browser needed.

```bash
cargo test --lib
cargo test --test property_detect
cargo test --test property_solver
cargo test --test property_frame
cargo test --test property_behavior
cargo test --test snapshot_structures
cargo test --test chaos_resilience
```

### Integration tier (~2 minutes)
Real browser tests. Requires Chrome/Chromium installed.

```bash
# Run all integration tests
cargo test --test integration -- --ignored --test-threads=1

# Run a specific integration test
cargo test --test integration detect_turnstile_on_mock_page -- --ignored --test-threads=1
```

### Full suite (~5 minutes)
```bash
cargo test --workspace
```

### With coverage
```bash
cargo install cargo-llvm-cov
cargo llvm-cov --workspace --html --open
```

## Writing Property Tests

Add to `tests/property_*.rs`:

```rust
use captchaforge::detect::{is_captcha, CaptchaInfo, DetectedCaptcha};
use proptest::prelude::*;

proptest! {
    #[test]
    fn my_property(kind in any_detected_captcha()) {
        let info = CaptchaInfo { kind, ..Default::default() };
        // invariant to verify
        prop_assert!(/* ... */);
    }
}
```

Run with:
```bash
cargo test --test property_detect my_property -- --nocapture
```

## Writing Snapshot Tests

Add to `tests/snapshot_structures.rs`:

```rust
#[test]
fn snap_my_structure() {
    let data = MyStruct { /* ... */ };
    insta::assert_json_snapshot!(data);
}
```

After first run, review the `.snap` file in `tests/snapshots/` and commit it.

## Writing Chaos Tests

Add to `tests/chaos_resilience.rs`:

```rust
#[test]
fn my_chaos_test() {
    // Test extreme inputs, edge cases, failure modes
    // No browser needed — focus on panic prevention
}
```

## Fuzz Testing

```bash
cd fuzz
cargo fuzz run fuzz_detect -- -max_total_time=300
```

## CI Behavior

- PRs trigger: `ci.yml` (unit + property + lint + docs)
- Merges to `main` trigger: `ci.yml` + `bench.yml` + `coverage.yml`
- Weekly: `fuzz.yml` (30-min fuzz run)