// #region TestAgentChat.ToolCallCard [C:2] [TYPE Module] [SEMANTICS test,tool,call,card] // @BRIEF L2 UX tests for ToolCallCard — renders executing/completed/failed states with proper visual indicators. // @RELATION BINDS_TO -> [AgentChat.ToolCallCard] // @UX_TEST: executing → spinner visible, tool name shown, no details button. // @UX_TEST: completed → checkmark, details toggle shows result. // @UX_TEST: failed → cross, details show error. import { describe, it, expect } from "vitest"; import { render, screen, fireEvent } from "@testing-library/svelte"; import ToolCallCard from "../ToolCallCard.svelte"; // #region TestAgentChat.ToolCallCard.Executing [C:2] [TYPE Test] // @UX_STATE executing — spinner icon, tool name in mono font, no Details button. describe("ToolCallCard — executing state", () => { it("renders tool name and spinner", () => { render(ToolCallCard, { props: { tool: "search_dashboards", input: { query: "test" }, status: "executing", }, }); expect(screen.getByText("search_dashboards")).toBeTruthy(); // SVG spinner should be present (has animate-spin class in the SVG element) const svg = document.querySelector("svg.animate-spin"); expect(svg).toBeTruthy(); }); it("does not show Details button while executing", () => { render(ToolCallCard, { props: { tool: "search_dashboards", status: "executing", }, }); expect(screen.queryByText("Details")).toBeNull(); }); }); // #endregion TestAgentChat.ToolCallCard.Executing // #region TestAgentChat.ToolCallCard.Completed [C:2] [TYPE Test] // @UX_STATE completed — checkmark icon, Details button present, clicking shows result. describe("ToolCallCard — completed state", () => { it("renders tool name and checkmark", () => { render(ToolCallCard, { props: { tool: "search_dashboards", output: { found: 3 }, status: "completed", }, }); expect(screen.getByText("search_dashboards")).toBeTruthy(); expect(screen.getByText("Details")).toBeTruthy(); }); it("toggles detail section on Details click", async () => { render(ToolCallCard, { props: { tool: "search_dashboards", output: { found: 3, items: ["a", "b"] }, status: "completed", }, }); // Initially details should be hidden expect(document.querySelector("details")).toBeNull(); // Click Details button using fireEvent for reactive flush const detailsBtn = screen.getByText("Details"); await fireEvent.click(detailsBtn); // After click, details elements appear const postDetails = document.querySelector("details"); expect(postDetails).toBeTruthy(); const summary = postDetails?.querySelector("summary"); expect(summary).toBeTruthy(); }); }); // #endregion TestAgentChat.ToolCallCard.Completed // #region TestAgentChat.ToolCallCard.Failed [C:2] [TYPE Test] // @UX_STATE failed — cross icon, error visible inline. describe("ToolCallCard — failed state", () => { it("renders tool name, cross, and error detail", () => { render(ToolCallCard, { props: { tool: "search_dashboards", error: "API timeout after 30s", status: "failed", }, }); expect(screen.getByText("search_dashboards")).toBeTruthy(); expect(screen.getByText("Details")).toBeTruthy(); }); }); // #endregion TestAgentChat.ToolCallCard.Failed // #endregion TestAgentChat.ToolCallCard