Files
kandev/apps/web/e2e/playwright.config.ts
T
José Almeida b1f57cec6b test(docker-e2e): add real-Docker Playwright project + first spec
A new Playwright project — \`docker\` — runs container-bound E2E specs
against a backend with KANDEV_E2E_DOCKER=1. The fixture probes for a
Docker daemon and skips the worker entirely when none is reachable, so
contributors without Docker can still run the rest of the suite.

The fixture builds a tiny kandev-agent:e2e image once per machine
(node:22-slim + git/curl), pre-seeds a local_docker executor profile,
and seeds a local repo with a file:// origin so the executor's
clone-inside-container path resolves without network access. A small
WS-based session.launch helper is added to the api-client for tests
that need to launch additional sessions on an existing task.

First spec — docker-launch.spec.ts — covers the smoke path: a session
launches in a real container, the task environment records its
container_id, and \`docker inspect\` confirms the container exists.
Two follow-up specs (multi-session env reuse + recovery from external
container removal) are wired up but marked test.fixme with comments
pinpointing the backend gaps that block them: persistTaskEnvironment
isn't called for workflow-prepared sessions (so task_environment_id
stays empty on those rows), and DockerExecutor.reconnectToContainer
loses the agentctl handshake auth token across launches (so reconnect
401s and falls back to a fresh container every time).

Run locally with: \`pnpm --filter @kandev/web exec playwright test
--config e2e/playwright.config.ts --project=docker\`.
2026-05-04 21:09:39 +01:00

55 lines
1.7 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.
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: [
{
name: "chromium",
testIgnore: [/mobile-.*\.spec\.ts/, /docker\/.*\.spec\.ts/],
use: { ...devices["Desktop Chrome"] },
},
{
name: "mobile-chrome",
testMatch: /mobile-.*\.spec\.ts/,
use: { ...devices["Pixel 5"] },
},
{
// Real-Docker E2E. Opt-in: run with `playwright test --project=docker`.
// Spawns the backend with KANDEV_E2E_DOCKER=1, builds the
// kandev-agent:e2e image, and skips entirely on hosts without a Docker
// daemon. Container-bound tests are slow (~10-30s each) so they live
// in their own project to keep the default CI fast.
name: "docker",
testMatch: /docker\/.*\.spec\.ts/,
use: { ...devices["Desktop Chrome"] },
timeout: 180_000,
},
],
// No webServer — each Playwright worker spawns its own frontend
// via the backend fixture (see fixtures/backend.ts)
globalSetup: "./global-setup.ts",
});