4.8 KiB
swap-testing-e2e-cloakbrowser
Why
@playwright/test ships a stock Chromium that is trivially fingerprinted as
automation (navigator.webdriver === true, HeadlessChrome UA, missing
window.chrome, GPU/canvas/audio leaks, CDP detection). E2E suites that
exercise production-like flows against bot-aware infrastructure
(Cloudflare Turnstile, reCAPTCHA v3, ShieldSquare, FingerprintJS,
BrowserScan) either fail outright or skew metrics on the first request.
CloakBrowser (cloakbrowser,
v0.3.28) is a real Chromium binary with 49 source-level C++ patches
covering canvas, WebGL, audio, fonts, GPU, screen, WebRTC, network
timing, automation signals, and CDP input behaviour. It is a drop-in
replacement at the browser-launch layer: the returned object is a
playwright-core Browser and works with every existing Playwright
test, fixture, page-object, and helper without API changes.
This proposal swaps every browser-launch call inside
@suaveplan/testing-e2e to cloakbrowser, retains @playwright/test
as the test runner (CloakBrowser does not provide one), and exposes the
stealth-specific knobs (humanize, proxy, geoip,
launchPersistentContext, extension support) as first-class API surface.
What Changes
- ADDED:
CLOAK_LAUNCH_FAILED,CLOAK_BINARY_MISSING,CLOAK_PROXY_INVALIDerror codes +CloakLaunchErrorclass +classifyCloakErrorhelper that turns raw cloakbrowser errors into classifiedTestingE2eErrorinstances with remediation hints. - ADDED:
@suaveplan/testing-e2e/cloakservesubpath —connectCloakServe(options, chromium?)+buildCloakServeUrl(options)pair that wrapschromium.connectOverCDP(...)for the cloakserve CDP multiplexer. Strongly-typed query-parameter surface (fingerprint,timezone,locale,platform, GPU vendor / renderer, hardware concurrency, device memory, screen dimensions,proxy,geoip). Errors wrapped inCloakLaunchError. - ADDED:
@suaveplan/testing-e2e/presetssubpath — stealth presets matching the upstream README's "Recommended config for anti-bot sites" block.STEALTH_DEFAULT_CLOAK,STEALTH_HEADED_CLOAK,stealthMax(proxy),stealthMaxHeadless(proxy). - ADDED:
tests/no-disallowed.test.tsrule againstwaitForTimeout/wait_for_timeout. Both forms emit CDP traffic that reCAPTCHA v3 / Enterprise behavioural scorers detect; the upstream README documents this explicitly. Test files excluded. - ADDED:
docker/bundle —Dockerfile.cloakserve(extendscloakhq/cloakbrowser, adds the Kasada / Akamai font set, runscloakserveon 9222),Dockerfile.manager(extendscloakhq/cloakbrowser-manager, exposes 8080 with acloakprofilesnamed volume),docker-compose.ymlbinding both to127.0.0.1with the manager gated behind themanagercompose profile,.env.examplefor pinned tags +AUTH_TOKEN, operatorREADME.md. - MODIFIED:
extendedTest'sbrowserfixture now launches viacloakbrowser.launch()instead of the stock Playwright chromium fixture.freshPageand any downstream fixture composition keep the same signature. The launcher is unit-test-injectable via thelaunchBrowserWithCloak(opts, injectedLaunch?)helper. - MODIFIED:
launchWithExtensionaccepts an injectablelaunchPersistentContextfunction (default: cloakbrowser's). The legacychromium: BrowserTypeparameter is removed. - MODIFIED:
packages/testing/testing-e2e/package.jsonaddscloakbrowser: ^0.3.28as a direct dependency. (The dep is pinned in-package rather than added toworkspaces.catalogs.testingto keep this change isolated from concurrent in-flight work that also touches the root catalog; promote to the testing catalog as a follow-up if other packages start consumingcloakbrowser.) - MODIFIED: Package description, README updated. No public
re-exports of cloakbrowser symbols — per CLAUDE.md rule 4,
consumers
import { launch } from "cloakbrowser"directly when bypassing the fixture layer.
Impact
- Affected specs:
testing-e2e. - Affected code: all six consumer packages currently importing from
@suaveplan/testing-e2econtinue to work unchanged — the browser launcher swap is transparent to existing tests because the returnedBrowserobject is the sameplaywright-coreBrowsertype. - Binary footprint: CI runners gain a ~200MB stealth Chromium
download on first run (cached under
~/.cache/cloakbrowser/). Acceptable: the alternative isplaywright install chromium(~170MB) on every@playwright/testconsumer. - Out of scope: Python flavour (
cloakbrowserPyPI),cloakserveCDP multiplexer,cloakbrowser-managerDocker profile UI — none are consumed by the genesis monorepo today.