Files
kandev/apps/web/e2e/playwright.config.ts
T
José Almeida 21cc4304a6 chore(e2e): rename docker project to containers + add e2e README
The Docker e2e Playwright project was the natural home for any test
that needs a real Docker daemon on the host — but its name implied it
was only about the Docker executor. SSH e2e tests (incoming in
follow-up commits) belong here too, since they use a Dockerised sshd
container as the SSH executor's remote target.

- Rename project: docker -> containers, widen testMatch to also include
  tests/ssh/*.spec.ts.
- Rename env flag: KANDEV_E2E_DOCKER -> KANDEV_E2E_CONTAINERS, with the
  old name kept as a deprecated alias for one release so local scripts
  and CI configs don't break overnight.
- Rename CI job: e2e-docker -> e2e-containers, switch its blob report
  name and the merge-job dependency.
- Add apps/web/e2e/README.md explaining the project layout, what the
  containers project covers (Docker executor + SSH executor), why it
  was renamed, and how to run it locally.
- Add docs/specs/ssh-executor/e2e-plan.md tracking the SSH e2e
  coverage we'll implement on top of this rename (real sshd container,
  no mocks, 17 spec files covering ~75 cases). Includes a "Deferred"
  section that flags arm64 as something to revisit when
  agentctl-linux-arm64 lands in the build pipeline.
2026-05-17 23:31:16 +01:00

96 lines
3.9 KiB
TypeScript

import { defineConfig, devices } from "@playwright/test";
const CI = !!process.env.CI;
export default defineConfig({
testDir: "./tests",
// Single worker per process — CI uses --shard to split tests across matrix
// runners (each gets its own 4 vCPUs). Tests run serially within the worker
// because the testPage fixture does e2eReset on a shared worker-scoped
// backend before each test.
//
// Isolation strategy: office-routing-* specs are gathered into their own
// Playwright project (see below) so the worker-scoped backend env
// (KANDEV_MOCK_PROVIDERS, KANDEV_PROVIDER_FAILURES) that those specs
// restart with cannot leak into specs that count agents or read the
// topbar agent name. Each routing spec restarts the backend back to
// baseline in `afterAll` (see backend.restart() — no args = revert to
// the fixture's baseline env snapshot).
fullyParallel: false,
forbidOnly: CI,
retries: CI ? 2 : 0,
workers: 1,
timeout: 60_000,
// CI uses blob reporter for cross-shard merge-reports; local uses list.
reporter: CI ? [["blob", { outputDir: "./blob-report" }]] : "list",
outputDir: "./test-results",
use: {
trace: "on-first-retry",
screenshot: "only-on-failure",
video: "on-first-retry",
},
projects: [
{
// The office-routing-* specs call `backend.restart()` with
// KANDEV_MOCK_PROVIDERS, which permanently mutates the backend's
// env for the lifetime of the worker (and registers extra
// canonical providers). Run them in their own project so that
// pollution can never leak into specs that count agents or read
// the topbar agent name — see CLAUDE.md's note on
// KANDEV_MOCK_PROVIDERS for the underlying invariant.
name: "routing",
testMatch: /office-routing-.*\.spec\.ts/,
use: { ...devices["Desktop Chrome"] },
},
{
name: "chromium",
testIgnore: [
/mobile-.*\.spec\.ts/,
// Container-backed tests (Docker executor, SSH executor) live in the
// `containers` project and skip when Docker is not available locally.
// See apps/web/e2e/README.md for what runs there.
/docker\/.*\.spec\.ts/,
/ssh\/.*\.spec\.ts/,
/office-routing-.*\.spec\.ts/,
],
use: { ...devices["Desktop Chrome"] },
},
{
name: "mobile-chrome",
testMatch: /mobile-.*\.spec\.ts/,
use: { ...devices["Pixel 5"] },
},
{
// Real-container E2E. Opt-in: run with `playwright test --project=containers`.
// Spawns the backend with KANDEV_E2E_CONTAINERS=1 (KANDEV_E2E_DOCKER=1
// is honored as a deprecated alias for one release). Builds the
// kandev-agent:e2e and kandev-sshd:e2e images and skips entirely on
// hosts without a Docker daemon — Docker is used as the runtime for
// both the Docker executor's own containers AND the sshd target the
// SSH executor connects to. Container-bound tests are slow (~10-30s
// each) so they live in their own project to keep the default CI fast.
//
// See apps/web/e2e/README.md for context and how to run locally.
name: "containers",
testMatch: [/docker\/.*\.spec\.ts/, /ssh\/.*\.spec\.ts/],
use: { ...devices["Desktop Chrome"] },
timeout: 180_000,
// Per-test sharding: CI runs `--shard=N/6` to split this project's
// tests across runners. Playwright only shards at the test level
// when fullyParallel is true (otherwise sharding is by file, and
// since this project has a single spec file every test would land
// in shard 1). Each shard is its own process with its own backend,
// and workers:1 still serializes tests within a shard, so this is
// safe.
fullyParallel: true,
},
],
// No webServer — each Playwright worker spawns its own frontend
// via the backend fixture (see fixtures/backend.ts)
globalSetup: "./global-setup.ts",
});