End-to-end antibot-detection tests that verify a pip-installed camoufox release works correctly — both the Firefox binary and the Python package — using real proxies for each browser context.
- Python 3.9+
- Node.js (for building the TypeScript checks bundle via
esbuild) - At least one proxy in
proxies.txt
# 1. Add your proxies (see format below)
# 2. Run the test script — it handles everything else automatically
./run_tests.shrun_tests.sh will:
- Install npm deps in
../build-tester/(foresbuild, first run only) - Create a
.venvvirtualenv (first run only) - Install
camoufoxfrom the local../pythonlibsource - Download the camoufox browser binary
- Run the full test suite
Tests require real proxies. Each context gets its own proxy, and the WebRTC IP is automatically derived from the proxy server address.
Create proxies.txt in this directory with one proxy per line:
user:pass@domain:port
Example:
alice:[email protected]:10000
bob:[email protected]:10000
alice:[email protected]:10001
- Blank lines and lines starting with
#are ignored - Proxies are assigned round-robin across the 6 test profiles
- Fewer proxies than profiles is fine — they cycle
If you prefer to run steps individually:
# Install build-tester deps (once)
cd ../build-tester && npm install && cd ../service_tests
# Create and activate virtualenv
python3 -m venv .venv
source .venv/bin/activate
# Install camoufox from local source
pip install -e ../pythonlib
# Download the browser binary
python -m camoufox fetch
# Run tests
python run_tests.py./run_tests.sh [options]
python run_tests.py [options]
--browser-version VER Camoufox version specifier (default: official/stable)
e.g. official/prerelease/146.0.1-beta.50
--profile-count N Number of profiles to test (1-6, default: 6)
--proxies PATH Path to proxies file (default: proxies.txt)
--headful Run with visible browser window
--no-cert Skip certificate generation
--save-cert PATH Save certificate text to a file
--secret KEY HMAC signing key for the certificate
6 browser contexts run simultaneously — 3 macOS profiles and 3 Linux profiles — each with:
- A unique fingerprint generated by camoufox via BrowserForge (navigator, screen, WebGL, fonts, voices, audio/canvas seeds)
- A distinct timezone
- Its own proxy, with WebRTC ICE candidates spoofed to the proxy's IP
Each context is scored across these categories:
| Category | What it checks |
|---|---|
| Automation Detection | Playwright/CDP artefacts |
| JS Engine | V8 vs SpiderMonkey signals |
| Lie Detection | Inconsistent property overrides |
| Firefox APIs | Firefox-specific API presence |
| Cross-Signal | Consistency across navigator, screen, etc. |
| CSS Fingerprint | CSS rendering fingerprint |
| Canvas Noise | Canvas hash uniqueness and stability |
| WebGL Render | WebGL rendering hash |
| Audio Integrity | AudioContext fingerprint |
| Font Platform | OS-consistent font availability |
| Speech Voices | Voice list matches declared OS |
| WebRTC | IP matches proxy server address |
| Stability | Fingerprint stable over time with other contexts open |
| Headless Detection | No headless mode signals |
| Grade | Meaning |
|---|---|
| A | All checks pass |
| B | 1–2 failures (minor) |
| C | 3–5 failures |
| D | 6–10 failures |
| F | 11+ failures |
A grade of A or B exits with code 0. Anything worse exits with code 1.
The cross-profile uniqueness section confirms each context has distinct audio, canvas, timezone, and screen fingerprints — verifying camoufox generates genuinely different identities per context.
If a check fails, fix it in the Python package (../pythonlib/camoufox/), not in the test. The test is intentionally a black-box validator — it only uses the public AsyncNewContext API and trusts camoufox to produce correct fingerprints.