From 7c090571c5ae1387e48f44d51b76db5e1e6a8523 Mon Sep 17 00:00:00 2001 From: Codex Review Integration Date: Wed, 16 Sep 2026 13:20:32 -0300 Subject: [PATCH] test(work-orders): cover wizard vendor company notes journey --- .../wizard-vendor-company-notes.spec.ts | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 e2e/work-orders/wizard-vendor-company-notes.spec.ts diff --git a/e2e/work-orders/wizard-vendor-company-notes.spec.ts b/e2e/work-orders/wizard-vendor-company-notes.spec.ts new file mode 100644 index 00000000..df507616 --- /dev/null +++ b/e2e/work-orders/wizard-vendor-company-notes.spec.ts @@ -0,0 +1,168 @@ +import { expect, test, type Page, type Route } from "@playwright/test"; + +const FROZEN_NOW = "2026-08-19T15:00:00.000Z"; + +const TEST_USER = { + token: "wizard-vendor-notes-e2e-token", + expiration: "2030-01-01T00:00:00.000Z", + email: "admin@seahavenind.com", + userRoles: "Admin", + phoneNumber: "5551234567", + fullname: "Work Order E2E Admin", + id: "1", +}; + +const LOCATIONS = [ + { + id: 10, + name: "STL-01 · St. Louis, MO", + siteCode: "STL-01", + city: "St. Louis", + state: "MO", + code: "STL-01", + }, +]; + +const VENDORS = [ + { + id: 101, + companyName: "Gateway Plumbing", + contactName: "Adam Whyte", + tradeSpecialties: "Plumbing", + address: "1 Market St", + }, +]; + +type Captured = { method: string; path: string; body: unknown }; + +async function fulfillJson(route: Route, body: unknown, status = 200) { + await route.fulfill({ status, contentType: "application/json", body: JSON.stringify(body) }); +} + +async function mockApi(page: Page, captured: Captured[]) { + await page.route( + (url) => url.pathname.startsWith("/api/"), + async (route) => { + const request = route.request(); + const { pathname } = new URL(request.url()); + if (request.method() !== "GET") { + captured.push({ method: request.method(), path: pathname, body: request.postDataJSON() }); + } + if (pathname.endsWith("/workorders/board") && request.method() === "POST") { + await fulfillJson(route, { data: { id: 900, woNumber: "SH00900" } }); + return; + } + if (pathname.endsWith("/vendor-company-roster/55") && request.method() === "PATCH") { + await fulfillJson(route, { + companyId: 55, + rowVersion: "rv-2", + name: "Gateway Plumbing", + notes: "Gate code 4411", + technicians: [], + }); + return; + } + if (pathname.endsWith("/vendor-company-roster") && request.method() === "GET") { + await fulfillJson(route, { + companyId: 55, + rowVersion: "rv-1", + name: "Gateway Plumbing", + notes: "Call before arrival", + technicians: [{ id: 101, contactName: "Adam Whyte", isActive: true }], + }); + return; + } + if (pathname.includes("workorders/board")) { + await fulfillJson(route, { + weekStart: "2026-08-17", + weekEnd: "2026-08-21", + counts: { returned: 0, total: 0 }, + unscheduled: [], + scheduled: [], + items: [], + }); + return; + } + if (pathname.endsWith("/locations/10")) { + await fulfillJson(route, { + data: { + id: 10, + name: "STL-01 · St. Louis, MO", + contact: "Jamie Site", + phone: "3145550100", + zipCode: "63101", + }, + }); + return; + } + if (pathname.includes("/locations/sites") || pathname.includes("/Contact/GetLocations")) { + await fulfillJson(route, { data: LOCATIONS }); + return; + } + if (pathname.toLowerCase().includes("/vendors/dropdown")) { + await fulfillJson(route, { data: VENDORS }); + return; + } + await fulfillJson(route, { data: [], items: [] }); + }, + ); +} + +test.describe("wizard vendor company notes (SH-321)", () => { + test.setTimeout(60_000); + + test("pre-fills the company notes and saves edits to the vendor company on create", async ({ + page, + }) => { + const captured: Captured[] = []; + await page.clock.install({ time: new Date(FROZEN_NOW) }); + await page.clock.resume(); + await page.addInitScript((user) => { + localStorage.setItem("auth", JSON.stringify(user)); + const style = document.createElement("style"); + style.textContent = ".tsqd-parent-container { display: none !important; }"; + document.documentElement.appendChild(style); + }, TEST_USER); + await mockApi(page, captured); + + await page.goto("/workorders"); + await page.getByRole("button", { name: "New WO" }).click(); + await expect(page.getByRole("heading", { name: "Type & schedule" })).toBeVisible({ + timeout: 20_000, + }); + await page.getByRole("button", { name: "Continue" }).click(); + + await page.getByRole("button", { name: /Select site/ }).click(); + await page.getByRole("button", { name: "STL-01 · St. Louis, MO" }).first().click(); + await expect(page.getByRole("button", { name: "Continue" })).toBeEnabled(); + await page.getByRole("button", { name: "Continue" }).click(); + + await page.getByRole("button", { name: /Select technician/ }).click(); + await page + .getByRole("button", { name: /Adam Whyte/ }) + .last() + .first() + .click(); + + const notes = page.getByPlaceholder("Contact preferences, availability, etc."); + await expect(notes).toHaveValue("Call before arrival"); + await notes.fill("Gate code 4411"); + + await page.getByRole("button", { name: /Create/ }).click(); + + await expect + .poll(() => captured.find((c) => c.method === "PATCH")) + .toEqual({ + method: "PATCH", + path: "/api/vendor-company-roster/55", + body: { + rowVersion: "rv-1", + addTechnicians: [], + companyFields: { notes: "Gate code 4411" }, + }, + }); + expect(captured.some((c) => c.method === "POST" && c.path.endsWith("/workorders/board"))).toBe( + true, + ); + }); +});