; }");
expect(result.status).toBe("failed");
});
// The same render that validates the artifact also produces the gallery's
// layout preview. These pin the markup half of the contract.
describe("layout markup", () => {
it("returns the markup the component rendered", async () => {
const result = await smokeRenderArtifact(
'function App(){ return
Revenue
; }',
);
expect(result.status).toBe("ok");
const markup = result.status === "ok" ? (result.markup ?? "") : "";
// The classes are the whole visual layer, so they have to survive.
expect(markup).toContain('class="p-4"');
expect(markup).toContain("Revenue");
});
it("returns the LOADING composition for a component that queries", async () => {
// Every tool call hangs by design, so this is the state the user sees
// first — and the state that is safe to store, since nothing was fetched.
const result = await smokeRenderArtifact(
[
"function App(){",
" const q = useQuery(tools.github.issues.list.queryOptions({}));",
" if (q.isPending) return
;",
" return
{String(q.data)}
;",
"}",
].join("\n"),
);
expect(result.status).toBe("ok");
const markup = result.status === "ok" ? (result.markup ?? "") : "";
expect(markup).toContain("artifact-loading");
expect(markup).not.toContain("undefined");
});
it("omits markup when the render fails", async () => {
// A failed verdict has no preview to offer, and the type says so.
const result = await smokeRenderArtifact("function App(){ return
; }");
expect(result.status).toBe("failed");
expect("markup" in result).toBe(false);
});
it("omits markup for a component that renders nothing", async () => {
// Empty is not a preview, and the caller must not read "" as one.
const result = await smokeRenderArtifact("function App(){ return null; }");
expect(result.status).toBe("ok");
expect(result.status === "ok" ? result.markup : "unused").toBeUndefined();
});
it("drops the markup rather than returning a partial tree when it is huge", async () => {
// Past the harness's cap the render is still driven to completion — that
// is how a late throw is observed — but nothing is kept, because half a
// DOM tree is not a picture of anything.
const result = await smokeRenderArtifact(
[
"function App(){",
" return (",
"
",
" {Array.from({ length: 4000 }, (_, i) => (",
'
',
" Row number {i} with enough text to add up quickly",
"
",
" ))}",
"
",
" );",
"}",
].join("\n"),
);
expect(result.status).toBe("ok");
expect(result.status === "ok" ? result.markup : "unused").toBeUndefined();
}, 60_000);
});
it("reports code with no App component", async () => {
const result = await smokeRenderArtifact("const x = 1;");
expect(result.status).toBe("failed");
expect(result.status === "failed" ? result.message : "").toContain("App");
});
it("carries a component stack when React reports one", async () => {
const result = await smokeRenderArtifact(
[
"function Inner(){ throw new Error('boom'); }",
"function App(){ return
; }",
].join("\n"),
);
expect(result.status).toBe("failed");
expect(result.status === "failed" ? result.message : "").toContain("boom");
expect(result.status === "failed" ? result.componentStack : undefined).toContain("Inner");
});
it("renders the shadcn components that need their own provider from the shell", async () => {
// TooltipProvider is supplied by the harness exactly as the inner renderer
// supplies it, so a bare Tooltip must not be reported as broken.
const result = await smokeRenderArtifact(
[
"function App(){",
" return (",
"
",
" ?",
" Help",
" ",
" );",
"}",
].join("\n"),
);
expect(result.status).toBe("ok");
});
it("renders a representative dashboard: cards, table, badges, icons", async () => {
const result = await smokeRenderArtifact(
[
"function App(){",
" const q = useQuery(tools.vercel.getDomains.queryOptions({}));",
" const rows = q.data?.domains ?? [];",
" if (q.isLoading) return
;",
" if (q.error) return
;",
" if (!rows.length) return
;",
" return (",
"
",
" Domains",
" ",
" ",
" {rows.map((row) => (",
" ",
" {row.name}",
" {row.status}",
" ",
" ))}",
"
",
" ",
" ",
" );",
"}",
].join("\n"),
);
expect(result.status).toBe("ok");
});
});