# Write Vitest Tests for a SvelteKit App

Yes. An agent adds Vitest to your SvelteKit app, tests its load functions and form actions with real Request objects, runs them and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/write-vitest-tests/sveltekit/), in a Project that has your repository.

## What the agent does

In a SvelteKit app the code that breaks is on the server, in `+page.server.js` and `+layout.server.js`, so that is what the agent tests. In sveltejs/realworld it finds no test files, no test script and no Vitest: `package.json` has `@sveltejs/kit` ^2.52, Svelte 5, Vite 7 and `pnpm@10.20.0`, and `vite.config.js` holds only the `sveltekit()` plugin. It adds Vitest as a dev dependency, a `test` block in that same `vite.config.js` so `$lib` and `./$types` resolve the way they do in the app, and a `test` script.

It lists every load function and action under `src/routes`. `login` and `register` each have a `default` action that posts to the API and sets a `jwt` cookie. `editor/+page.server.js` redirects a signed-out visitor to `/login` and creates an article. `article/[slug]` loads the article and its comments, renders the body with `marked` and `sanitize-html`, and has `createComment`, `deleteComment`, `deleteArticle` and `toggleFavorite` actions. `settings` has `logout` and `save`, `profile/@[user]` has `toggleFollow`, and the home `+page.server.js` builds the `limit` and `offset` query from `tab`, `tag` and `page`.

Each test calls the function directly, as SvelteKit would: a real `Request` with a `FormData` body for actions, a `URL` for loads, a small cookie jar with `get`, `set` and `delete`, and `locals.user` set or null. Because `src/lib/api.js` calls `fetch` on a fixed `https://api.realworld.show/api` base, the agent stubs the global `fetch` for these unit tests and asserts the request each function sends (method, path, `Authorization: Token ...` header, JSON body) along with what it returns. Redirects and errors are thrown by `redirect()`, `error()` and returned by `fail()`, so the tests check them with `isRedirect`, `isHttpError` and `isActionFailure` from `@sveltejs/kit`.

The tests find behavior worth reporting. `toggleFavorite` calls `api.post` or `api.del` without `await` and then redirects, so the page can reload before the API has recorded the favorite. `hooks.server.js` builds `locals.user` with `JSON.parse(atob(jwt))`, so a malformed cookie throws on every request. A failed registration returns `fail(401, ...)`. The agent writes the intended behavior as tests, marks them as expected to fail, and names each in the pull request.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Add Vitest to this SvelteKit app and write unit tests for its load functions and form actions in src/routes, calling them directly with real Request objects. Run them and open a pull request.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-sveltekit-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request that adds Vitest to `package.json` and `pnpm-lock.yaml`, a `test` block and `test` script, and a `.test.js` file beside each server file it covers, such as `src/routes/login/page.server.test.js` and `src/routes/article/[slug]/page.server.test.js`, plus one for `hooks.server.js`. A shared helper builds the request, cookies and `locals`. No route code changes.

The description lists each load and action with the cases covered (signed in, signed out, API validation errors, redirects) and every test marked as expected to fail with the line that causes it: the unawaited favorite call, the unguarded cookie parse, the 401 on a validation failure. The session's trajectory keeps each `pnpm test` run with its output.

Before merging, a reviewer checks that the stubbed API answers match the real RealWorld API's shapes, decides which expected failures to fix, and decides whether to run these in CI beside `prettier --check`. A follow-up on the same session can fix the unawaited call and turn its test green.

## Run it on every new route

When a pull request adds a `+page.server.js` or `+server.js` under `src/routes`, a GitHub webhook can send this request with that pull request in `resources`, asking for tests of the new load function and actions only. The agent writes and runs them on that branch in its own sandbox.

Set a webhook URL on the API key and Rush POSTs `run.completed` or `run.failed` when the turn finishes, with the session URL, so your server can post the result on the pull request.

## Why run it on Rush?

Testing SvelteKit server code needs the generated `./$types`, the `$lib` alias and Kit's own redirect and error objects to behave as they do in the app, which is why many apps never get past the first failing import. In its own sandbox the agent wires Vitest through the app's own Vite config and iterates until every file imports and runs, without touching your checkout.

The result has been run, and it says what it found: each `pnpm test` is in the trajectory with its output, and the expected failures point at real lines. Because runs are independent, the same request can add server tests to several SvelteKit apps at once.

## Frequently asked questions

### Why stub fetch here?

The app's API client has a fixed base URL to a public server, so a unit test that called it would depend on shared, changing data. Stubbing the global `fetch` lets each test assert the exact request a load or action sends. For tests against a real backend, the browser tests on the Playwright page for this app are the place.

### Does it test Svelte components too?

Not in this request. It targets load functions, actions and the server hook, where SvelteKit apps break. Component tests need a browser-like environment and `@testing-library/svelte`; ask for them in a follow-up.

### How does it handle redirect() and error()?

Both throw in SvelteKit 2, so the tests catch the thrown value and check it with `isRedirect` or `isHttpError`, asserting the status and location. `fail()` returns a value, which the tests check with `isActionFailure`.

### Will it change my vite.config.js?

It adds a `test` block to it so Vitest uses the same `sveltekit()` plugin as the app. The diff shows that block alone; the plugin list and anything else stay as they are.
