Skip to content

Commit 97df7e7

Browse files
committed
ci(e2e): serve a production build instead of the dev server
The suite has been failing on CI while staying green locally: 19 failures spread across admin navigation, the editor publish flow, bookmarking, the feed sidebar and moderation. Identical failures on develop and on every branch off it, so nothing in the feature work caused them. They all share a cause. Playwright's webServer ran `next dev`, so the first request to each route blocked on an on-demand Turbopack compile. Locally that is under a second; on a cold runner with three workers compiling at once it outlasts the 10s expect timeout — hence assertions like `toHaveURL(/admin/users)` polling 13 times and giving up while the navigation was still compiling. CI now builds once and serves it. Measured on the same machine, a cold route costs ~0.7-1.2s under `next dev` and ~0.02-0.03s prebuilt. Local runs keep `next dev` for the fast feedback loop. EMAIL_AUTH_ENABLED is set for the job because a production build runs with NODE_ENV=production, which would otherwise disable the passwordless provider that dev turns on implicitly.
1 parent 7037484 commit 97df7e7

3 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎.github/workflows/e2e-tests.yml‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ jobs:
4141
env:
4242
DATABASE_URL: "postgresql://postgres:secret@localhost:5432/postgres"
4343
NEXTAUTH_URL: http://localhost:3000/api/auth
44+
# A production build sets NODE_ENV=production, which would otherwise turn
45+
# off the passwordless provider that dev enables implicitly.
46+
EMAIL_AUTH_ENABLED: "true"
4447
GITHUB_ID: ${{ secrets.E2E_GITHUB_ID }}
4548
GITHUB_SECRET: ${{ secrets.E2E_GITHUB_SECRET }}
4649
NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }}
@@ -91,6 +94,12 @@ jobs:
9194
npm run db:migrate
9295
npm run db:seed
9396
97+
# Playwright serves this build (see webServer in playwright.config.ts).
98+
# Tests used to run against `next dev`, where the first hit on a route
99+
# blocked on an on-demand compile for longer than the assertion timeouts.
100+
- name: Build app
101+
run: npm run build:e2e
102+
94103
- name: Run Playwright tests
95104
id: playwright-tests
96105
run: npx playwright test

‎package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"scripts": {
66
"dev": "next dev",
77
"dev:e2e": "ENV=E2E next dev",
8+
"build:e2e": "ENV=E2E next build",
9+
"start:e2e": "ENV=E2E next start",
810
"build": "next build",
911
"ci-build": "next build",
1012
"vercel-build": "if [ \"$VERCEL_ENV\" = \"production\" ]; then npm run db:migrate; fi && next build",

‎playwright.config.ts‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,19 @@ export default defineConfig({
6868

6969
outputDir: "playwright-report",
7070

71-
/* Run your local dev server before starting the tests */
71+
/* Run your local dev server before starting the tests.
72+
73+
CI serves a production build instead. Against `next dev`, the FIRST visit
74+
to each route waits on an on-demand Turbopack compile, which on a cold
75+
runner routinely outlasts the 10s expect timeout — that is what made the
76+
admin-nav, editor-publish, bookmark, feed and moderation specs fail there
77+
while the same suite stayed green locally. A prebuilt server has no
78+
per-route compile step, so those assertions see the page immediately.
79+
The workflow runs `build:e2e` before invoking Playwright. */
7280
webServer: {
73-
command: "npm run dev:e2e",
81+
command: process.env.CI ? "npm run start:e2e" : "npm run dev:e2e",
7482
url: "http://127.0.0.1:3000",
7583
reuseExistingServer: !process.env.CI,
84+
timeout: 120_000,
7685
},
7786
});

0 commit comments

Comments
 (0)