Files
camoufox/tests
Jake WriterandClaude Opus 5.5 fb21b2e35a fix: stock animations and speech by default; drop config keys that freeze live values
Three behaviours a page could detect, changed in one breaking release:

- **Animations run on stock timing.** no-css-animations.patch finished every
  finite animation at once by default, and any page could read it:
  `el.animate(frames, 1000).effect.getComputedTiming().duration` was 0, and a
  500ms transition reported 0. Measured on v152.0.4-beta.31. The speedup is
  now an opt-in, `instantAnimations: True`, which raises a LeakWarning.
  disableInstantAnimations is gone.
- **speak() on a spoofed voice works like a real voice.** It fired `error`
  after 3ms unless voices:fakeCompletion was set, and then start and end in
  the same tick. It now starts and ends after the text's duration at ~150
  words per minute. Both voices:fakeCompletion keys are gone, and so is a
  debug line printed to stderr on every call.
- **Keys removed:**
  - battery:* and window.scrollMinX/Y: Firefox keeps getBattery() and
    scrollMin* chrome-only, so no page could read them.
  - window.scrollMaxX/Y, screen.pageXOffset/pageYOffset,
    window.history.length and document.body.client*: each pinned a live value
    to a constant, so scrolling, navigating or re-laying out never changed it.
    fpgen.yml mapped pageYOffset, so about 15% of identities froze
    window.scrollY at a non-zero value.
  - The body keys' role as an undocumented alias for window.innerWidth/Height
    in browser-init and in the launcher.
  - MaskConfig::GetInt32Rect, which only the body keys used.

New guards, both of which fail on v152.0.4-beta.31:
tests/patches/animation-timing.py and tests/patches/spoofed-voice-speaks.py.
The decisions are recorded as animations-run-on-stock-timing and
spoofed-voices-speak. Every patch applies cleanly to a fresh tree, and the
result builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:33:21 -06:00
..

Tests

Two things live here, and neither is a copy of anyone else's suite.

patches/ — patch guards

One standalone script per shipped spoofing behaviour: isolated evaluate, trusted events, font spoofing, mouse trajectories, the touchscreen digitizer, and so on. Each exits 0 or 1 and drives the browser through the Python package.

These are the most direct evidence that a Firefox bump did not quietly neuter a patch that still applies cleanly — the failure a compile check cannot catch.

python3 -m ci.run_patch_guards --binary /path/to/camoufox-bin
python3 -m ci.run_patch_guards --binary /path/to/camoufox-bin --only isolated-evaluate

camoufox/ — Camoufox's own Playwright tests

Tests for behaviour upstream Playwright has no equivalent for, or asserts the opposite of on purpose. ci/suite.py overlays them onto the upstream checkout so they run against its harness. See camoufox/README.md for when to add one.


Where the Playwright suite went

This directory used to hold a fork of a ~v1.55-era playwright-python suite. It was deleted, because measuring it showed it was strictly weaker than running upstream's own suite:

  • 73 of the 74 tests it skipped as "Not supported by Camoufox" pass when the same binary runs upstream's copy. The skips predated main-world execution and were never revisited; the suite was asserting that Camoufox was worse than it is.
  • Of its passing tests, eight had no upstream counterpart. Six of those were Camoufox-specific and are now the three modules in camoufox/; the other two were tests upstream had since renamed.
  • Everything else was upstream code, one generation stale.

ci/run_playwright.py fetches playwright-python at the tag ci/versions.py resolves for the browser under test, applies ci/skiplist.yml, and overlays camoufox/. A suite that is re-fetched every run cannot go stale, and a deliberate difference from upstream now has to be written down in the skiplist with a reason instead of being encoded as a silent fork.

make tests                  # the whole suite
make tests headful=true     # ... headed
python3 -m ci.run_playwright --binary /path/to/camoufox-bin --shard 3/6