# Write Playwright Tests for a Nuxt App

Yes. An agent extends a Nuxt app's Playwright suite from the home page to its search, listing, detail, genre and person pages, on every browser project.

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

## What the agent does

The agent clones the repository into its own cloud sandbox and reads what the suite already is before adding to it. In a Nuxt app like nuxt/movies, `package.json` asks for Node `^24.0.0` and pnpm 11.1.2 through `devEngines`, and has `test:e2e` as `playwright test`, `test:unit` as `vitest`, `typecheck` as `nuxt typecheck` and `lint` as `eslint .`. `playwright.config.ts` imports `ConfigOptions` from `@nuxt/test-utils/playwright`, matches `**/tests/e2e/*.spec.ts`, points at `BASE_URL` when that variable is set, and defines four projects: Chrome on the `chrome` channel, Safari on WebKit, a Samsung Galaxy S20 and an iPhone 14, the two mobile ones at 412 by 915. `tests/e2e/` holds one file, `homepage.spec.ts`, with four tests; the unit side has component tests next to the components and `tests/unit/mocks.ts`.

It reads those four tests closely because they set the house style. They use the `goto` fixture from `@nuxt/test-utils/playwright` with `waitUntil: 'hydration'`, locate by role and accessible name (`getByRole('heading', { level: 2, name: 'Popular Movies' })`), check the document title `Movies · Nuxt Movies` after clicking the nav link titled `Movies`, measure the mobile nav's bounding box at 320 by 568, and switch `#langSwitcher` to `fr-FR` on `/tv/549` while collecting console messages to assert no hydration mismatch. Data comes from `https://movies-proxy.vercel.app`, the `apiBaseUrl` in `nuxt.config.ts`, and the pages fetch it on the server, so the suite runs against live data and `page.route` cannot stub the first render.

Then it reads the pages that have no test. `app/pages/search.vue` binds an input to `route.query.s` and calls `searchShows`, replacing the URL query as you type. `app/pages/[type]/index.vue` validates `type` as `movie` or `tv`, sets the title to `Movies` or `TV Shows`, renders a `MediaHero` and one `CarouselAutoQuery` per entry of `QUERY_LIST`. `app/pages/[type]/[id].vue` loads `getMedia` and renders `media/Details.vue` with its `Overview`, `Videos` and `Media Photos` headings. `app/pages/[type]/category/[query].vue` and `app/pages/genre/[no]/movie.vue` share `MediaAutoLoadGrid`, which fetches the next page on scroll. `app/pages/person/[id].vue` sets the title to the person's name. The agent writes one spec per page: a search that types a query, waits for the URL to carry `?s=`, and expects result cards; a listing that asserts the hero and the carousel headings for both types; a detail page that asserts the three headings and that the hero image loaded; a category grid that counts cards, scrolls to the bottom and expects more; a genre page that asserts the `Movie Genre:` heading; a person page whose title matches its `h1`; and a request for an invalid type that expects the 404 page.

Because the data is live, the assertions are about shape, not titles: a count greater than zero, a heading present, a URL changed. The one existing test that pins a specific French title stays as it is. The agent runs `pnpm exec playwright install --with-deps`, then `pnpm exec playwright test` across all four projects, since `tests-e2e.yml` runs exactly that in CI, and `pnpm lint` and `pnpm typecheck` afterwards because the ESLint config is strict about imports and unused variables.

## Start it with one API call

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

```json
{
  "agent": "claude",
  "input": "Write Playwright tests for the pages of this Nuxt app that tests/e2e/homepage.spec.ts does not cover: search, the movie and tv listing pages, a media detail page, a category grid, a genre page, a person page and a 404 for an invalid type. Read playwright.config.ts, the existing spec and the page files under app/pages first, and follow the existing style: the goto fixture from @nuxt/test-utils/playwright with waitUntil hydration, locators by role and accessible name, and no screenshots. The data is live from the proxy in nuxt.config.ts, so assert structure and counts rather than specific titles. Put one spec per page in tests/e2e/. Run pnpm exec playwright install --with-deps, then pnpm exec playwright test on all configured projects, then pnpm lint and pnpm typecheck, and open a pull request with the test output.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-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 on its own branch that adds spec files under `tests/e2e/`, one per page, and changes nothing else: no page, component or config file, because `playwright.config.ts` already matches every spec in that directory and already defines the four browser projects. The description lists each spec, the page it covers and the locators it relies on, and quotes the summary line of the Playwright run for all four projects.

A reviewer checks that no assertion depends on a title that will change as the live catalogue moves, that the mobile projects pass the same specs without separate branches in the test code, and that the 404 test asks for a type outside `movie` and `tv` rather than a missing id, which the proxy answers differently. The session's transcript keeps the full Playwright output per project and the lint and typecheck runs.

The existing `tests-e2e.yml` workflow runs the new specs on the pull request with no change to the workflow, so the checks on the pull request are the same suite the agent ran.

## Run it on every new page under app/pages

Add an automation to the Project with a GitHub trigger on `pull_request.opened` and `pull_request.synchronize` and a prompt that asks the agent to check whether the pull request adds a file under `app/pages/` without a matching spec under `tests/e2e/`, and if so to write the spec and push it to the same branch. Only work by an owner, member or collaborator fires the trigger; pull requests from forks never do, and a bot's own push does not fire it again.

A `schedule` trigger with a weekly `cron` in your `timezone` covers the slower drift: each run compares pages to specs and opens one pull request when something is uncovered.

## Why run it on Rush?

End-to-end tests for a site that reads live data are easy to write badly and slow to write well: every assertion has to survive next week's catalogue, four browsers have to agree, and WebKit has to be installed somewhere. The agent does that in its own sandbox with the browsers Playwright installs, runs every project the config defines, and your machine never opens a browser.

The pull request comes with the run that proves the suite passes today, per project, in the transcript. The reviewer reads locators and assertions, not a promise, and several apps can get the same treatment at once, each in its own sandbox.

## Frequently asked questions

### The data is live. Won't these tests be flaky?

They would be if they pinned titles. The new specs assert structure: a heading exists, a grid has more than zero cards and gains more after a scroll, the URL carries the search query. The one existing test that asserts a French title for `/tv/549` is left as it was. A test that still depends on the catalogue is named in the pull request so you can decide.

### Can it stub the proxy instead?

Not for the first render. The pages call `fetchTMDB` on the server during SSR, so `page.route` in the browser never sees those requests; only client-side navigations go through the browser. Stubbing would mean a mock server behind `apiBaseUrl` in `nuxt.config.ts`, which is a larger change the prompt did not ask for and the pull request mentions as an option.

### Does it run on WebKit and the mobile projects too?

Yes. `playwright.config.ts` defines Chrome, Safari, a Samsung Galaxy S20 and an iPhone 14, and `tests-e2e.yml` runs them all, so the agent runs them all before opening the pull request and quotes the per-project results. The browsers are installed with `pnpm exec playwright install --with-deps`, the same command the workflow uses.

### Will it write unit tests too?

Not in this run. The components already have Vitest tests beside them, and the gap the prompt names is page-level coverage in `tests/e2e/`. Ask in a follow-up message and it continues in the same sandbox with the app already installed.
