Files
skills/docs/testkit/testing/testing-e2e/README.md
2026-05-29 08:20:56 +01:00

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 |