All jobs

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 RushIn 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 with this body:

{
  "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.

The use case this job follows, with its automation and trigger: Write the missing tests.

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.