import type { Meta, StoryObj } from "@storybook/vue3-vite"; import { expect, within, userEvent } from "storybook/test"; import RcaPanel from "./RcaPanel.vue"; import { groupIncidents } from "@/lib/rca"; import type { TelemetryRecord } from "@/lib/telemetry"; const env = (m: string, c: string) => ({ messageId: m, causationId: c, correlationId: "c-9f8e", tenant: "acme", userId: "u-42", }); // A failed chain: dispatch → retrying action.failed → dead-lettered. const RECORDS: TelemetryRecord[] = [ { kind: "action.dispatched", action: "orders.charge", appName: "billing", ts: "2026-01-01T00:00:00.000Z", durationMs: 4, envelope: env("m1", "m1"), }, { kind: "event.published", event: "ChargeStarted", appName: "billing", ts: "2026-01-01T00:00:00.010Z", envelope: env("m2", "m1"), }, { kind: "action.failed", action: "orders.charge", appName: "billing", attempt: 1, maxAttempts: 3, willRetry: true, durationMs: 40, ts: "2026-01-01T00:00:00.050Z", error: { name: "TimeoutError", message: "upstream timed out", stack: "TimeoutError: upstream timed out\n at chargeCard (apps/billing/orders.charge.ts:42:11)", }, envelope: env("m3", "m1"), }, { kind: "dlq.recorded", action: "orders.charge", appName: "billing", attempts: 3, ts: "2026-01-01T00:00:00.300Z", error: { name: "TimeoutError", message: "upstream timed out" }, envelope: env("m4", "m1"), }, ]; const incident = groupIncidents(RECORDS)[0]!; const meta: Meta = { title: "Errors/RcaPanel", component: RcaPanel, tags: ["autodocs"], decorators: [ (story) => ({ components: { story }, template: '
', }), ], }; export default meta; type Story = StoryObj; export const Default: Story = { args: { incident, source: { file: "apps/billing/orders.charge.ts", line: 42 } }, play: async ({ canvasElement }) => { const c = within(canvasElement); await expect(c.getByTestId("rca-what")).toBeInTheDocument(); await expect(c.getByTestId("rca-suggestion")).toBeInTheDocument(); await userEvent.click(c.getByTestId("rca-tab-timeline")); await expect(c.getAllByTestId("rca-timeline-row")).toHaveLength(4); await userEvent.click(c.getByTestId("rca-tab-evidence")); await expect(c.getByTestId("rca-evidence")).toHaveTextContent("TimeoutError"); }, }; export const WithoutSource: Story = { args: { incident }, };