281 lines
25 KiB
Markdown
281 lines
25 KiB
Markdown
# @suaveplan/testing-e2e - Stealth Playwright E2E utilities backed by cloakbrowser — config factory, page objects, fixtures, helpers, structured errors. Drop-in browser-launch swap that passes Cloudflare Turnstile, reCAPTCHA v3, FingerprintJS. Layer 0; no @suaveplan/* runtime deps
|
|
|
|
## Summary
|
|
|
|
Playwright E2E testing utilities for Suaveplan, with the
|
|
default `browser` worker fixture launching
|
|
[`cloakbrowser`](https://github.com/CloakHQ/cloakbrowser) — a real
|
|
Chromium binary with 49 source-level C++ fingerprint patches — instead
|
|
of the stock Playwright Chromium. Every spec that imports
|
|
`extendedTest` from this package gets `navigator.webdriver === false`,
|
|
real GPU/canvas/audio/screen/WebRTC fingerprints, a normal
|
|
`window.chrome`, no `HeadlessChrome` UA leak, and no CDP detection
|
|
signal. Cloudflare Turnstile, reCAPTCHA v3 (0.9 score), FingerprintJS,
|
|
BrowserScan, and ShieldSquare see a normal browser.
|
|
|
|
The rest of the package is unchanged: a config factory with WSL2/CI
|
|
defaults, an abstract `PageObject` base, an `apiContext` fixture that
|
|
deliberately does NOT depend on `browser`, network/console monitors,
|
|
multi-session orchestration, OTel-instrumented entry points, and a
|
|
structured `TestingE2eError` hierarchy (now with `CLOAK_*` codes).
|
|
Layer 0 — no `@suaveplan/*` runtime dependencies.
|
|
|
|
### What the swap changes
|
|
|
|
- `extendedTest.browser` is launched via `cloakbrowser.launch`. The
|
|
returned object is still a Playwright `Browser` from
|
|
`playwright-core` — every fixture, page object, helper, and monitor
|
|
works unchanged.
|
|
- A new worker option `cloak: CloakOptions` flows into the launcher.
|
|
Set per project in `playwright.config.ts`:
|
|
`use: { cloak: { humanize: true, geoip: true, proxy: "…" } }`.
|
|
- `launchWithExtension` defaults to
|
|
`cloakbrowser.launchPersistentContext` and exposes a
|
|
`launchPersistentContext` injector for tests / profile managers.
|
|
- Failures classify into `TESTING_E2E.CLOAK.{LAUNCH_FAILED,BINARY_MISSING,PROXY_INVALID}`
|
|
via `classifyCloakError` + `wrapCloakError`, wrapped in
|
|
`CloakLaunchError`.
|
|
- `@playwright/test` stays as the test runner — cloakbrowser is a
|
|
drop-in browser-launch replacement, not a runner replacement.
|
|
- **No public re-exports of `cloakbrowser` symbols.** Per CLAUDE.md
|
|
rule 4, when bypassing the fixture layer, consumers
|
|
`import { launch } from "cloakbrowser"` directly.
|
|
|
|
### Binary footprint
|
|
|
|
On first launch the stealth Chromium binary (~200 MB) is auto-
|
|
downloaded to `~/.cache/cloakbrowser/`. CI runners pre-cache it via
|
|
`npx cloakbrowser install` in the setup step (parity with
|
|
`playwright install chromium`).
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [build-cloakserve-url](./src/cloakserve/build-cloakserve-url.md) — `buildCloakServeUrl` constructs the WebSocket / HTTP endpoint URL for `cloakserve`, the cloakbrowser CDP multiplexer th…
|
|
- [cloakserve-connect](./src/cloakserve/cloakserve-connect.md) — `connectCloakServe` connects Playwright to a running `cloakserve` CDP multiplexer over `chromium.connectOverCDP(...)`,…
|
|
- [config](./src/config/create-playwright-config.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [create-playwright-config](./src/config/create-playwright-config.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [codes](./src/errors/codes.md) — `TESTING_E2E_ERROR_CODES` is the frozen registry of every failure code `@suaveplan/testing-e2e` emits. All codes carry…
|
|
- [testing-e2e-error](./src/errors/testing-e2e-error.md) — `TestingE2eError` is the structured error class thrown by every helper, fixture, and page object in `@suaveplan/testing…
|
|
- [extension-fixture](./src/extension-fixture/launch-with-extension.md) — `launchWithExtension` starts a stealth Chromium persistent browser context with an unpacked browser extension loaded, t…
|
|
- [launch-with-extension](./src/extension-fixture/launch-with-extension.md) — `launchWithExtension` starts a stealth Chromium persistent browser context with an unpacked browser extension loaded, t…
|
|
- [fixtures](./src/fixtures/extended-test.md) — `extendedTest` is the Playwright `test` function pre-extended with the fixtures this package ships, and — critically —…
|
|
- [extended-test](./src/fixtures/extended-test.md) — `extendedTest` is the Playwright `test` function pre-extended with the fixtures this package ships, and — critically —…
|
|
- [dismiss-dialog](./src/helpers/dismiss-dialog.md) — `dismissDialog` attaches a one-shot handler to the next `page.on("dialog")` event, with the caller choosing between `ac…
|
|
- [mock-clipboard](./src/helpers/mock-clipboard.md) — `mockClipboard` installs a deterministic, in-memory clipboard implementation on the navigator object for a Playwright p…
|
|
- [mock-geolocation](./src/helpers/mock-geolocation.md) — `mockGeolocation` pins a Playwright page to a fixed `{ latitude, longitude }` so tests that exercise location-aware fea…
|
|
- [screenshot-on-failure](./src/helpers/screenshot-on-failure.md) — `screenshotOnFailure` captures a full-page screenshot when a Playwright test fails and attaches it to the `TestInfo` re…
|
|
- [wait-for-network-idle](./src/helpers/wait-for-network-idle.md) — `waitForNetworkIdle` suspends until a Playwright page has had zero in-flight requests for at least `idleMs` consecutive…
|
|
- [multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [create-multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [observability](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [instrumented](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [page-objects](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [page-object](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [presets](./src/presets/stealth-presets.md) — Ready-made `CloakOptions` bundles for the most common cloakbrowser deployment shapes. Pulled from the official CloakBro…
|
|
- [stealth-presets](./src/presets/stealth-presets.md) — Ready-made `CloakOptions` bundles for the most common cloakbrowser deployment shapes. Pulled from the official CloakBro…
|
|
<!-- end:auto-docs --> - [create-playwright-config](./src/config/create-playwright-config.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — `TESTING_E2E_ERROR_CODES` is the frozen registry of every failure code `@suaveplan/testing-e2e` emits. All codes carry…
|
|
- [testing-e2e-error](./src/errors/testing-e2e-error.md) — `TestingE2eError` is the structured error class thrown by every helper, fixture, and page object in `@suaveplan/testing…
|
|
- [extension-fixture](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [launch-with-extension](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixtures](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [extended-test](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [dismiss-dialog](./src/helpers/dismiss-dialog.md) — `dismissDialog` attaches a one-shot handler to the next `page.on("dialog")` event, with the caller choosing between `ac…
|
|
- [mock-clipboard](./src/helpers/mock-clipboard.md) — `mockClipboard` installs a deterministic, in-memory clipboard implementation on the navigator object for a Playwright p…
|
|
- [mock-geolocation](./src/helpers/mock-geolocation.md) — `mockGeolocation` pins a Playwright page to a fixed `{ latitude, longitude }` so tests that exercise location-aware fea…
|
|
- [screenshot-on-failure](./src/helpers/screenshot-on-failure.md) — `screenshotOnFailure` captures a full-page screenshot when a Playwright test fails and attaches it to the `TestInfo` re…
|
|
- [wait-for-network-idle](./src/helpers/wait-for-network-idle.md) — `waitForNetworkIdle` suspends until a Playwright page has had zero in-flight requests for at least `idleMs` consecutive…
|
|
- [multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [instrumented](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-objects](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-object](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-playwright-config](./src/config/create-playwright-config.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — `TESTING_E2E_ERROR_CODES` is the frozen registry of every failure code `@suaveplan/testing-e2e` emits. All codes carry…
|
|
- [testing-e2e-error](./src/errors/testing-e2e-error.md) — `TestingE2eError` is the structured error class thrown by every helper, fixture, and page object in `@suaveplan/testing…
|
|
- [extension-fixture](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [launch-with-extension](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixtures](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [extended-test](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [dismiss-dialog](./src/helpers/dismiss-dialog.md) — `dismissDialog` attaches a one-shot handler to the next `page.on("dialog")` event, with the caller choosing between `ac…
|
|
- [mock-clipboard](./src/helpers/mock-clipboard.md) — `mockClipboard` installs a deterministic, in-memory clipboard implementation on the navigator object for a Playwright p…
|
|
- [mock-geolocation](./src/helpers/mock-geolocation.md) — `mockGeolocation` pins a Playwright page to a fixed `{ latitude, longitude }` so tests that exercise location-aware fea…
|
|
- [screenshot-on-failure](./src/helpers/screenshot-on-failure.md) — `screenshotOnFailure` captures a full-page screenshot when a Playwright test fails and attaches it to the `TestInfo` re…
|
|
- [wait-for-network-idle](./src/helpers/wait-for-network-idle.md) — `waitForNetworkIdle` suspends until a Playwright page has had zero in-flight requests for at least `idleMs` consecutive…
|
|
- [multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [instrumented](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-objects](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-object](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-playwright-config](./src/config/create-playwright-config.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — `TESTING_E2E_ERROR_CODES` is the frozen registry of every failure code `@suaveplan/testing-e2e` emits. All codes carry…
|
|
- [testing-e2e-error](./src/errors/testing-e2e-error.md) — `TestingE2eError` is the structured error class thrown by every helper, fixture, and page object in `@suaveplan/testing…
|
|
- [extension-fixture](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [launch-with-extension](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixtures](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [extended-test](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [dismiss-dialog](./src/helpers/dismiss-dialog.md) — `dismissDialog` attaches a one-shot handler to the next `page.on("dialog")` event, with the caller choosing between `ac…
|
|
- [mock-clipboard](./src/helpers/mock-clipboard.md) — `mockClipboard` installs a deterministic, in-memory clipboard implementation on the navigator object for a Playwright p…
|
|
- [mock-geolocation](./src/helpers/mock-geolocation.md) — `mockGeolocation` pins a Playwright page to a fixed `{ latitude, longitude }` so tests that exercise location-aware fea…
|
|
- [screenshot-on-failure](./src/helpers/screenshot-on-failure.md) — `screenshotOnFailure` captures a full-page screenshot when a Playwright test fails and attaches it to the `TestInfo` re…
|
|
- [wait-for-network-idle](./src/helpers/wait-for-network-idle.md) — `waitForNetworkIdle` suspends until a Playwright page has had zero in-flight requests for at least `idleMs` consecutive…
|
|
- [multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [instrumented](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-objects](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-object](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-playwright-config](./src/config/create-playwright-config.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_ - [console-monitor](./src/console-monitor/console-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — `TESTING_E2E_ERROR_CODES` is the frozen registry of every failure code `@suaveplan/testing-e2e` emits. All codes carry…
|
|
- [testing-e2e-error](./src/errors/testing-e2e-error.md) — `TestingE2eError` is the structured error class thrown by every helper, fixture, and page object in `@suaveplan/testing…
|
|
- [extension-fixture](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_ - [launch-with-extension](./src/extension-fixture/launch-with-extension.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixtures](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_ - [extended-test](./src/fixtures/extended-test.md) — <!-- begin:auto-docs --> _(no submodules)_- [dismiss-dialog](./src/helpers/dismiss-dialog.md) — `dismissDialog` attaches a one-shot handler to the next `page.on("dialog")` event, with the caller choosing between `ac…
|
|
- [mock-clipboard](./src/helpers/mock-clipboard.md) — `mockClipboard` installs a deterministic, in-memory clipboard implementation on the navigator object for a Playwright p…
|
|
- [mock-geolocation](./src/helpers/mock-geolocation.md) — `mockGeolocation` pins a Playwright page to a fixed `{ latitude, longitude }` so tests that exercise location-aware fea…
|
|
- [screenshot-on-failure](./src/helpers/screenshot-on-failure.md) — `screenshotOnFailure` captures a full-page screenshot when a Playwright test fails and attaches it to the `TestInfo` re…
|
|
- [wait-for-network-idle](./src/helpers/wait-for-network-idle.md) — `waitForNetworkIdle` suspends until a Playwright page has had zero in-flight requests for at least `idleMs` consecutive…
|
|
- [multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_ - [create-multi-session](./src/multi-session/create-multi-session.md) — <!-- begin:auto-docs --> _(no submodules)_- [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_ - [network-monitor](./src/network-monitor/network-monitor.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_ - [instrumented](./src/observability/instrumented.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-objects](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_ - [page-object](./src/page-objects/page-object.md) — <!-- begin:auto-docs --> _(no submodules)_
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/testing-e2e
|
|
```
|
|
|
|
Requires `@playwright/test` and `cloakbrowser` (installed automatically as direct dependencies). On first launch cloakbrowser auto-downloads the stealth Chromium binary; pre-cache in CI with `npx cloakbrowser install`.
|
|
|
|
## Quick Start
|
|
|
|
### Playwright config
|
|
|
|
```ts
|
|
// playwright.config.ts
|
|
import { createPlaywrightConfig } from "@suaveplan/testing-e2e/config";
|
|
|
|
export default createPlaywrightConfig({
|
|
baseURL: "http://localhost:3000",
|
|
testDir: "e2e",
|
|
projects: [
|
|
{ name: "chromium", use: { browserName: "chromium" } },
|
|
],
|
|
});
|
|
```
|
|
|
|
### Page object + stealth extended fixtures
|
|
|
|
```ts
|
|
// playwright.config.ts — cloak options for the default browser fixture
|
|
import { createPlaywrightConfig } from "@suaveplan/testing-e2e/config";
|
|
|
|
export default createPlaywrightConfig({
|
|
baseURL: "http://localhost:3000",
|
|
testDir: "e2e",
|
|
use: {
|
|
cloak: {
|
|
headless: true,
|
|
humanize: true,
|
|
geoip: true,
|
|
proxy: "socks5://user:pass@residential:1080",
|
|
},
|
|
},
|
|
});
|
|
```
|
|
|
|
```ts
|
|
// e2e/pages/login.page.ts
|
|
import { PageObject } from "@suaveplan/testing-e2e/page-objects";
|
|
|
|
export class LoginPage extends PageObject {
|
|
public readonly path = "/login";
|
|
|
|
get emailInput() { return this.findByLabel("Email"); }
|
|
get submitButton() { return this.findByRole("button", { name: /sign in/i }); }
|
|
}
|
|
|
|
// e2e/login.spec.ts — runs against a Cloudflare-walled app
|
|
import { extendedTest as test, expect } from "@suaveplan/testing-e2e/fixtures";
|
|
import { waitForNetworkIdle } from "@suaveplan/testing-e2e/helpers";
|
|
import { LoginPage } from "./pages/login.page.js";
|
|
|
|
test("signs in through Cloudflare Turnstile", async ({ page }) => {
|
|
const login = new LoginPage(page);
|
|
await login.navigate(); // Turnstile lets us through
|
|
await login.emailInput.fill("user@example.com");
|
|
await login.submitButton.click();
|
|
await waitForNetworkIdle(page);
|
|
await expect(page).toHaveURL("/dashboard");
|
|
});
|
|
```
|
|
|
|
### Programmatic launch (outside the Playwright runner)
|
|
|
|
```ts
|
|
import { launchBrowserWithCloak } from "@suaveplan/testing-e2e/fixtures";
|
|
|
|
const browser = await launchBrowserWithCloak({
|
|
humanize: true,
|
|
geoip: true,
|
|
proxy: "http://user:pass@proxy:8080",
|
|
});
|
|
const ctx = await browser.newContext();
|
|
const page = await ctx.newPage();
|
|
await page.goto("https://bot.incolumitas.com");
|
|
console.log(await page.title());
|
|
await browser.close();
|
|
```
|
|
|
|
### Extension fixture (stealth + persistent profile)
|
|
|
|
```ts
|
|
import { launchWithExtension } from "@suaveplan/testing-e2e/extension-fixture";
|
|
|
|
const { context, extensionId } = await launchWithExtension({
|
|
extensionPath: "/path/to/unpacked-extension",
|
|
userDataDir: "/tmp/profile",
|
|
launchOptions: { humanize: true, geoip: true },
|
|
});
|
|
```
|
|
|
|
### Cloakserve CDP server (shared container, N parallel workers)
|
|
|
|
```bash
|
|
# One container, all your test workers share it
|
|
cd packages/testing/testing-e2e/docker
|
|
docker compose up -d cloakserve
|
|
```
|
|
|
|
```ts
|
|
import { connectCloakServe, stealthMax } from "@suaveplan/testing-e2e";
|
|
|
|
const browser = await connectCloakServe({
|
|
url: "http://localhost:9222",
|
|
fingerprint: 11111, // per-worker seed
|
|
timezone: "America/New_York",
|
|
locale: "en-US",
|
|
proxy: process.env.RESIDENTIAL_PROXY,
|
|
geoip: true,
|
|
});
|
|
```
|
|
|
|
### Stealth presets
|
|
|
|
```ts
|
|
// playwright.config.ts
|
|
import { defineConfig } from "@playwright/test";
|
|
import { stealthMax } from "@suaveplan/testing-e2e";
|
|
|
|
export default defineConfig({
|
|
use: {
|
|
// Upstream-recommended config: residential proxy + geoip + headed + humanize.
|
|
cloak: stealthMax(process.env.RESIDENTIAL_PROXY!),
|
|
},
|
|
});
|
|
```
|
|
|
|
`STEALTH_DEFAULT_CLOAK` / `STEALTH_HEADED_CLOAK` are also exported
|
|
for the lighter shapes. See `src/presets/stealth-presets.md` for the
|
|
full menu.
|
|
|
|
### Docker bundle
|
|
|
|
`packages/testing/testing-e2e/docker/` ships:
|
|
|
|
- `Dockerfile.cloakserve` — extends `cloakhq/cloakbrowser`, adds the
|
|
Kasada / Akamai font set, runs `cloakserve` on 9222
|
|
- `Dockerfile.manager` — extends `cloakhq/cloakbrowser-manager`,
|
|
exposes 8080 with a `cloakprofiles` named volume for persistence
|
|
- `docker-compose.yml` — both services on `127.0.0.1`, with the
|
|
manager gated behind the `manager` compose profile
|
|
- `.env.example` — pinnable `CLOAKBROWSER_TAG`, `MANAGER_TAG`, and
|
|
`MANAGER_AUTH_TOKEN`
|
|
|
|
See `docker/README.md` for the full operator playbook.
|
|
|
|
## Modules
|
|
|
|
| Subpath | Module | Description |
|
|
|---|---|---|
|
|
| `@suaveplan/testing-e2e/config` | [src/config/create-playwright-config.md](src/config/create-playwright-config.md) | `createPlaywrightConfig` — emits a `PlaywrightTestConfig` with WSL2-safe defaults (`fullyParallel: false`, trace/screenshot/video retention) and automatic CI mode (`retries: 2`, `workers: 1`) |
|
|
| `@suaveplan/testing-e2e/page-objects` | [src/page-objects/page-object.md](src/page-objects/page-object.md) | Abstract `PageObject` base class — typed wrapper around a Playwright `Page` with `navigate()`, `waitForReady()`, and accessibility-first locator helpers (`findByRole`, `findByLabel`, `findByText`) |
|
|
| `@suaveplan/testing-e2e/fixtures` | [src/fixtures/extended-test.md](src/fixtures/extended-test.md) | `extendedTest` — `test.extend(...)` with the `browser` worker fixture overridden to launch `cloakbrowser`; plus `apiContext` (isolated `APIRequestContext`, browser-free) and `freshPage` (isolated browser context + page); also exports `launchBrowserWithCloak` and `expect` |
|
|
| `@suaveplan/testing-e2e/helpers` | [src/helpers/wait-for-network-idle.md](src/helpers/wait-for-network-idle.md) | `waitForNetworkIdle` — polls in-flight request count and resolves once the network has been idle for `idleMs` (default 500 ms); throws `WaitTimeoutError` on timeout |
|
|
| | [src/helpers/mock-clipboard.md](src/helpers/mock-clipboard.md) | `mockClipboard` — installs a programmatic in-page clipboard so tests can assert `writeText`/`readText` without OS permissions |
|
|
| | [src/helpers/mock-geolocation.md](src/helpers/mock-geolocation.md) | `mockGeolocation` — grants geolocation permission and sets static latitude/longitude/accuracy on a `BrowserContext` |
|
|
| | [src/helpers/screenshot-on-failure.md](src/helpers/screenshot-on-failure.md) | `screenshotOnFailure` — captures a full-page screenshot named after the failing test; useful as a manual teardown hook alongside Playwright's built-in artifact retention |
|
|
| | [src/helpers/dismiss-dialog.md](src/helpers/dismiss-dialog.md) | `dismissDialog` — registers a one-shot `dialog` handler that accepts or dismisses the next browser dialog (`alert`, `confirm`, `prompt`) |
|
|
| `@suaveplan/testing-e2e/errors` | [src/errors/testing-e2e-error.md](src/errors/testing-e2e-error.md) | Typed error classes (`NavigationError`, `WaitTimeoutError`, `AbortedError`, `CloakLaunchError`) + `classifyCloakError` / `wrapCloakError` helpers |
|
|
| | [src/errors/codes.md](src/errors/codes.md) | `TESTING_E2E_ERROR_CODES` registry |
|
|
| _(observability)_ | [src/observability/instrumented.md](src/observability/instrumented.md) | `instrumented` — optional OTel wrapper (gated by `TESTING_E2E_OTEL_ENABLED=1`) that records call counts and duration histograms for package entrypoints |
|
|
|