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

3.6 KiB

cloakserve-connect

Purpose

connectCloakServe connects Playwright to a running cloakserve CDP multiplexer over chromium.connectOverCDP(...), with the fingerprint / proxy / geoip / locale parameters expressed as a strongly-typed options bundle rather than a hand-rolled query string.

The helper exists so test suites can share a single Docker container of cloakhq/cloakbrowser running cloakserve across many parallel workers — each worker requests its own seeded fingerprint via a URL parameter, cloakserve spawns (or reuses) a stealth Chromium process for that seed, and you save the ~200 MB binary download + launch latency that an in-process cloakbrowser.launch() per worker would incur.

Features

  • Strongly-typed CloakServeConnectOptions (mirrors the documented cloakserve query-param surface)
  • Uses {@link buildCloakServeUrl} for URL composition
  • Pluggable Playwright chromium driver (defaults to @playwright/test's built-in chromium)
  • Errors classified by classifyCloakError and wrapped in a CloakLaunchError with cloakServeUrl in context
  • Cache-busting test hook (_resetCloakServeChromiumCache)

Usage: Basic Example

import { connectCloakServe } from "@suaveplan/testing-e2e";

const browser = await connectCloakServe({
    url: "http://localhost:9222",
    fingerprint: 11111,
});
const page = await browser.newPage();
await page.goto("https://protected-site.com");

Usage: Advanced Example

// Parallel workers share one cloakserve container.
import { connectCloakServe } from "@suaveplan/testing-e2e";
import { test } from "@suaveplan/testing-e2e";

test("worker-isolated identity", async ({}, testInfo) => {
    // Per-worker seed gives each worker an isolated Chromium process.
    const browser = await connectCloakServe({
        url: process.env.CLOAKSERVE_URL ?? "http://localhost:9222",
        fingerprint: 10000 + testInfo.parallelIndex,
        timezone: "America/New_York",
        locale: "en-US",
        proxy: process.env.PROXY,
        geoip: true,
    });
    try {
        const ctx = await browser.newContext();
        const page = await ctx.newPage();
        await page.goto("https://example.com");
        await ctx.close();
    } finally {
        await browser.close();
    }
});

API Reference

connectCloakServe(options?, chromium?): Promise<Browser>

Connects to a cloakserve CDP endpoint and returns a Playwright Browser. chromium defaults to @playwright/test's built-in.

Throws: CloakLaunchError with TESTING_E2E.CLOAK.{LAUNCH_FAILED|BINARY_MISSING|PROXY_INVALID} when connectOverCDP rejects. context.cloakServeUrl carries the URL that was attempted.

_resetCloakServeChromiumCache(): void

Internal hook to reset the lazy dynamic-import cache. Exposed for unit tests; production code should never call this.

Implementation Notes

The connectOverCDP call goes through @playwright/test's chromium rather than playwright-core directly because tests in this project already pins @playwright/test as the test runner and Playwright re-exports chromium from there. The injected chromium parameter only needs connectOverCDP — typed as Pick<BrowserType, "connectOverCDP"> so spies are cheap to write.

When pointing at a remote cloakserve, never expose port 9222 to the public internet without an upstream auth layer. CDP gives full control over the browser; see the security warning in the upstream CloakBrowser README. The bundled docker-compose.yml in packages/testing/testing-e2e/docker/ binds to 127.0.0.1 by default.