Files
PaperClipAI/tests/storybook-visual/failure-notices.spec.ts
T
DottaandPaperclip b11010b0d4 Simplify failure banners and show only the latest error (#16982)
Remove dashed failure dividers and show only the latest adjacent run or recovery error. Preserve permitted retries, pending state and unrelated notice boundaries. Add production-component Storybook examples and browser regression coverage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-20 14:29:39 -05:00

52 lines
3.0 KiB
TypeScript

import { expect, test } from "@playwright/test";
const stories = [
"failed-run", "older-marker", "production-mode", "recovery-is-latest",
"failure-is-latest", "expanded-recovery-and-retry", "expanded-failure-and-retry",
"message-between-errors", "system-notice-between-errors", "production-system-notice-between-errors",
"light", "mobile", "legacy-run-retry", "legacy-production-retry",
"automatic-recovery-blocked", "production-automatic-recovery-blocked",
];
for (const theme of ["dark", "light"]) {
for (const story of stories) {
test(`${story} [${theme}]`, async ({ page }, testInfo) => {
if (story === "mobile") await page.setViewportSize({ width: 390, height: 844 });
const errors: string[] = [];
page.on("pageerror", (error) => errors.push(error.message));
const id = `tasks-failure-notices--${story}`;
await page.goto(`/iframe.html?id=${id}&viewMode=story&globals=theme:${theme}`);
// Storybook records this after play assertions and accessibility reports.
await expect.poll(() => page.evaluate(() => {
const channel = (window as unknown as {
__STORYBOOK_ADDONS_CHANNEL__?: { data: Record<string, Array<{ storyId?: string; status?: string }>> };
}).__STORYBOOK_ADDONS_CHANNEL__;
return channel?.data.storyFinished?.[0]?.status;
})).toBe("success");
expect(await page.evaluate(() => (window as unknown as {
__STORYBOOK_ADDONS_CHANNEL__: { data: Record<string, unknown> };
}).__STORYBOOK_ADDONS_CHANNEL__.data.playFunctionThrewException)).toBeUndefined();
expect(errors).toEqual([]);
await expect(page.locator("body.sb-show-errordisplay, main .border-dashed, main .h-px")).toHaveCount(0);
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true);
if (["recovery-is-latest", "failure-is-latest", "light", "mobile"].includes(story)) {
await expect(page.getByRole("button", { name: "Try again" })).toHaveCount(1);
await expect(page.getByText(story === "failure-is-latest" ? "No live execution path" : "Run failed", { exact: true })).toHaveCount(0);
}
if (["expanded-recovery-and-retry", "automatic-recovery-blocked", "production-automatic-recovery-blocked"].includes(story)) {
await expect(page.getByRole("status")).toHaveText("Recovery retry requested");
}
if (["legacy-run-retry", "legacy-production-retry"].includes(story)) {
await expect(page.getByRole("status")).toHaveText("Retry requested for failed-run");
await expect(page.getByText("Run failed", { exact: true })).toHaveCount(0);
await expect(page.getByRole("button", { name: "Try again" })).toHaveCount(1);
}
if (story === "expanded-failure-and-retry") {
await expect(page.getByRole("status")).toHaveText("Retry requested for failed-run");
await expect(page.getByRole("link", { name: "View run" })).toBeVisible();
}
await page.screenshot({ path: testInfo.outputPath(`${story}-${theme}.png`), fullPage: true });
});
}
}