import { expect, test } from "@playwright/test"; import { loginAsOperator, loginAsUser } from "../fixtures/authHelpers"; import { attachPageHealthGuards, expectBodyHasContent, expectOneVisible, requiredEnv, settlePage, } from "./helpers"; const liveSmokeEnabled = Boolean( process.env.PLAYWRIGHT_BASE_URL && process.env.PLAYWRIGHT_USER_CUSTOMER_NUMBER && process.env.PLAYWRIGHT_USER_PASSWORD && process.env.PLAYWRIGHT_OPERATOR_USER_ID && process.env.PLAYWRIGHT_OPERATOR_PASSWORD, ); function getLiveSettings() { return { baseURL: requiredEnv("PLAYWRIGHT_BASE_URL"), customerCredentials: { customerNumber: requiredEnv("PLAYWRIGHT_USER_CUSTOMER_NUMBER"), password: requiredEnv("PLAYWRIGHT_USER_PASSWORD"), otpSecret: process.env.PLAYWRIGHT_USER_OTP_SECRET || "", twoFactorAuthentication: Boolean(process.env.PLAYWRIGHT_USER_OTP_SECRET), }, operatorCredentials: { userId: requiredEnv("PLAYWRIGHT_OPERATOR_USER_ID"), password: requiredEnv("PLAYWRIGHT_OPERATOR_PASSWORD"), }, departmentId: Number.parseInt(process.env.PLAYWRIGHT_DEPARTMENT_ID || "12", 10), }; } test.describe.configure({ mode: "serial" }); test.describe("Live smoke release gate", () => { test.skip(!liveSmokeEnabled, "Set PLAYWRIGHT_BASE_URL and seeded live credentials to run the live smoke gate."); test("guest flow renders on the deployed environment", async ({ page }) => { const { baseURL } = getLiveSettings(); const guards = attachPageHealthGuards(page, baseURL); await page.goto("/guest/book/wash"); await settlePage(page); await expect(page).toHaveURL(/\/guest\/book\/wash(?:\?.*)?$/); await expectBodyHasContent(page); await expect(page.locator("body")).not.toContainText(/404/i); await guards.expectHealthy(); guards.dispose(); }); test("customer login reaches dashboard, profile, and bookings", async ({ page }) => { const { baseURL, customerCredentials } = getLiveSettings(); const guards = attachPageHealthGuards(page, baseURL); await loginAsUser(page, customerCredentials); await expect(page.locator("#book-wash-button")).toBeVisible(); await expect(page.locator("#download-invoices-button")).toBeVisible(); await page.goto("/user/profile"); await settlePage(page); await expect(page).toHaveURL(/\/user\/profile(?:\?.*)?$/); await expect(page.locator(".card-header").first()).toBeVisible(); await page.goto("/user/bookings"); await settlePage(page); await expect(page).toHaveURL(/\/user\/bookings(?:\?.*)?$/); await expect(page.locator(".title").first()).toBeVisible(); await guards.expectHealthy(); guards.dispose(); }); test("operator login reaches the seeded department route", async ({ page }) => { const { baseURL, operatorCredentials, departmentId } = getLiveSettings(); const guards = attachPageHealthGuards(page, baseURL); await loginAsOperator(page, operatorCredentials); await page.goto(`/admin/${departmentId}/modules/pos`); await settlePage(page); await expect(page).toHaveURL(new RegExp(`/admin/${departmentId}/modules/pos(?:\\?.*)?$`)); await expectOneVisible([ page.getByTestId("pos-step-1"), page.getByTestId("pos-mobile-step-1-shell"), ]); await guards.expectHealthy(); guards.dispose(); }); });