shoc-frontend-new/e2e/work-orders/board-day-pagination.spec.ts

149 lines
5.5 KiB
TypeScript
Raw Normal View History

import { expect, test, type Page, type Route } from "@playwright/test";
const FROZEN_NOW = "2026-08-19T15:00:00.000Z";
const TEST_USER = {
token: "wo-day-pagination-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) });
}
function boardRow(id: number, woNumber: string, scheduledDate: string) {
return {
id,
woNumber,
workOrderType: 2,
siteCode: woNumber,
lifecycleStatusLabel: "Scheduled",
scheduledDate,
dispatcherId: "1",
dispatcherName: "Pat Dispatcher",
pm: "HVAC",
};
}
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();
}
});
}
async function mockWorkOrderBoard(page: Page) {
const wednesday = Array.from({ length: 60 }, (_, index) =>
boardRow(1000 + index, `WO-${1000 + index}`, "2026-08-19"),
);
const monday = Array.from({ length: 5 }, (_, index) =>
boardRow(2000 + index, `MON-${2000 + index}`, "2026-08-17"),
);
await page.route(
(url) => url.pathname.startsWith("/api/"),
async (route) => {
const url = route.request().url();
if (url.includes("workorders/board/search")) {
const page = Number(new URL(url).searchParams.get("page") ?? "0");
const pageSize = Number(new URL(url).searchParams.get("pageSize") ?? "50");
const items = wednesday.slice(page * pageSize, page * pageSize + pageSize);
await fulfillJson(route, {
items,
totalCount: 1778,
page,
pageSize,
});
return;
}
if (url.includes("workorders/board") && route.request().method() === "GET") {
const weekStart = new URL(url).searchParams.get("weekStart") ?? "2026-08-17";
const scheduled =
weekStart === "2026-08-17" ? [...wednesday, ...monday] : monday.slice(0, 1);
await fulfillJson(route, {
weekStart,
weekEnd: weekStart === "2026-08-17" ? "2026-08-21" : "2026-08-14",
counts: { returned: scheduled.length, total: scheduled.length },
unscheduled: [],
scheduled,
});
return;
}
await fulfillJson(route, { data: [], items: [] });
},
);
}
test.describe("work order per-day pagination (SH-241)", () => {
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));
const style = document.createElement("style");
style.textContent = ".tsqd-parent-container { display: none !important; }";
document.documentElement.appendChild(style);
}, TEST_USER);
await mockWorkOrderBoard(page);
});
test("changes rows-per-page, keeps search pager on advanced filters, and resets on day or week change", async ({
page,
}) => {
const pager = page.getByTestId("wo-day-pagination");
await page.goto("/workorders");
await hideQueryDevtools(page);
await expect(page.getByRole("heading", { name: "Work Orders" })).toBeVisible({
timeout: 20_000,
});
await expect(pager).toBeVisible();
await expect(pager.getByText("Page 1 of 2")).toBeVisible();
await expect(page.getByTestId("wo-day-pagination-next")).toBeEnabled();
await expect(page.getByText("WO-1000").first()).toBeVisible();
await expect(page.getByText("WO-1050")).toHaveCount(0);
await pager.getByLabel("Rows per page").selectOption("25");
await expect(pager.getByText("Page 1 of 3")).toBeVisible();
await expect(page.getByTestId("wo-day-pagination-next")).toBeEnabled();
await expect(page.getByText("WO-1025")).toHaveCount(0);
await hideQueryDevtools(page);
await page.getByTestId("wo-day-pagination-next").click();
await expect(pager.getByText("Page 2 of 3")).toBeVisible();
await expect(page.getByText("WO-1025").first()).toBeVisible();
await expect(page.getByText("WO-1000")).toHaveCount(0);
await page.getByRole("tab", { name: "Mon · 08/17" }).click({ force: true });
await expect(pager.getByText("Page 1 of 1")).toBeVisible();
await expect(page.getByText("MON-2000").first()).toBeVisible();
await page.getByRole("button", { name: "Week 8/17–8/21" }).click({ force: true });
await page.getByRole("button", { name: /Aug 10/ }).click({ force: true });
await expect(page.getByTestId("wo-day-pagination")).toBeVisible();
await expect(page.getByTestId("wo-day-pagination").getByText("Page 1 of")).toBeVisible();
await page.getByRole("button", { name: "Advanced Filters" }).click();
await page.getByRole("button", { name: /Indicators/i }).click();
await page.getByRole("button", { name: "Rescheduled ≥ 2" }).click();
await page.getByRole("button", { name: "Apply filters" }).click();
await expect(pager).toBeVisible();
await expect(pager.getByText("RESULTS · 1778 items")).toBeVisible();
await expect(pager.getByText("Page 1 of 36")).toBeVisible();
await page.getByRole("button", { name: "Clear all" }).click();
await expect(page.getByTestId("wo-day-pagination")).toBeVisible();
});
});