// @vitest-environment happy-dom import { describe, expect, it, vi } from "vitest"; import { branchFromWorktreePath, buildTranscriptRow, renderInlineMarkdown, renderRail, } from "./structuredRender.js"; import type { Session, TranscriptRow } from "./types.js"; function row( kind: K, data: unknown, id = "r1", ): TranscriptRow & { kind: K } { return { id, kind, data }; } describe("buildTranscriptRow: user/agent/thought", () => { it("renders a user row with the text content and no markdown", () => { const el = buildTranscriptRow( row("user", { content: { type: "text", text: "hi there" } }), ); expect(el.className).toContain("st-row-user"); expect(el.textContent).toContain("hi there"); // never actual markup from user input expect(el.querySelector("b")).toBeNull(); }); it("renders agent prose as paragraphs with inline markdown", () => { const el = buildTranscriptRow( row("agent_text", { content: { type: "text", text: "one **two** `three`\n\nfour" } }), ); expect(el.className).toContain("st-row-agent"); const ps = el.querySelectorAll("p"); expect(ps).toHaveLength(2); expect(ps[0].innerHTML).toContain("two"); expect(ps[0].innerHTML).toContain("three"); }); it("renders a thought row as plain text", () => { const el = buildTranscriptRow(row("agent_thought", { content: { type: "text", text: "hmm" } })); expect(el.className).toContain("st-row-thought"); expect(el.textContent).toBe("hmm"); }); it("falls back to a labelled placeholder for non-text content, never crashing", () => { const el = buildTranscriptRow(row("user", { content: { type: "image" } })); expect(el.textContent).toContain("[image]"); }); it("never clips text: a very long user message is not truncated", () => { const long = "x".repeat(5000); const el = buildTranscriptRow(row("user", { content: { type: "text", text: long } })); expect(el.textContent).toContain(long); }); }); describe("renderInlineMarkdown", () => { it("escapes raw HTML before applying markdown", () => { expect(renderInlineMarkdown("")).not.toContain("