import fs from "node:fs"; import path from "node:path"; import { defineConfig, devices } from "@playwright/test"; import { portFor } from "yt-dlp-transcript-common/lib/ports.mjs"; import { buildFixtureSettings } from "./e2e/fixtures/data"; // Hub-mode e2e: the export app built/run with INSTANCE_MODE=hub renders the // federated shelf and reads other origins at runtime. Cross-origin JSON is // route-mocked WITH CORS headers per spec, so the browser's real same-origin / // CORS enforcement is exercised (a fulfilled cross-origin response the hub can // read only because it carries Access-Control-Allow-Origin) without standing up // a second real static server. Real _headers/serve.json CORS + the offline SW // are covered separately once the hub SW lands. const PORT = portFor("HUB_PORT"); const baseURL = `http://localhost:${PORT}`; const TEST_SETTINGS_FILE = path.resolve(process.cwd(), "test-settings.hub.json"); const TEST_SITES_DIR = path.resolve(process.cwd(), "e2e", "fixtures", "sites"); buildFixtureSettings(TEST_SETTINGS_FILE); // e2e-hub/transcript-downloads.spec writes SITES_DIR/_homepage/homepage.json for // one test and removes it; the fixture tree never commits one. Remove a leftover // from a killed run before any spec reads the hub's config. fs.rmSync(path.join(TEST_SITES_DIR, "_homepage"), { recursive: true, force: true }); // E2E_MODE (start | dev), the editor's and umtool's switch: those suites // default to `start`, a production build the stamp vouches for // (scripts/e2e-stamp.mjs). This suite always runs under `next dev`: the export is a // STATIC export (output: "export"), and the hub specs rewrite fixture sites // mid-run and assert the page that follows — a build would have baked the // old ones in. // `E2E_MODE=start` is accepted and says so; anything else is refused. { const mode = (process.env.E2E_MODE ?? "").trim().toLowerCase(); if (mode !== "" && mode !== "start" && mode !== "dev") { throw new Error(`E2E_MODE=${process.env.E2E_MODE} is not a mode: use start or dev`); } if (mode === "start" && !process.env.E2E_BUILD_CHECKED) { process.stderr.write( "export hub e2e: E2E_MODE=start has no build to run here (a static export bakes its fixtures in at build time) — running next dev\n", ); process.env.E2E_BUILD_CHECKED = "1"; } } export default defineConfig({ testDir: "./e2e-hub", timeout: 30_000, retries: process.env.CI ? 2 : 0, // `json` beside `list`: the run's timing record, which // scripts/e2e-timings.mjs totals per spec against the branch's last run. reporter: process.env.CI ? "github" : [["list"], ["json", { outputFile: "test-results-hub/timings.json" }]], outputDir: "test-results-hub/", fullyParallel: false, workers: 1, webServer: { command: `pnpm dev --port ${PORT}`, url: baseURL, timeout: 120_000, reuseExistingServer: !process.env.CI, env: { INSTANCE_MODE: "hub", SETTINGS_FILE: TEST_SETTINGS_FILE, SITES_DIR: TEST_SITES_DIR, }, }, use: { baseURL, trace: "on-first-retry", screenshot: "only-on-failure", video: "retain-on-failure", }, projects: [ { name: "chromium", use: { ...devices["Desktop Chrome"], viewport: { width: 1440, height: 1200 } }, }, ], });