captchaforge 0.2.36

[DO NOT USE — UNDER ACTIVE DEVELOPMENT, NOT PRODUCTION-READY] Captcha solver scaffolding for chromiumoxide-driven browsers. The architecture is in place (vendor solvers, retry-loop iframe walking, VLM provider abstraction, real-WAF bench harness) but the live-vendor success rate is still 0% — Cloudflare Turnstile / hCaptcha / reCAPTCHA detect us at a TLS / CDP fingerprint layer that no flag-based stealth has cleared. Watch the repo; do not depend on this for any real workload.
Documentation
#!/usr/bin/env python3
"""Smoke tests for pcap2fixture. Validates that HAR + curl-trace
parsers produce the expected outputs against synthetic input."""

import json
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path

ROOT = Path(__file__).resolve().parent
ROOT_REPO = ROOT.parent.parent
CONVERT = ROOT / "convert.py"


def synthetic_har(url: str, body: str) -> dict:
    return {
        "log": {
            "version": "1.2",
            "creator": {"name": "pcap2fixture-test", "version": "0"},
            "entries": [
                {
                    "request": {"method": "GET", "url": url, "headers": []},
                    "response": {
                        "status": 200,
                        "statusText": "OK",
                        "headers": [{"name": "content-type", "value": "text/html"}],
                        "content": {"size": len(body), "mimeType": "text/html", "text": body},
                    },
                }
            ],
        }
    }


def test_har_turnstile():
    body = '<div class="cf-turnstile" data-sitekey="x"></div>'
    har = synthetic_har("https://challenges.cloudflare.com/turnstile/v0/api.js", body)
    with tempfile.TemporaryDirectory() as td:
        td = Path(td)
        incoming = td / "incoming"
        incoming.mkdir()
        (incoming / "turnstile.har").write_text(json.dumps(har))
        # Run convert with INCOMING redirected via env-trick: copy
        # script into td so it picks up the td's incoming/.
        script = td / "convert.py"
        shutil.copy(CONVERT, script)
        # Adjust ROOT in the script to the td via runtime import
        # would be brittle — instead just chdir + run with ROOT_REPO
        # pointing at td.
        out_root = td / "adversarial-corpus"
        out_root.mkdir()
        # Patch the script's ROOT_REPO via env var would be a feature;
        # for now, monkey-patch by writing the script under a known
        # path. Skip integration: just import the module functions.
        sys.path.insert(0, str(ROOT))
        import convert as mod  # noqa: E402
        # Run parse_har directly.
        captured = mod.parse_har(incoming / "turnstile.har")
        assert captured is not None, "parse_har returned None"
        assert "cf-turnstile" in captured["body"]
        assert captured["status"] == 200
        assert mod.infer_vendor(captured) == "cloudflare-turnstile"
        dest = mod.to_adversarial(captured, "cloudflare-turnstile", out_root)
        assert dest.is_file()
        payload = json.loads(dest.read_text())
        assert payload["vendor"] == "cloudflare-turnstile"
        assert payload["expected"] == "recognised"
        assert payload["body"] == body
        # ID is 16 hex chars (sha256[:16]).
        assert len(payload["id"]) == 16
    print("PASS: HAR turnstile import")


def test_har_recaptcha_v2():
    body = '<div class="g-recaptcha" data-sitekey="X"></div>'
    har = synthetic_har("https://www.google.com/recaptcha/api.js", body)
    with tempfile.TemporaryDirectory() as td:
        td = Path(td)
        incoming = td / "incoming"
        incoming.mkdir()
        (incoming / "rc.har").write_text(json.dumps(har))
        sys.path.insert(0, str(ROOT))
        import convert as mod
        captured = mod.parse_har(incoming / "rc.har")
        assert captured is not None
        assert mod.infer_vendor(captured) == "recaptcha-v2"
    print("PASS: HAR reCAPTCHA v2 import")


def test_har_skips_non_captcha_urls():
    har = synthetic_har("https://example.com/", "<p>hello</p>")
    with tempfile.TemporaryDirectory() as td:
        td = Path(td)
        path = td / "x.har"
        path.write_text(json.dumps(har))
        sys.path.insert(0, str(ROOT))
        import convert as mod
        assert mod.parse_har(path) is None
    print("PASS: HAR non-captcha skipped")


if __name__ == "__main__":
    test_har_turnstile()
    test_har_recaptcha_v2()
    test_har_skips_non_captcha_urls()
    print("ALL PASS")