e2e/snap-negative.spec.ts
Linked repository file from this build.
let importedReviewKey: string;
import { fixtureReviewKey } from "../src/programs/snap-negative/fixture-key";
import { appendDemoFixture, resetDemoFixture } from "./demo-fixture";
import { expect, test, type APIRequestContext, type Page } from "@playwright/test";
import path from "node:path";
import type { ReviewCommand } from "../src/features/reviews/commands";
import { demoActor } from "../src/lib/auth/roster";
import type { Actor } from "../src/features/reviews/types";
import { PEC_ROUTING_PENDING } from "../src/features/reviews/workflow";
import {
completedReviewAnswers,
demoScenarioTemplate,
DEMO_REVIEW_NUMBER,
} from "../src/programs/snap-negative/seed";
import { enterMoney } from "./money-input";
test.use({ viewport: { width: 1280, height: 800 } });
const examiner = demoActor("examiner");
const supervisor = demoActor("supervisor");
const pec = demoActor("pec");
// Keep import/persistence scenarios independent of terminal reviews in the FFY baseline.
async function importFixture(request: APIRequestContext) {
const files = {
closedSuspended: (
await (await request.get("/fixtures/snap-negative/closed-suspended.txt")).text()
)
.replaceAll("60002", "61999")
.replaceAll("|102|HBG", "|101|HBG"),
rejected: await (await request.get("/fixtures/snap-negative/rejected.txt")).text(),
};
const headers = { "x-qc-test-staff": "401" };
const versions = await (await request.get("/api/reviews", { headers })).json();
const current = versions.find(
(row: { reviewNumber: string; sampleMonth: string }) =>
row.reviewNumber === "61999" && row.sampleMonth === "2026-04",
);
const response = await request.post("/api/imports/snap-negative", {
headers,
data: {
files,
identity: { program: "SNAP", fiscalYear: 2026, reviewNumber: "61999" },
expectedVersion: current?.version ?? null,
requestId: crypto.randomUUID(),
},
});
expect(response.ok(), await response.text()).toBe(true);
importedReviewKey = (await response.json()).review.id;
return files;
}
async function loadReview(request: APIRequestContext, reviewNumber = DEMO_REVIEW_NUMBER) {
const response = await request.get(
`/api/reviews/${reviewNumber === "61999" ? importedReviewKey : fixtureReviewKey(reviewNumber)}`,
);
expect(response.ok()).toBeTruthy();
return response.json();
}
async function resetDemoSeed(request: APIRequestContext) {
await resetDemoFixture();
for (let attempt = 0; attempt < 3; attempt++) {
const initial = await loadReview(request);
const response = await request.post(`/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, {
data: {
version: initial.version,
requestId: crypto.randomUUID(),
commands: [
{
id: crypto.randomUUID(),
command: { type: "reset_demo" },
},
],
},
});
if (response.ok()) return response.json();
if (response.status() !== 409 || attempt === 2) {
expect(response.ok(), await response.text()).toBeTruthy();
}
}
throw new Error("Unable to reset demo seed.");
}
async function postCommands(
request: APIRequestContext,
reviewNumber: string,
version: number,
commands: ReviewCommand[],
actor: Actor,
) {
const response = await request.post(
`/api/reviews/${reviewNumber === "61999" ? importedReviewKey : fixtureReviewKey(reviewNumber)}`,
{
headers: { "x-qc-test-staff": actor.staffId! },
data: {
version,
requestId: crypto.randomUUID(),
commands: commands.map((command) => ({ id: crypto.randomUUID(), command })),
},
},
);
return { response, data: await response.json() };
}
async function runCommands(
request: APIRequestContext,
reviewNumber: string,
commands: ReviewCommand[],
actor: Actor,
) {
let stored = await loadReview(request, reviewNumber);
for (const command of commands) {
const { response, data } = await postCommands(
request,
reviewNumber,
stored.version,
[command],
actor,
);
expect(response.ok(), JSON.stringify(data)).toBeTruthy();
stored = data;
}
return stored;
}
async function seedReadyForSubmit(
request: APIRequestContext,
patch: Parameters<typeof completedReviewAnswers>[0] = {},
outcome: "clean" | "error" | "drop" = "error",
) {
await resetDemoSeed(request);
return runCommands(
request,
DEMO_REVIEW_NUMBER,
[
{ type: "scenario", scenario: "eligibility", value: demoScenarioTemplate(5000) },
{ type: "scenario", scenario: "compI", value: demoScenarioTemplate(1800) },
{ type: "scenario", scenario: "compII", value: demoScenarioTemplate(2300) },
{
type: "answers",
value: completedReviewAnswers({
...(outcome === "clean"
? {
finding: "1",
recordedReasonAccuracy: "1",
noticeReasonAccuracy: "11",
noticeClearUnderstandable: "1",
narrative: "Verification supports the negative action.",
}
: {}),
...patch,
}),
},
{ type: "apply_final" },
{ type: "outcome", value: outcome },
...(outcome === "drop"
? [{ type: "drop_kind" as const, value: "not_subject_to_review" as const }]
: []),
],
examiner,
);
}
async function seedSubmitted(
request: APIRequestContext,
patch: Parameters<typeof completedReviewAnswers>[0] = {},
outcome: "clean" | "error" | "drop" = "error",
) {
const ready = await seedReadyForSubmit(request, patch, outcome);
const { response, data } = await postCommands(
request,
DEMO_REVIEW_NUMBER,
ready.version,
[{ type: "transition", action: "submit", note: "" }],
examiner,
);
expect(response.ok()).toBeTruthy();
return data;
}
/** Historical PEC cases remain actionable while new non-drop routing awaits management. */
async function seedHistoricPec(request: APIRequestContext) {
const stored = await loadReview(request);
return appendDemoFixture({
...stored.review,
state: "awaiting_pec_approval",
supervisorApproved: { actor: supervisor, at: new Date().toISOString() },
});
}
/** Right after a navigation the first click can land before the select is ready, so retry the open. */
async function chooseRole(page: Page, label: string) {
const trigger = page.locator("#demo-role");
const option = page.getByRole("option", { name: label, exact: true });
await expect(async () => {
if ((await trigger.getAttribute("aria-expanded")) !== "true") await trigger.click();
await expect(option).toBeVisible({ timeout: 1000 });
}).toPass();
await option.click();
}
async function chooseCodedField(page: Page, fieldId: string, optionLabel: string) {
await page.locator(`#${fieldId}`).click();
await page.getByRole("option", { name: optionLabel, exact: true }).click();
}
async function expectNoHorizontalOverflow(page: Page) {
const overflow = await page.evaluate(() => ({
document: document.documentElement.scrollWidth > document.documentElement.clientWidth,
body: document.body.scrollWidth > document.body.clientWidth,
}));
expect(overflow.document).toBe(false);
expect(overflow.body).toBe(false);
}
async function expectSaved(page: Page) {
await expect(page.getByRole("status").first()).toContainText(/^Saved /, {
timeout: 15_000,
});
}
test.beforeEach(async ({ request }, testInfo) => {
if (
testInfo.title.includes("intake") ||
testInfo.title.includes("unavailable") ||
testInfo.title.includes("workflow terminals")
) {
return;
}
await resetDemoSeed(request);
});
test("workspace header stays visible at 1280×800 without horizontal overflow", async ({ page }) => {
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await expect(page.getByRole("heading", { name: DEMO_REVIEW_NUMBER })).toBeVisible();
await expect(
page.getByRole("region", { name: "Identifying Information (II)", exact: true }),
).toBeVisible();
await expect(page.getByRole("button", { name: "Save review", exact: true })).toBeVisible();
await expect(page.getByRole("button", { name: "Save & Submit", exact: true })).toBeVisible();
await expectNoHorizontalOverflow(page);
const general = await page
.getByRole("region", { name: "Identifying Information (II)", exact: true })
.boundingBox();
const tabs = await page.getByRole("tablist").boundingBox();
expect(general).not.toBeNull();
expect(tabs).not.toBeNull();
expect(general!.x).toBeLessThan(tabs!.x);
await page.getByRole("tab", { name: "Computation", exact: true }).click();
await expect(page.getByRole("button", { name: /Apply Final Results/ })).toBeVisible();
await expectNoHorizontalOverflow(page);
await page.setViewportSize({ width: 1280, height: 720 });
await expect(page.getByRole("heading", { name: DEMO_REVIEW_NUMBER })).toBeVisible();
await expect(
page.getByRole("region", { name: "Identifying Information (II)", exact: true }),
).toBeVisible();
await expect(page.getByRole("tab", { name: "Computation", exact: true })).toBeVisible();
await expectNoHorizontalOverflow(page);
});
test("required coded fields block Save & Submit until disposition and contact codes are set", async ({
page,
}) => {
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await page.getByRole("tab", { name: "Review", exact: true }).click();
await page.getByRole("button", { name: "Save & Submit", exact: true }).click();
await expect(page.getByRole("region", { name: "Confirm finish action" })).toBeVisible();
await expect(
page
.getByRole("region", { name: "Confirm finish action" })
.getByText(/Disposition of Review is required/),
).toBeVisible();
await chooseCodedField(page, "disposition", "1 — Review completed");
const confirm = page.getByRole("region", { name: "Confirm finish action" });
await expect(confirm.getByText(/Collateral \/ Household Contact is required/)).toBeVisible();
await chooseCodedField(page, "contactResponse", "03 — Phone to household");
await chooseCodedField(page, "actionInitiatedBy", "04 — Application");
await expect(confirm.getByText(/Finding is required/)).toBeVisible();
});
test("computation grid keeps unsaved Comp I drafts out of Apply Final until column save", async ({
page,
request,
}) => {
await seedReadyForSubmit(request);
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await page.getByRole("tab", { name: "Computation", exact: true }).click();
const incomeIds = await page
.locator("[id*='-income-']")
.evaluateAll((elements) => elements.map((element) => element.id));
expect(new Set(incomeIds).size).toBe(incomeIds.length);
const dependentCare = page.locator('[id*="compI-dependentCareCents"]').first();
await enterMoney(dependentCare, "125.00");
await dependentCare.blur();
await expect(page.getByText("Unsaved draft").first()).toBeVisible();
await page.getByRole("button", { name: /Apply Final Results/ }).click();
await expect(page.getByRole("alert").filter({ hasText: /Save.*draft|unsaved/i })).toBeVisible();
await page.getByRole("button", { name: /Save Comp I column/ }).click();
await expectSaved(page);
await expect(page.getByText("Unsaved draft")).toHaveCount(0);
await page.getByRole("button", { name: /Apply Final Results/ }).click();
await expectSaved(page);
await expect(page.getByText(/Source: Comp I{1,2}/)).toBeVisible();
});
test("Save & Submit confirm persists tab edits and its action note", async ({ page, request }) => {
await seedReadyForSubmit(request);
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await page.getByRole("tab", { name: "Review", exact: true }).click();
await page.locator("#narrative").fill("E2E narrative before submit.");
await page.getByRole("tab", { name: "Household", exact: true }).click();
await page.locator("#client-name").fill("Taylor Brooks (edited pre-submit)");
await page.getByRole("tab", { name: "Activity", exact: true }).click();
await page.getByRole("tab", { name: "Review", exact: true }).click();
await page.getByRole("button", { name: "Save & Submit", exact: true }).click();
await expect(page.getByRole("region", { name: "Confirm finish action" })).toBeVisible();
await page.locator("#finish-note").fill("Note captured before submit confirm.");
await page.getByRole("button", { name: "Confirm submit", exact: true }).click();
await expect(page.getByText("Awaiting supervisor", { exact: true }).first()).toBeVisible();
await expectSaved(page);
await page.reload();
await expect(page.locator("#client-name")).toHaveValue("Taylor Brooks (edited pre-submit)");
await page.getByRole("tab", { name: "Activity", exact: true }).click();
await expect(
page.getByText("Note captured before submit confirm.", { exact: true }),
).toBeVisible();
await page.getByRole("tab", { name: "Review", exact: true }).click();
await expect(page.locator("#narrative")).toHaveValue("E2E narrative before submit.");
});
test("supervisor approval stays blocked until stored findings are refused", async ({
page,
request,
}) => {
await seedSubmitted(request, { finding: "1", recordedReasonAccuracy: "2" });
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await chooseRole(page, "Supervisor");
await page.getByRole("button", { name: "Approve", exact: true }).click();
await expect(
page
.getByRole("region", { name: "Confirm finish action" })
.getByText(/Resolve or refuse open edit-check findings/),
).toBeVisible();
let stored = await loadReview(request);
for (const finding of stored.review.validation!.findings) {
stored = await runCommands(
request,
DEMO_REVIEW_NUMBER,
[
{
type: "refuse_finding",
findingId: finding.id,
reason: "Collateral supports the recorded reason.",
},
],
supervisor,
);
}
await page.reload();
await chooseRole(page, "Supervisor");
await page.getByRole("button", { name: "Approve", exact: true }).click();
const confirmation = page.getByRole("region", { name: "Confirm finish action" });
await expect(confirmation.getByText(/Resolve or refuse open edit-check findings/)).toHaveCount(0);
await expect(confirmation.getByText(PEC_ROUTING_PENDING, { exact: true })).toBeVisible();
await expect(
confirmation.getByRole("button", { name: "Confirm approve", exact: true }),
).toBeDisabled();
expect((await loadReview(request)).review.state).toBe("awaiting_review");
});
test("supervisors cannot edit submitted facts and refusal survives approval checks", async ({
page,
request,
}) => {
await seedSubmitted(request, { finding: "1", recordedReasonAccuracy: "2" });
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await chooseRole(page, "Supervisor");
await page.getByRole("tab", { name: "Review", exact: true }).click();
await expect(page.locator("#finding")).toBeDisabled();
await expect(page.locator("#narrative")).toHaveAttribute("readonly", "");
await page
.getByLabel("Refuse reason", { exact: true })
.fill("Collateral verification supports this finding despite the recorded code.");
await page.getByRole("button", { name: "Refuse finding", exact: true }).click();
await page.getByRole("button", { name: "Save review", exact: true }).click();
await expectSaved(page);
await page.getByRole("button", { name: "Approve", exact: true }).click();
const confirmation = page.getByRole("region", { name: "Confirm finish action" });
await expect(confirmation.getByText(PEC_ROUTING_PENDING, { exact: true })).toBeVisible();
await expect(
confirmation.getByRole("button", { name: "Confirm approve", exact: true }),
).toBeDisabled();
const stored = await loadReview(request);
expect(stored.review.validation.revision).toBe(stored.review.revision);
expect(stored.review.validation.findings[0].refused.reason).toBe(
"Collateral verification supports this finding despite the recorded code.",
);
});
test("clean approval waits for the management-approved routing map", async ({ page, request }) => {
const cleanSubmitted = await seedSubmitted(request, {}, "clean");
for (const finding of cleanSubmitted.review.validation!.findings) {
await runCommands(
request,
DEMO_REVIEW_NUMBER,
[{ type: "refuse_finding", findingId: finding.id, reason: "Documented for clean path." }],
supervisor,
);
}
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await chooseRole(page, "Supervisor");
await page.getByRole("button", { name: "Approve", exact: true }).click();
const confirmation = page.getByRole("region", { name: "Confirm finish action" });
await expect(confirmation.getByText(PEC_ROUTING_PENDING, { exact: true })).toBeVisible();
await expect(
confirmation.getByRole("button", { name: "Confirm approve", exact: true }),
).toBeDisabled();
await expect(page.getByLabel("Skip PEC routing (explicit supervisor override)")).toHaveCount(0);
expect((await loadReview(request)).review.state).toBe("awaiting_review");
});
test("PEC approval requires notes for deny and conditional decisions", async ({
page,
request,
}) => {
await resetDemoSeed(request);
const errorSubmitted = await seedSubmitted(request, {}, "error");
for (const finding of errorSubmitted.review.validation!.findings) {
await runCommands(
request,
DEMO_REVIEW_NUMBER,
[{ type: "refuse_finding", findingId: finding.id, reason: "Ready for PEC." }],
supervisor,
);
}
let stored = await seedHistoricPec(request);
expect(stored.review.state).toBe("awaiting_pec_approval");
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await chooseRole(page, "PEC stakeholder");
await page.getByRole("button", { name: "Approve", exact: true }).click();
await page.getByRole("button", { name: "Deny", exact: true }).click();
await expect(page.getByRole("button", { name: "Confirm deny", exact: true })).toBeDisabled();
await page.getByRole("button", { name: "Conditional approval", exact: true }).click();
await expect(
page.getByRole("button", { name: "Confirm conditional approval", exact: true }),
).toBeDisabled();
await page.getByRole("button", { name: "Approve", exact: true }).click();
await page.locator("#policy-note").fill("Policy aligns with the demo error.");
await page.getByRole("button", { name: "Confirm approve", exact: true }).click();
await expect(page.getByText("Awaiting manager", { exact: true }).first()).toBeVisible();
await expectSaved(page);
});
test("Drop approval closes the review and locks examiner edits", async ({ page, request }) => {
await seedReadyForSubmit(request, {}, "drop");
await runCommands(
request,
DEMO_REVIEW_NUMBER,
[
{
type: "transition",
action: "submit",
note: "Insufficient verification for a completed negative review.",
},
],
examiner,
);
let stored = await loadReview(request);
expect(stored.review.validation).toBeUndefined();
stored = await runCommands(
request,
DEMO_REVIEW_NUMBER,
[{ type: "transition", action: "approve", note: "" }],
supervisor,
);
expect(stored.review.state).toBe("awaiting_manager");
stored = await runCommands(
request,
DEMO_REVIEW_NUMBER,
[{ type: "transition", action: "approve", note: "" }],
demoActor("program_manager"),
);
expect(stored.review.state).toBe("dropped");
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await expect(page.getByText("Dropped", { exact: true }).first()).toBeVisible();
await expect(page.locator("#client-name")).toHaveAttribute("readonly", "");
await expect(page.getByRole("button", { name: "Save & Submit", exact: true })).toHaveCount(0);
});
test("PEC conditional approval preserves read-only conditions for admin", async ({
page,
request,
}) => {
await resetDemoSeed(request);
await seedSubmitted(request, {}, "error");
let stored = await loadReview(request);
for (const finding of stored.review.validation!.findings) {
await runCommands(
request,
DEMO_REVIEW_NUMBER,
[{ type: "refuse_finding", findingId: finding.id, reason: "Route to PEC." }],
supervisor,
);
}
stored = await seedHistoricPec(request);
stored = await runCommands(
request,
DEMO_REVIEW_NUMBER,
[
{
type: "policy_decision",
decision: "conditional",
policyNote: "Corrective action memo due.",
},
],
pec,
);
expect(stored.review.state).toBe("awaiting_pec_approval");
expect(stored.review.conditionalNotes).toContain("Corrective action memo due.");
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await expect(page.getByText(/PEC conditional/)).toBeVisible();
await chooseRole(page, "Admin");
await page.getByRole("tab", { name: "Activity", exact: true }).click();
await expect(
page.getByText("Policy note: Corrective action memo due.", { exact: true }),
).toBeVisible();
});
test("PEC denial returns the review for changes", async ({ page, request }) => {
await resetDemoSeed(request);
await seedSubmitted(request, {}, "error");
let stored = await loadReview(request);
for (const finding of stored.review.validation!.findings) {
await runCommands(
request,
DEMO_REVIEW_NUMBER,
[{ type: "refuse_finding", findingId: finding.id, reason: "Route to PEC." }],
supervisor,
);
}
stored = await seedHistoricPec(request);
stored = await runCommands(
request,
DEMO_REVIEW_NUMBER,
[
{
type: "policy_decision",
decision: "deny",
policyNote: "Return for additional verification.",
},
],
pec,
);
expect(stored.review.state).toBe("needs_changes");
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await expect(page.getByText("Needs Changes", { exact: true }).first()).toBeVisible();
});
test("PDF evidence previews and edited details survive reload", async ({ page, request }) => {
await seedReadyForSubmit(request);
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await page.getByRole("tab", { name: "Documents", exact: true }).click();
await expect(
page.getByRole("button", { name: "Choose PDF to attach", exact: true }),
).toBeDisabled();
await page.locator("#doc-name").fill("Denial notice");
await page
.locator("#doc-description")
.fill("Shows the notice sent to the household and its stated denial reason.");
await page.locator('input[type="file"]').setInputFiles(path.resolve("public/demo-evidence.pdf"));
// The form clears only after the document and its metadata finish saving.
await expect(page.locator("#doc-name")).toHaveValue("");
await expect(page.getByText("Alex Examiner", { exact: false }).last()).toBeVisible();
const preview = page.getByRole("link", { name: "Preview", exact: true });
await expect(preview).toHaveAttribute("href", /^\/api\/documents\//);
const previewUrl = await preview.getAttribute("href");
await expectSaved(page);
await expect
.poll(() =>
page.evaluate(async (url) => {
const response = await fetch(url!);
return response.ok && (await response.text()).startsWith("%PDF-");
}, previewUrl),
)
.toBe(true);
await page.getByRole("button", { name: "Edit details", exact: true }).click();
await page.locator('[id^="doc-name-"]').fill("Household denial notice");
await page
.locator('[id^="doc-purpose-"]')
.fill("Documents the household notice date and the reason reviewed against the case record.");
await page.getByRole("button", { name: "Save details", exact: true }).click();
await expect(page.getByRole("button", { name: "Edit details", exact: true })).toBeVisible();
await expectSaved(page);
await page.reload();
await page.getByRole("tab", { name: "Documents", exact: true }).click();
await expect(
page.getByRole("heading", { name: "Household denial notice", exact: true }),
).toBeVisible();
await expect(
page.getByText(
"Documents the household notice date and the reason reviewed against the case record.",
{ exact: true },
),
).toBeVisible();
await expect(page.getByRole("link", { name: "Preview", exact: true })).toHaveAttribute(
"href",
previewUrl!,
);
});
test("owned review appointment and uploaded PDF persist from the workspace", async ({
page,
request,
}) => {
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await page.locator("#appointment").fill("2026-09-10T14:30");
await page.locator("#appointment").blur();
await page.getByRole("button", { name: "Save review", exact: true }).click();
await expectSaved(page);
await page.getByRole("tab", { name: "Documents", exact: true }).click();
await expect(
page.getByRole("button", { name: "Choose PDF to attach", exact: true }),
).toBeDisabled();
await page.locator("#doc-name").fill("Denial notice");
await page
.locator("#doc-description")
.fill("Shows the notice sent to the household and its stated denial reason.");
await page.locator('input[type="file"]').setInputFiles(path.resolve("public/demo-evidence.pdf"));
// The form clears only after the document and its metadata finish saving.
await expect(page.locator("#doc-name")).toHaveValue("");
await expect(page.getByRole("link", { name: "Preview", exact: true })).toBeVisible();
await expectSaved(page);
const stored = await loadReview(request);
expect(stored.review.appointment).toBe("2026-09-10T14:30");
expect(stored.review.documents.some((doc: { storageKey: string }) => doc.storageKey)).toBe(true);
});
test("synthetic intake promotes and refreshes a durable live case without disturbing the demo seed", async ({
page,
request,
}) => {
test.setTimeout(120_000);
const files = await importFixture(request);
await page.route("**/fixtures/snap-negative/closed-suspended.txt", (route) =>
route.fulfill({ body: files.closedSuspended, contentType: "text/plain" }),
);
const demoBefore = await loadReview(request);
await page
.context()
.addCookies([{ name: "qc-test-staff", value: "401", url: "http://localhost:3001" }]);
await page.goto("/imports");
await page.getByRole("button", { name: "Load synthetic files", exact: true }).click();
await page.getByRole("button", { name: "Preview reviews", exact: true }).click();
await expect(page.getByText("Sample batch: 4 reviews")).toBeVisible();
await page.getByRole("button", { name: /^Promote 61999$|^Refresh 61999$/ }).click();
await expect(page).toHaveURL(new RegExp(`/reviews/${importedReviewKey}$`));
await chooseRole(page, "Examiner");
await page.getByRole("tab", { name: "Household", exact: true }).click();
await page.getByRole("button", { name: "Add member", exact: true }).click();
await page.getByRole("button", { name: "Save review", exact: true }).click();
await expectSaved(page);
await page.reload();
await page.getByRole("tab", { name: "Household", exact: true }).click();
const stored = await (
await request.get(`/api/reviews/${importedReviewKey}`, {
headers: { "x-qc-test-staff": "201" },
})
).json();
expect(stored.review.facts.members).toHaveLength(1);
expect(stored.review.facts.paCap).toBeUndefined();
expect(stored.review.lineage[0].sourceSystem).toBe("sample_delim");
expect(stored.review.intake.sources.rejected).toContain("SYNTHETIC");
await chooseRole(page, "Admin");
await page.getByRole("main").getByRole("link", { name: "Return", exact: true }).click();
await expect(page).toHaveURL(/\/imports/);
await expect(page.getByRole("heading", { name: "Load sample delimited files" })).toBeVisible();
await page.getByRole("textbox", { name: "Search reviews", exact: true }).fill("61999");
await page.getByRole("link", { name: /^See all \d+ results?$/ }).click();
await expect(page.getByRole("table", { name: "Search results" })).toContainText("Casey Walker");
const demoAfter = await loadReview(request);
expect(demoAfter.version).toBe(demoBefore.version);
});
test("server rejects forged PEC edits, malformed commands and stale writes", async ({
request,
}) => {
const initial = await loadReview(request);
const body = (command: unknown, version = initial.version) => ({
version,
requestId: crypto.randomUUID(),
commands: [
{
command,
id: crypto.randomUUID(),
},
],
});
const denied = await request.post(`/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, {
headers: { "x-qc-test-staff": "601" },
data: body({ type: "outcome", value: "clean" }),
});
expect(denied.status()).toBe(400);
expect((await denied.json()).error).toMatch(/PEC|not editable|cannot/i);
const malformed = await request.post(`/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, {
data: body({ type: "identity", value: { state: "released_to_reporting" } }),
});
expect(malformed.status()).toBe(400);
const note = await request.post(`/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, {
data: body({ type: "note", body: "Synthetic server guard verification" }),
});
expect(note.status()).toBe(200);
const stale = await request.post(`/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, {
data: body({ type: "note", body: "Stale write must not save" }),
});
expect(stale.status()).toBe(409);
const latest = await loadReview(request);
expect(
latest.review.notes.some(
(entry: { body: string }) => entry.body === "Stale write must not save",
),
).toBe(false);
});
test("field save retries failures and drains edits typed during a save before switching cases", async ({
page,
request,
}) => {
test.setTimeout(120_000);
await importFixture(request);
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await chooseRole(page, "Examiner");
await page.getByRole("tab", { name: "Review", exact: true }).click();
let posts = 0;
await page.route(`**/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, async (route) => {
if (route.request().method() !== "POST") {
await route.continue();
return;
}
posts++;
if (posts === 1) {
await route.fulfill({
status: 503,
contentType: "application/json",
body: JSON.stringify({ error: "Synthetic temporary save failure" }),
});
return;
}
await route.continue();
});
await page.locator("#narrative").fill("Synthetic retry preserved");
await page.locator("#narrative").blur();
await page.getByRole("button", { name: "Save review", exact: true }).click();
await expect(page.getByRole("status").first()).toContainText(/Save failed|Saving/, {
timeout: 10_000,
});
await page.getByRole("button", { name: "Save failed. Retry save", exact: true }).click();
await expectSaved(page);
await page.unroute(`**/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
let release: () => void = () => {};
const gate = new Promise<void>((resolve) => {
release = resolve;
});
let blocked = false;
await page.route(`**/api/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`, async (route) => {
if (route.request().method() === "POST" && !blocked) {
blocked = true;
await gate;
}
await route.continue();
});
try {
await page.locator("#narrative").fill("First in flight");
await page.locator("#narrative").blur();
await page.getByRole("button", { name: "Save review", exact: true }).click();
await expect.poll(() => blocked, { timeout: 10_000 }).toBe(true);
await page.locator("#narrative").fill("Second must drain before navigation");
await page.getByRole("textbox", { name: "Search reviews", exact: true }).fill("61999");
await page.getByRole("link", { name: /^See all \d+ results?$/ }).click();
await expect(page).toHaveURL(/\/reviews\/aa1635c0-c99d-5f12-8f26-54d3f23bf13d$/);
release();
await expect(page).toHaveURL(/\/search\?/);
await page.getByRole("link", { name: "61999", exact: true }).click();
await expect(page).toHaveURL(new RegExp(`/reviews/${importedReviewKey}$`));
await expect(page.locator("#client-name")).toHaveValue("Casey Walker");
const previous = await loadReview(request);
expect(previous.review.facts.answers.narrative).toBe("Second must drain before navigation");
const selected = await (
await request.get(`/api/reviews/${importedReviewKey}`, {
headers: { "x-qc-test-staff": "201" },
})
).json();
expect(selected.review.facts.answers.narrative).not.toBe("Second must drain before navigation");
} finally {
release();
}
});
test("docs, intake and dashboard render while review database requests are unavailable", async ({
page,
}) => {
await page.route("**/api/reviews**", (route) =>
route.fulfill({
status: 503,
contentType: "application/json",
body: JSON.stringify({ error: "Synthetic database outage" }),
}),
);
await page.goto("/docs");
await expect(page.getByRole("heading", { name: "Map of the repo", exact: true })).toBeVisible();
await page
.context()
.addCookies([{ name: "qc-test-staff", value: "401", url: "http://localhost:3001" }]);
await page.goto("/imports");
await expect(
page.getByRole("button", { name: "Load synthetic files", exact: true }),
).toBeVisible();
await page.getByRole("button", { name: "Load synthetic files", exact: true }).click();
await page.goto("/dashboard");
await expect(page.getByRole("heading", { name: "Home", exact: true })).toBeVisible();
});
test("typing coalesces into one narrative command when explicitly saved", async ({
page,
request,
}) => {
await page.goto(`/reviews/${fixtureReviewKey(DEMO_REVIEW_NUMBER)}`);
await chooseRole(page, "Examiner");
await page.getByRole("tab", { name: "Review", exact: true }).click();
const before = await loadReview(request);
await page.clock.install();
const narrative = page.locator("#narrative");
await narrative.fill("");
await narrative.pressSequentially("Synthetic draft", { delay: 5 });
await expect(page.getByRole("status").first()).toHaveText("Unsaved changes");
await narrative.blur();
await page.clock.fastForward(60_000);
expect((await loadReview(request)).version).toBe(before.version);
await page.getByRole("button", { name: "Save review", exact: true }).click();
await expectSaved(page);
const after = await loadReview(request);
expect(after.review.facts.answers.narrative).toBe("Synthetic draft");
expect(after.review.revision).toBe(before.review.revision + 1);
expect(after.review.activity.length).toBe(before.review.activity.length + 1);
});