import { defineConfig, devices } from '@playwright/test'; import { fileURLToPath } from 'node:url'; import { dirname, resolve } from 'node:path'; import { tmpdir } from 'node:os'; import { mkdtempSync } from 'node:fs'; import { join } from 'node:path'; // __dirname under ESM. const __dirname = dirname(fileURLToPath(import.meta.url)); // Repo root is one level up from ui/. const repoRoot = resolve(__dirname, '..'); // Dedicated E2E port — avoids clashing with a dev server on 9876. const PORT = Number(process.env.E2E_PORT ?? 8788); const BASE_URL = `http://127.0.0.1:${PORT}`; // Isolated, throwaway data + workspace dirs so the E2E never touches real data // (real DB lives at ./data/maestro.db). A fresh temp DB also means the personal // space is auto-created clean on first /api/local/spaces hit. const e2eTmp = mkdtempSync(join(tmpdir(), 'maestro-e2e-')); const DB_PATH = join(e2eTmp, 'e2e.db'); const WORKTREE_DIR = join(e2eTmp, 'workspaces'); export default defineConfig({ testDir: resolve(__dirname, 'e2e'), // The build+boot can be slow; keep a roomy per-test budget. timeout: 60_000, expect: { timeout: 15_000 }, fullyParallel: false, workers: 1, retries: 0, reporter: [['list']], use: { baseURL: BASE_URL, headless: true, // This sandbox disables the Chromium sandbox (bwrap/userns off). Launch // with --no-sandbox or every browser launch fails to spawn. launchOptions: { args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'], }, trace: 'retain-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, ], // Boot the real orchestrator (worker mode) with auth OFF (no config.yaml => // defaults => synthetic 'local' user). dist/ must exist (npm run build:all). webServer: { command: 'node dist/main.js', cwd: repoRoot, url: `${BASE_URL}/ui`, reuseExistingServer: false, timeout: 120_000, stdout: 'pipe', stderr: 'pipe', env: { ...process.env, PORT: String(PORT), DB_PATH, WORKTREE_DIR, AAO_MODE: 'worker', LOG_LEVEL: 'warn', // Mount the MCP subsystem (gated on a 64-hex MCP_ENCRYPTION_KEY) so the // per-space MCP isolation E2E can register/list servers via /api/mcp/*. // A fixed throwaway key keeps the run deterministic; the temp DB it // encrypts is discarded after the run. MCP_ENCRYPTION_KEY: '00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff', }, }, });