From svelte-5
Fixes and creates Svelte 5 tests using vitest-browser-svelte and Playwright for unit, SSR, and e2e testing. Use when fixing broken tests, debugging failures, or working with vitest/Playwright.
npx claudepluginhub fubits1/svelte-skills --plugin svelte-5This skill uses the workspace's default tool permissions.
```typescript
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
// Client-side component test (.svelte.test.ts)
import { render } from "vitest-browser-svelte";
import { expect } from "vitest";
import Button from "./button.svelte";
test("button click increments counter", async () => {
const { page } = render(Button);
const button = page.getByRole("button", { name: /click me/i });
await button.click();
await expect.element(button).toHaveTextContent("Clicked: 1");
});
Every test for an interactive component MUST include meaningful interaction. A render-only test proves the component mounts — it does NOT prove it works.
For components with inputs, autocompletes, buttons, or forms:
if (items.length > 0) guards
that skip the interaction when the precondition fails. ASSERT
the precondition instead.Example failure: tests that "verified" autocomplete interaction by checking "a selection exists" without checking which value — this missed a bug where onChange returned objects instead of strings.
page.getBy*() methods, never containers.first(), .nth(), .last() to avoid
strict mode violations$derived values in tests@storybook/addon-vitest): svelte-5:storybook-vitest skill — vitest.config.ts, test.projects entry, vitest --project=storybook, storybookUrl for CI links.pnpm test:unit or vitest run — run vitest browser tests only (fast, no dev server needed)pnpm test — runs vitest + Playwright e2e concurrently (e2e needs a dev server)pnpm validate — runs vitest + lint + typecheck + svelte-check (CI pipeline, no e2e)pnpm lint:tests. One command, all 5 linters (oxlint, tsgo, eslint, knip, svelte-check). Must exit 0. No exceptions.await expect.element().svelte.test.ts (client), .ssr.test.ts (SSR),
server.test.ts (API)page from vitest/browser, not @vitest/browser/context.focus() method — use .click() to focus elements<a href> clicks in tests navigate the iframe away, crashing the test. Avoid clicking links; test radio/button state instead.vi.waitFor() is unreliable in browser mode — prefer await expect.element() retry or await new Promise(r => setTimeout(r, N)) for async init.@astrojs/svelte ships svelte-shims.d.ts that wraps all .svelte imports with PropsWithClientDirectives, breaking vitest-browser-svelte's render() types.tsconfig.test.json extending main tsconfig but with "types": ["node", "svelte"] (no "astro/client"). Exclude .svelte.test.ts from main tsconfig.json. Point vitest to test tsconfig via test.typecheck.tsconfig.