Reusable dossier primitives (classification strips, brackets, readouts, provenance chips, notice states) plus server-rendered /operations overview, ledger drill-down, and AAR with permission-gated sections and an authorized reconciliation panel. Realtime refresh is enhancement only. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
58 lines
2.5 KiB
TypeScript
58 lines
2.5 KiB
TypeScript
import { mkdirSync } from "node:fs";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
const SHOT_DIR = ".omo/evidence/screenshots";
|
|
async function shot(page: import("@playwright/test").Page, name: string): Promise<void> {
|
|
mkdirSync(SHOT_DIR, { recursive: true });
|
|
await page.screenshot({ path: `${SHOT_DIR}/${name}.png`, fullPage: true });
|
|
}
|
|
|
|
/**
|
|
* Operations surfaces: role-scoped visibility and failure-state behavior.
|
|
* NOTE: these tests exercise the real dev server and are run in the final
|
|
* verification wave (F3) under the dev-server protocol, not on every change.
|
|
*/
|
|
test.describe("Operations surfaces", () => {
|
|
test("guests are gated away from /operations by the landing page", async ({ page }) => {
|
|
await page.goto("/operations");
|
|
await expect(page.getByRole("heading", { level: 1 })).toHaveText("Polaris Task Force");
|
|
});
|
|
|
|
test("an authed user sees the operations overview with role sections", async ({ page }) => {
|
|
await page.goto("/login");
|
|
await page.getByLabel("Username").fill("dev");
|
|
await page.getByLabel("Password").fill("Test123");
|
|
await page.getByRole("button", { name: "Log in" }).click();
|
|
|
|
await page.goto("/operations");
|
|
await expect(page.getByRole("heading", { name: "Operations" })).toBeVisible();
|
|
await expect(page.getByText("Recent operations")).toBeVisible();
|
|
await shot(page, "operations-overview-authed");
|
|
await expect(page.getByText("My extractions")).toBeVisible();
|
|
});
|
|
|
|
test("the ledger shows empty and filtered states without raw payloads", async ({ page }) => {
|
|
await page.goto("/login");
|
|
await page.getByLabel("Username").fill("dev");
|
|
await page.getByLabel("Password").fill("Test123");
|
|
await page.getByRole("button", { name: "Log in" }).click();
|
|
|
|
await page.goto("/operations/ledger?status=dead-letter");
|
|
await expect(page.getByRole("heading", { name: "Operations ledger" })).toBeVisible();
|
|
await expect(page.getByText("No operation events match this view.")).toBeVisible();
|
|
await shot(page, "operations-ledger-dead-letter-empty");
|
|
});
|
|
|
|
test("an unknown operation id renders the empty AAR state", async ({ page }) => {
|
|
await page.goto("/login");
|
|
await page.getByLabel("Username").fill("dev");
|
|
await page.getByLabel("Password").fill("Test123");
|
|
await page.getByRole("button", { name: "Log in" }).click();
|
|
|
|
await page.goto("/operations/definitely-not-a-real-operation");
|
|
await expect(
|
|
page.getByText("No operation events are recorded under"),
|
|
).toBeVisible();
|
|
await shot(page, "operations-aar-unknown-empty");
|
|
});
|
|
});
|