What the agent does
The agent first works out what the repository already has, because an Angular app often has more test wiring than tests. In realworld-apps/angular-realworld-example-app, package.json pins Angular 21.2 and @playwright/test 1.58, uses Bun (bun.lock, bun run setup), and runs unit tests with Vitest through @analogjs/vite-plugin-angular, whose vitest.config.ts only picks up src/**/*.spec.ts. There is a playwright.config.ts, but its testDir is ./realworld/specs/e2e and it imports baseConfig from the realworld git submodule. A fresh clone without git submodule update has an empty realworld/, so bun run test:e2e finds no tests and no config to load.
So it writes the app's own specs under e2e/ with a config of its own, playwright.config.ts pointing at ./e2e and no longer importing from the submodule, with webServer running npm run start (ng serve) on http://localhost:4200 and reuseExistingServer off in CI, as the existing config already sets. It installs Chromium with npx playwright install --with-deps chromium and keeps test:e2e working for the new location.
The specs follow the app's real routes in app.routes.ts and its real form controls. Sign-in fills the Email and Password placeholders on /login, waits for the header to show the username, and checks /settings is reachable while /editor redirects to /login for a signed-out visitor through requireAuth. The editor spec fills Article Title, What's this article about?, the markdown body and Enter tags, publishes, and checks the article page renders the title and tags. The comments spec posts a comment on that article, reloads, and deletes it. For waiting on auth, the agent uses the window.__conduit_debug__ hook app.config.ts installs (getAuthState() returns authenticated) instead of fixed sleeps.
Every request goes to https://api.realworld.show/api (api.interceptor.ts hard-codes it), a shared public backend. The agent registers a fresh user per test run with a unique username so specs never collide with other people's data, and keeps every article it creates traceable to that user. It runs the suite headless several times to catch flakiness, and where a test fails because of the app rather than the test, it marks it test.fail() with the reason.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Write Playwright end-to-end tests for sign-in, the editor and comments in this Angular app. Put them in e2e/ with a playwright.config that starts the dev server, run them headless, and open a pull request with the passing suite. If a test exposes a real bug, mark it expected to fail and explain it in the description.",
"resources": [
{
"url": "https://github.com/your-org/your-angular-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 that adds e2e/auth.spec.ts, e2e/editor.spec.ts and e2e/comments.spec.ts, a small fixture that registers a unique user and signs it in, and a playwright.config.ts whose testDir is ./e2e with the ng serve web server. package.json keeps its existing scripts; test:e2e now runs the new specs without needing the submodule.
The description lists each spec and the flow it proves, how to run the suite locally, and every test marked test.fail() with what it found and the file that causes it. The session's trajectory keeps each npx playwright test run with its full output, including the failure message of every test marked as expected to fail.
Before merging, a reviewer checks whether the team wants the specs to keep using the public RealWorld API or a local backend, whether the old submodule-based config should be removed or kept beside the new one, and whether each expected failure is a bug to fix next. Adding the suite to CI is a one-step follow-up.
Run it on every pull request that changes a route
A GitHub webhook for pull_request can send a request when a pull request touches app.routes.ts or a page component, with that pull request in resources, asking the agent to extend or fix the e2e specs for the changed flow. It works on that pull request's branch in its own sandbox and runs the suite there.
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?
Writing Playwright tests for an Angular app on a laptop ties up a port, a dev server and a browser while you iterate, and a spec that passes once on your machine can still flake. In its own sandbox the agent runs ng serve, installs Chromium and runs the suite headless repeatedly, so what reaches you is a suite that has passed more than once.
The proof travels with the pull request: the trajectory has every playwright test command with its output, failures included. Because each run is isolated, the same request can add end-to-end tests to several Angular front ends at once without their dev servers fighting over port 4200.
Frequently asked questions
My repo already has a playwright.config.ts. Will it be overwritten?
It changes it only as far as the request needs, and the diff shows exactly how. In this app the existing config pointed at a submodule's shared specs, so the agent points testDir at ./e2e and explains why in the description. If you want to keep both suites, ask for a second Playwright project instead.
Does it test against my real backend?
It uses whatever URL the app calls. Here api.interceptor.ts hard-codes the public RealWorld API, so the specs register their own throwaway users there. For a private backend, name its URL or a local server command in the prompt, and the agent starts it before the tests.
Will it use the Vitest setup the app already has?
No. Vitest stays for the unit specs under src/, and Playwright runs the end-to-end specs in e2e/. The two do not share files or config, so bun run test and bun run test:e2e keep working separately.
What happens when a test finds a real bug?
The spec stays in the suite, marked test.fail() with a comment naming the cause, so the suite is green and the bug is still recorded. The pull request description lists each one, and a follow-up on the same session can fix it and remove the mark.