What the agent does
The agent maps the full-stack layout before it touches a spec. In a project like fastapi/full-stack-fastapi-template it finds compose.yml with Traefik v3.7, Postgres 18 (POSTGRES_DB=app), the backend image built from backend/Dockerfile, and a React frontend under frontend/ with Vite, Bun (bun.lock at the repo root) and @playwright/test 1.63.0. Backend pytest already lives under backend/tests/; the browser suite lives in frontend/tests/ with playwright.config.ts setting testDir to ./tests, a setup project for *.setup.ts, Chromium using playwright/.auth/user.json, and a webServer that runs bun run dev at http://localhost:5173 unless PLAYWRIGHT_BASE_URL points at Compose.
It reads the specs that already ship: items.spec.ts covers create, edit, delete, validation and the empty state through roles like Add Item and toasts such as Item created successfully; admin.spec.ts covers create, edit and delete of users including the superuser checkbox; login.spec.ts, sign-up.spec.ts, reset-password.spec.ts and user-settings.spec.ts cover the auth surfaces. Helpers in frontend/tests/utils/ (createUser via the private API, logInUser, random email and title generators) and frontend/tests/config.ts (firstSuperuser, firstSuperuserPassword) are the patterns new cases must follow.
The gaps it fills are the edges those files still skip: a non-superuser hitting /admin and being refused, item list behaviour after pagination or refresh, admin deactivate/reactivate if the UI exposes it, and any new screen the template added without a matching spec. New cases go in frontend/tests/ (or a focused file beside items.spec.ts / admin.spec.ts), reuse storageState resets with test.use({ storageState: { cookies: [], origins: [] } }) when they need a fresh session, and keep selectors on roles and labels the way the existing suite does.
It brings the stack up with Docker Compose (compose.yml plus compose.override.yml for local ports), points Playwright at the proxied URL when the frontend is served through the stack, installs browsers if needed, and runs bunx playwright test (the test script in frontend/package.json) headless until the suite is green. Only then does it open a pull request with the new or extended specs.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Extend this template's Playwright tests with end-to-end coverage of item creation, editing and deletion and the admin user screens, running the backend and frontend with Docker Compose in the sandbox. Open a pull request with the passing suite.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- 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.
- 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.
- 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 a new branch. In a repository shaped like the official full-stack FastAPI template it extends files under frontend/tests/ (for example richer cases in items.spec.ts and admin.spec.ts, or a new focused spec that reuses utils/privateApi and utils/user). compose.yml, backend pytest and production FastAPI routes stay unchanged unless a test setup file must name an env var that Compose already provides.
The pull request description states which flows were added, that Docker Compose was used for Postgres and the API, and that bunx playwright test passed headless in the sandbox. The trajectory keeps Compose logs and Playwright output, including any trace the agent collected on a retry.
Before merging, a reviewer checks that selectors still use roles and labels, that the suite does not depend on a developer's laptop URL, and that secrets in .env are not copied into the specs. Once merged, .github/workflows/playwright.yml can run the same files in CI.
Run it on every frontend route or admin screen merged
On pull_request synchronize for paths under frontend/src/ or backend/app/api/, have your server send this request so each UI change gets a Playwright pass against Compose before you rely on reviewers to click through it by hand.
Use the API key webhook for run.completed / run.failed and keep starts inside max_concurrent. Long Compose boots mean fewer parallel runs than a unit-test job.
The use case this job follows, with its automation and trigger: Write the missing tests.
Why run it on Rush?
Full-stack Playwright needs Postgres, the FastAPI container, the React dev server and a real Chromium. That loop is slow and fragile on a laptop that already runs other Docker stacks. On Rush the agent owns the Compose project in its sandbox, runs the headless suite there, and only opens the pull request when the flows pass.
The proof is the green Playwright run plus the trajectory, not a screenshot from a laptop. Reviewers see which admin and item paths were added, and several apps can get the same treatment at once without sharing a local Docker daemon.
Frequently asked questions
Does it rewrite the existing items and admin specs?
It extends them or adds sibling files. Create, edit and delete already exist in items.spec.ts and admin.spec.ts; the agent fills the remaining edges and any new screens rather than deleting the suite you already trust.
Bun or npm for the frontend?
The template's frontend scripts call bunx playwright test and the repo root has bun.lock, so the agent stays on Bun. If your fork only has package-lock.json, it follows that lockfile instead.
Will it hit my production database?
No. It uses the Compose db service and the env values from the project's .env / Compose files inside the sandbox. Nothing outside that stack is contacted for the test run.
What if a test finds a real UI bug?
The prompt asks for a passing suite. If a flow is broken in the template, the agent marks that case as expected to fail or documents the defect in the pull request description instead of weakening the assertion to hide it.