import { render } from "@testing-library/react"; import * as React from "react"; import { describe, expect, it } from "vitest"; import type { PipelineState } from "../api/client"; import { LozengeFlyProvider } from "./LozengeFlyContext"; import { StagePanel } from "./StagePanel"; // ─── Helpers ────────────────────────────────────────────────────────────────── function makePipeline(overrides: Partial = {}): PipelineState { return { backlog: [], current: [], qa: [], merge: [], done: [], deterministic_merges_in_flight: [], ...overrides, }; } function Wrapper({ pipeline, children, }: { pipeline: PipelineState; children: React.ReactNode; }) { return ( {children} ); } // ─── Agent lozenge fixed intrinsic width ────────────────────────────────────── describe("AgentLozenge fixed intrinsic width", () => { it("has align-self: flex-start so it never stretches inside a flex column", () => { const items = [ { story_id: "74_width_test", name: "Width Test", error: null, merge_failure: null, agent: { agent_name: "coder-1", model: "sonnet", status: "running" }, review_hold: null, qa: null, depends_on: null, }, ]; const pipeline = makePipeline({ current: items }); const { container } = render( , ); const lozenge = container.querySelector( '[data-testid="slot-lozenge-74_width_test"]', ) as HTMLElement; expect(lozenge).toBeInTheDocument(); expect(lozenge.style.alignSelf).toBe("flex-start"); }); }); // ─── Idle vs active visual distinction ──────────────────────────────────────── describe("AgentLozenge idle vs active appearance", () => { it("running agent lozenge uses the green active color", () => { const items = [ { story_id: "74_running_color", name: "Running", error: null, merge_failure: null, agent: { agent_name: "coder-1", model: null, status: "running" }, review_hold: null, qa: null, depends_on: null, }, ]; const { container } = render( , ); const lozenge = container.querySelector( '[data-testid="slot-lozenge-74_running_color"]', ) as HTMLElement; expect(lozenge).toBeInTheDocument(); // Green: rgb(63, 185, 80) = #3fb950 expect(lozenge.style.color).toBe("rgb(63, 185, 80)"); }); it("pending agent lozenge uses the yellow pending color", () => { const items = [ { story_id: "74_pending_color", name: "Pending", error: null, merge_failure: null, agent: { agent_name: "coder-1", model: null, status: "pending" }, review_hold: null, qa: null, depends_on: null, }, ]; const { container } = render( , ); const lozenge = container.querySelector( '[data-testid="slot-lozenge-74_pending_color"]', ) as HTMLElement; expect(lozenge).toBeInTheDocument(); // Yellow: rgb(227, 179, 65) = #e3b341 expect(lozenge.style.color).toBe("rgb(227, 179, 65)"); }); it("running lozenge has a pulsing dot child element", () => { const items = [ { story_id: "74_pulse_dot", name: "Pulse", error: null, merge_failure: null, agent: { agent_name: "coder-1", model: null, status: "running" }, review_hold: null, qa: null, depends_on: null, }, ]; const { container } = render( , ); const lozenge = container.querySelector( '[data-testid="slot-lozenge-74_pulse_dot"]', ) as HTMLElement; // The pulse dot is a child span with animation: pulse const dot = lozenge.querySelector("span"); expect(dot).not.toBeNull(); expect(dot?.style.animation).toContain("pulse"); }); });