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

148 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
});
});