From 492d6cab78f81e29f5140247b82f9320f409d38c Mon Sep 17 00:00:00 2001 From: Aaron Qian Date: Wed, 14 Oct 2026 00:30:03 -0700 Subject: [PATCH 1/2] test: compile every route once before the browser specs --- playwright.config.ts | 1 + tests/e2e/warm-up.ts | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/e2e/warm-up.ts diff --git a/playwright.config.ts b/playwright.config.ts index b5c1d24..46d37f0 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -5,6 +5,7 @@ const port = Number(process.env.PW_PORT ?? 5179); export default defineConfig({ testDir: "tests/e2e", + globalSetup: "./tests/e2e/warm-up.ts", retries: process.env.CI ? 2 : 0, reporter: process.env.CI ? [["dot"], ["html", { open: "never" }]] : "list", use: { diff --git a/tests/e2e/warm-up.ts b/tests/e2e/warm-up.ts new file mode 100644 index 0000000..c87cb9f --- /dev/null +++ b/tests/e2e/warm-up.ts @@ -0,0 +1,23 @@ +import { chromium, type FullConfig } from "@playwright/test"; + +// A route's first request makes the dev server transform its whole module +// graph; under load that outlasts a spec's 5 s expect, so it is paid here once. +const ROUTES = [ + ["/", "Dashboard"], + ["/servo", "Pick a servo in the left pane."], + ["/table", "Control table"], + ["/live", "Live"], +] as const; + +export default async function warmUp(config: FullConfig): Promise { + const browser = await chromium.launch(); + try { + const page = await browser.newPage({ baseURL: config.projects[0]?.use.baseURL }); + for (const [path, text] of ROUTES) { + await page.goto(`${path}?sim=1`); + await page.getByRole("main").getByText(text, { exact: true }).waitFor({ timeout: 60_000 }); + } + } finally { + await browser.close(); + } +} From 84262174d2800c166b3ee99a1b1ccc2442de28d7 Mon Sep 17 00:00:00 2001 From: Aaron Qian Date: Wed, 14 Oct 2026 00:30:03 -0700 Subject: [PATCH 2/2] test: keep the e2e server's watcher off --- playwright.config.ts | 1 + vite.config.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/playwright.config.ts b/playwright.config.ts index 46d37f0..96b9a2f 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -17,5 +17,6 @@ export default defineConfig({ command: `npm run dev -- --port ${port} --strictPort`, url: `http://localhost:${port}`, reuseExistingServer: !process.env.CI, + env: { PW_E2E: "1" }, }, }); diff --git a/vite.config.ts b/vite.config.ts index 0d028ce..1be308c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -37,6 +37,8 @@ export default defineConfig({ server: { // The file: dependency lives outside this repo, so dev must be allowed to serve its wasm. fs: { allow: [".", "../open-servo-core/client/web"] }, + // A rebuild of the shared wasm package mid-run hot-swaps the session out from under a spec. + watch: process.env.PW_E2E === "1" ? null : undefined, }, plugins: [ localDescriptors(),