Docker bundle for @suaveplan/testing-e2e
Two services that round-trip with @suaveplan/testing-e2e's
stealth-Chromium fixtures.
Services
| Service | Image | Port | Purpose |
|---|---|---|---|
cloakserve |
suaveplan-cloakserve:local |
127.0.0.1:9222 |
CDP multiplexer — one container, N parallel test workers, each picking a fingerprint seed. Pair with connectCloakServe(). |
manager |
suaveplan-cloakbrowser-manager:local |
127.0.0.1:8080 |
Optional noVNC + REST profile manager (Multilogin / GoLogin / AdsPower alternative). Enable via the manager compose profile. |
Both services bind to 127.0.0.1 only. Never expose 9222 or 8080
to the public internet without a reverse proxy + auth — both grant
full browser control.
Quick start
# CDP server only — recommended for most CI / dev loops
docker compose up -d cloakserve
# + GUI profile manager (enables the `manager` compose profile)
docker compose --profile manager up -d
# Tear down
docker compose down
Pin specific upstream tags via env vars:
CLOAKBROWSER_TAG=0.3.28 MANAGER_TAG=latest docker compose up -d cloakserve
Set an auth token on the manager before exposing past localhost:
MANAGER_AUTH_TOKEN="$(openssl rand -hex 32)" docker compose --profile manager up -d
Connecting from tests
import { connectCloakServe } from "@suaveplan/testing-e2e";
const browser = await connectCloakServe({
url: "http://localhost:9222",
fingerprint: 11111,
timezone: "America/New_York",
locale: "en-US",
proxy: process.env.RESIDENTIAL_PROXY,
geoip: true,
});
Each unique fingerprint value spawns a separate Chromium process
inside the container. Reuse the same seed across runs to look like a
returning visitor (recommended for reCAPTCHA v3 / Enterprise scoring).
Use testInfo.parallelIndex as the seed source to give each worker an
isolated identity.
Fonts
The cloakserve image bundles the font packages the upstream
CloakBrowser README flags as required for Kasada / Akamai:
fonts-noto-color-emoji(inherited from base)fonts-freefont-ttffonts-unifontfonts-ipafont-gothicfonts-wqy-zenheifonts-tlwg-loma-otf
Without these, canvas emoji rendering hashes don't match any real browser and aggressive bot detection flags the session.