import { expect, test, type Page, type Route } from "@playwright/test"; const FROZEN_NOW = "2026-08-19T15:00:00.000Z"; const TEST_USER = { token: "wo-number-sh-placeholder-e2e-token", expiration: "2030-01-01T00:00:00.000Z", email: "admin@seahavenind.com", userRoles: "Admin", phoneNumber: "5551234567", fullname: "Work Order E2E Admin", id: "1", }; async function fulfillJson(route: Route, body: unknown, status = 200) { await route.fulfill({ status, contentType: "application/json", body: JSON.stringify(body) }); } async function hideQueryDevtools(page: Page) { await page.addStyleTag({ content: ".tsqd-parent-container { display: none !important; pointer-events: none !important; }", }); await page.locator(".tsqd-parent-container").evaluateAll((nodes) => { for (const node of nodes) { node.remove(); } }); } const REAL_ROW = { id: 1000, woNumber: "12345678901", workOrderType: 2, siteCode: "DAL1", lifecycleStatusLabel: "Scheduled", scheduledDate: "2026-08-19", dispatcherId: "1", dispatcherName: "Pat Dispatcher", pm: "HVAC", }; async function mockBoard(page: Page, patches: unknown[]) { await page.route( (url) => url.pathname.startsWith("/api/"), async (route) => { const request = route.request(); const url = request.url(); if (request.method() !== "GET") { patches.push({ url, body: request.postDataJSON() }); await fulfillJson(route, {}, 500); return; } if (url.includes("workorders/board/search")) { await fulfillJson(route, { items: [REAL_ROW], totalCount: 1, page: 0, pageSize: 50 }); return; } if (url.includes("workorders/board")) { await fulfillJson(route, { weekStart: "2026-08-17", weekEnd: "2026-08-21", counts: { returned: 1, total: 1 }, unscheduled: [], scheduled: [REAL_ROW], }); return; } await fulfillJson(route, { data: [], items: [] }); }, ); } test.describe("inline WO number SH placeholder", () => { test.setTimeout(60_000); test.beforeEach(async ({ page }) => { await page.clock.install({ time: new Date(FROZEN_NOW) }); await page.clock.resume(); await page.addInitScript((user) => { localStorage.setItem("auth", JSON.stringify(user)); }, TEST_USER); }); test("keeps a typed SH number on a new inline row and blocks downgrading a saved real number", async ({ page, }) => { const mutations: unknown[] = []; await mockBoard(page, mutations); await page.goto("/workorders"); await hideQueryDevtools(page); await expect(page.getByRole("heading", { name: "Work Orders" })).toBeVisible({ timeout: 20_000, }); await expect(page.getByText("12345678901").first()).toBeVisible(); await page .getByRole("button", { name: /Add WO/ }) .first() .click(); await page .getByText(/^Insert WO #/) .first() .click(); const draftInput = page.getByLabel("Work order number"); await draftInput.fill("SH00001"); await draftInput.press("Enter"); await expect(draftInput).toHaveCount(0); await expect(page.getByText("SH00001", { exact: true })).toBeVisible(); await expect(page.getByText(/must be 11 digits/)).toHaveCount(0); await page.getByText("12345678901", { exact: true }).first().click(); const savedInput = page.getByLabel("Work order number"); await savedInput.fill("SH00009"); await savedInput.press("Enter"); await expect( page.getByText("Cannot replace an APM work order number with an internal number"), ).toBeVisible(); await expect(page.getByText("12345678901", { exact: true }).first()).toBeVisible(); expect(mutations).toEqual([]); }); });