Files
pleno-vue/tests/e2e/release/release.local-prod.spec.ts
T
Jeppe Bundgaard b39b458f4f Add .prettierrc.json and refactor test files for improved formatting consistency:
- Introduced `.prettierrc.json` to enforce consistent code formatting across the project.
- Updated unit and e2e test files to address formatting issues, improve readability, and ensure alignment with the new Prettier configuration.
2026-04-13 09:13:27 +02:00

210 lines
6.6 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { loginAsUser } from "../fixtures/authHelpers";
import { createPosFixture, mockApi, seedAuthenticatedState } from "../support/network.js";
import { attachPageHealthGuards, expectBodyHasContent, expectOneVisible, settlePage } from "./helpers";
const LOCAL_PROD_BASE_URL = "http://127.0.0.1:4173";
const LOGIN_URL = /\/login(?:\?.*)?$/;
const POS_PERMISSIONS = [
"admin",
"department_access_12",
"edit_order_items",
"get_user",
"list_customer_notes",
"list_customer_attributes",
"get_custom_prices_other",
];
async function gotoHealthyRoute(page, path: string) {
await page.goto(path);
await settlePage(page);
await expectBodyHasContent(page);
await expect(page.locator("body")).not.toContainText(/404/i);
}
async function seedAuthenticatedRole(
page,
{
token,
permissions,
sessionData = {},
pos = undefined,
}: {
token: string;
permissions: string[];
sessionData?: Record<string, unknown>;
pos?: unknown;
}
) {
await mockApi(page, {
authenticated: true,
permissions,
sessionData,
pos,
});
await seedAuthenticatedState(page, token);
}
test.describe("Local production release gate", () => {
test.describe("PWA sanity", () => {
test.use({ serviceWorkers: "allow" });
test("PWA bootstrap registers on the production build", async ({ page }, testInfo) => {
test.skip(
!testInfo.project.name.startsWith("chromium"),
"Service worker registration is release-gated on Chromium where Playwright exposes stable registrations."
);
const guards = attachPageHealthGuards(page, LOCAL_PROD_BASE_URL);
await mockApi(page, { authenticated: false });
await gotoHealthyRoute(page, "/");
await expect(page.getByTestId("landing-title")).toContainText("Truck Wash");
await page.waitForFunction(
async () => {
const registrations = await navigator.serviceWorker.getRegistrations();
return registrations.some((registration) =>
Boolean(registration.active || registration.installing || registration.waiting)
);
},
undefined,
{ timeout: 20_000 }
);
await guards.expectHealthy();
guards.dispose();
});
});
test.describe("Mocked local-prod browser coverage", () => {
test.use({ serviceWorkers: "block" });
test("public shell routes render on the production build", async ({ page }) => {
const guards = attachPageHealthGuards(page, LOCAL_PROD_BASE_URL);
await mockApi(page, {
authenticated: false,
selfServe: true,
});
await gotoHealthyRoute(page, "/");
await expect(page.getByTestId("landing-title")).toContainText("Truck Wash");
const manifestHref = await page.locator('link[rel="manifest"]').first().getAttribute("href");
expect(manifestHref).toBeTruthy();
const manifestResponse = await page.request.get(new URL(manifestHref!, LOCAL_PROD_BASE_URL).toString());
expect(manifestResponse.ok()).toBeTruthy();
await page.reload();
await settlePage(page);
await expect(page.getByTestId("landing-title")).toBeVisible();
for (const path of ["/about-us", "/privacy-policy", "/guest/home", "/guest/book/wash"]) {
await gotoHealthyRoute(page, path);
}
await guards.expectHealthy();
guards.dispose();
});
test("auth routes render and protected routes redirect when unauthenticated", async ({ page }) => {
const guards = attachPageHealthGuards(page, LOCAL_PROD_BASE_URL);
await mockApi(page, {
authenticated: false,
selfServe: true,
});
await gotoHealthyRoute(page, "/login");
await expect(page.getByTestId("login-submit")).toBeVisible();
await gotoHealthyRoute(page, "/login/driver");
await expect(page.locator('button[id="subuser-login-button"]')).toBeVisible();
await gotoHealthyRoute(page, "/admin/login");
await expect(page.locator('button[id="operator_login_button"]')).toBeVisible();
for (const path of ["/user", "/admin/12/modules/pos", "/superuser"]) {
await page.goto(path);
await settlePage(page);
await expect(page).toHaveURL(LOGIN_URL);
await expect(page.getByTestId("login-submit")).toBeVisible();
}
await guards.expectHealthy();
guards.dispose();
});
test("seeded user flow reaches dashboard, profile, and bookings", async ({ page }) => {
const guards = attachPageHealthGuards(page, LOCAL_PROD_BASE_URL);
await mockApi(page, {
authenticated: true,
permissions: ["user"],
sessionData: {
display_name: "Release User",
},
});
await loginAsUser(page, {
customerNumber: "release-user",
password: "release-password",
twoFactorAuthentication: false,
});
await expect(page.locator("#book-wash-button")).toBeVisible();
await expect(page.locator("#download-invoices-button")).toBeVisible();
await gotoHealthyRoute(page, "/user/profile");
await expect(page.locator(".card-header").first()).toBeVisible();
await gotoHealthyRoute(page, "/user/bookings");
await expect(page.locator(".title").first()).toBeVisible();
await guards.expectHealthy();
guards.dispose();
});
test("seeded department admin flow renders the POS shell", async ({ page }) => {
const guards = attachPageHealthGuards(page, LOCAL_PROD_BASE_URL);
await seedAuthenticatedRole(page, {
token: "release-admin-token",
permissions: POS_PERMISSIONS,
sessionData: {
display_name: "Release Admin",
},
pos: createPosFixture(),
});
await gotoHealthyRoute(page, "/admin/12/modules/pos");
await expectOneVisible([page.getByTestId("pos-step-1"), page.getByTestId("pos-mobile-step-1-shell")]);
await guards.expectHealthy();
guards.dispose();
});
test("seeded superuser flow renders the vehicles page", async ({ page }) => {
const guards = attachPageHealthGuards(page, LOCAL_PROD_BASE_URL);
await seedAuthenticatedRole(page, {
token: "release-superuser-token",
permissions: ["superuser", "user"],
sessionData: {
display_name: "Release Superuser",
},
});
await gotoHealthyRoute(page, "/superuser/vehicles");
await expect(page.locator("h2.title").first()).toBeVisible();
await expect(page.locator("body")).toContainText(/registrerede/i);
await expect(page.locator("body")).not.toContainText(/Order ID is required/i);
await guards.expectHealthy();
guards.dispose();
});
});
});