Astro 7 component rendering tests with the Container API (Vitest): working versions (tested 2026-10-15)
Render Astro components to HTML in Vitest with the Container API and getViteConfig, checking props, slots and conditional markup.
passed2 passed · 0 failed2026-10-15 11:51 UTC- Status
- passed
- Last passed
- 2026-10-15 11:51 UTC
- Tests
- 2 / 2
- Language
- TypeScript
- Runtime
- node v22.23.3
npm install --no-audit --no-fund --ignore-scripts=false npm test
node v22.23.3 linux 6.17.0-1022-azure x64 runner: github-actions 38730348195
The code
Exactly the files that passed. Your agent can pull them with get_recipe("astro-container-render") (install), or see them on GitHub.
{
"name": "astro-container-render",
"private": true,
"type": "module",
"scripts": {
"test": "vitest run --reporter=default --reporter=json --outputFile=test-report.json"
},
"dependencies": {
"astro": "7.3.8"
},
"devDependencies": {
"@types/node": "24.19.2",
"vitest": "5.0.4"
}
}
/// <reference types="vitest/config" />
import { getViteConfig } from "astro/config";
export default getViteConfig({ test: {} });
import { defineConfig } from "astro/config";
export default defineConfig({});
---
interface Props { name: string; price: number; featured?: boolean }
const { name, price, featured = false } = Astro.props;
const label = price === 0 ? "Free" : `$${price}/mo`;
---
<article class:list={["card", { featured }]}>
<h2>{name}</h2>
<p class="price">{label}</p>
{featured && <span class="badge">Most popular</span>}
<slot />
</article>
import { describe, it, expect } from "vitest";
import { experimental_AstroContainer as AstroContainer } from "astro/container";
import PriceCard from "../src/components/PriceCard.astro";
describe("PriceCard", () => {
it("renders props and slot", async () => {
const c = await AstroContainer.create();
const html = await c.renderToString(PriceCard, { props: { name: "Pro", price: 9 }, slots: { default: "<li>Unlimited recipes</li>" } });
expect(html).toContain("Pro</h2>");
expect(html).toContain("$9/mo");
expect(html).toContain("Unlimited recipes");
expect(html).not.toContain("Most popular");
});
it("featured + free variants", async () => {
const c = await AstroContainer.create();
const html = await c.renderToString(PriceCard, { props: { name: "Free", price: 0, featured: true } });
expect(html).toMatch(/Free<\/p>/);
expect(html).toMatch(/class="card featured/);
expect(html).toContain("Most popular");
});
});
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.
Related stacks
Hono + Drizzle ORM + SQLite REST API (Vitest)
CRUD REST API in Hono backed by Drizzle ORM on better-sqlite3, with Zod validation, tested with Vitest and app.request().
Hono + Valibot request validation (Vitest)
Validate JSON bodies and query strings in Hono with Valibot schemas via @hono/valibot-validator, with custom error responses, tested with Vitest.
ioredis cache-aside with TTL, tested with ioredis-mock (Vitest)
Cache-aside helper on ioredis with JSON values, TTLs, stampede-safe single flight and invalidation, tested offline with ioredis-mock in Vitest.
ky HTTP client with hooks and retries, tested with MSW + Vitest
A ky 2 API client (prefix option, state-object hooks) with auth hooks, retry on 5xx and typed JSON, tested offline with MSW's Node server in Vitest.