e2e/refresh-pagination.spec.ts
Linked repository file from this build.
import { expect, test } from "@playwright/test";
test("catalog requests only the selected page and slim row fields", async ({ page, request }) => {
const headers = { "x-qc-test-staff": "501" };
const first = await (await request.get("/api/catalog", { headers })).json();
const second = await (await request.get("/api/catalog?page=1", { headers })).json();
expect(first.reviews).toHaveLength(10);
expect(second.reviews).toHaveLength(10);
expect(
second.reviews.every(
(row: { reviewKey: string }) =>
!first.reviews.some((other: { reviewKey: string }) => other.reviewKey === row.reviewKey),
),
).toBe(true);
expect(Object.keys(first.reviews[0]).sort()).toEqual(
[
"fiscalYear",
"caseNumber",
"clientName",
"examiner",
"flagged",
"outcome",
"reviewKey",
"reviewNumber",
"routedBy",
"state",
"unread",
"updatedAt",
].sort(),
);
await page
.context()
.addCookies([{ name: "qc-test-staff", value: "501", url: "http://localhost:3001" }]);
await page.goto("/reviews");
const rows = page.getByRole("table", { name: "Reviews in branch" }).locator("tbody tr");
await expect(rows).toHaveCount(10);
await page.getByRole("button", { name: "Next", exact: true }).click();
await expect(page.getByText(/^11–20 of/)).toBeVisible();
await page.getByLabel("Reviews per page").selectOption("5");
await expect(rows).toHaveCount(5);
await expect(page.getByText(/^1–5 of/)).toBeVisible();
await page.getByLabel("Reviews per page").selectOption("25");
await expect(rows).toHaveCount(25);
await expect(page.getByText(/^1–25 of/)).toBeVisible();
});
test("notifications persist across navigation and catalogs refresh every five minutes or on demand", async ({
page,
}) => {
let notifications = 0;
let catalogs = 0;
await page.route("**/api/inbox/events", async (route) => {
notifications++;
await route.fulfill({ json: { events: [], unreadCount: 0 } });
});
page.on("request", (request) => {
if (new URL(request.url()).pathname === "/api/catalog") catalogs++;
});
await page.clock.install();
await page.goto("/dashboard");
await expect(page.locator('main section[aria-busy="false"] h2').first()).toBeVisible();
await expect.poll(() => notifications).toBe(1);
await page.locator('a[href="/reviews"]:visible').first().click();
await expect(page.getByLabel("Reviews per page")).toBeVisible();
expect(notifications).toBe(1);
expect(catalogs).toBe(0);
await page.evaluate(() => {
window.dispatchEvent(new Event("focus"));
document.dispatchEvent(new Event("visibilitychange"));
});
await page.clock.fastForward(290_000);
expect(notifications).toBe(1);
expect(catalogs).toBe(0);
await page.clock.fastForward(10_000);
await expect.poll(() => notifications).toBe(2);
await expect.poll(() => catalogs).toBe(1);
await page.getByRole("button", { name: "Refresh", exact: true }).click();
await expect.poll(() => catalogs).toBe(2);
});
test("catalog refresh clears previously cached folders when the result becomes empty", async ({
page,
}) => {
await page.goto("/reviews");
const folders = page.getByRole("region", { name: "Review folders" });
await expect(folders.getByRole("button").first()).toBeVisible();
await page.route("**/api/catalog?**", async (route) => {
expect(new URL(route.request().url()).searchParams.get("includeBranches")).toBe("true");
await route.fulfill({ json: { reviews: [], branches: [], total: 0 } });
});
await page.getByRole("button", { name: "Refresh", exact: true }).click();
await expect(folders.getByText("No reviews in these categories.")).toBeVisible();
});