What the agent does
In a site built from gatsbyjs/gatsby-starter-blog the agent reads package.json first: gatsby ^5.14.6 with React 18, ten official plugins and transformers including gatsby-plugin-feed, gatsby-plugin-image, gatsby-plugin-sharp, gatsby-remark-images, gatsby-remark-prismjs, gatsby-source-filesystem and gatsby-transformer-remark, a package-lock.json so npm is the package manager, and scripts for build, develop, serve, clean and format. The test script is the starter's placeholder: it prints a reminder to write tests and exits 1. There is no workflow under .github/, no test runner, and .prettierrc sets arrowParens: avoid and semi: false, so new files must follow that style.
Then it maps what the build will emit. gatsby-config.js points gatsby-source-filesystem at content/blog, configures gatsby-remark-images at 630 pixels wide, and defines the feed with output: /rss.xml built from allMarkdownRemark sorted by date descending. gatsby-node.js creates one page per Markdown post from the same query sorted ascending, passing previousPostId and nextPostId into src/templates/blog-post.js, and sets each post's slug from createFilePath, so the three posts under content/blog become /hello-world/, /my-second-post/ and /new-beginnings/. The template renders the title in an h1 with itemProp="headline", the date formatted MMMM DD, YYYY, the HTML body, the Bio component and a nav.blog-post-nav whose rel="prev" and rel="next" links appear only when a neighbour exists. src/pages/index.js lists posts newest first as article.post-list-item with an h2 link and a small date, and src/pages/404.js and src/pages/using-typescript.tsx are the other routes. hello-world/index.md embeds salty_egg.jpg, which gatsby-remark-images turns into a responsive image wrapper, and new-beginnings/index.md sets a description that Seo puts in the meta tag.
The agent adds @playwright/test as a dev dependency with npm, writes playwright.config.js with a webServer that runs npm run serve against the finished public/ directory on the port gatsby serve reports, and replaces the placeholder test script with playwright test. The specs live in a tests directory, one per area. The home page lists three posts with New Beginnings first and Hello World last, each heading linking to its slug. A post page has the right h1, a date in the configured format, and for Hello World a rendered image inside the article body. Navigation follows gatsby-node.js: the oldest post has only a next link, the newest only a previous link, and the middle one both, with rel attributes the test asserts on. The <title> from Seo reads the post title followed by the site title, and the description meta tag uses the frontmatter description when there is one and the excerpt when there is not. GET /rss.xml answers XML with one item per post, and an unknown path renders the 404 page.
The run executes npm ci, npm run build, npx playwright install chromium, then the suite headless until it passes, then npx prettier --check on the new files so they match .prettierrc. Because every page is static, the tests read the built HTML rather than waiting on hydration, except where a Link click must change the page, and the agent writes those with Playwright's navigation waits. It changes nothing under src/ or content/; if a test reveals a real defect in a page, that goes in the pull request description for a separate change.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Write Playwright tests for this Gatsby site that build it, serve the output, and check the pages it generates. Read package.json, gatsby-config.js, gatsby-node.js, src/templates/blog-post.js and src/pages/index.js first: the site builds with npm, posts come from content/blog, and gatsby-node.js creates one page per post with previous and next neighbours. Add @playwright/test as a dev dependency, a playwright.config.js whose webServer runs npm run serve against the built public directory, and replace the placeholder test script with playwright test. Cover the home page listing every post newest first with links to their slugs, one post page with its heading, formatted date and rendered image, the previous and next links on the oldest, newest and a middle post, the document title and description meta tag from the Seo component, GET /rss.xml with one item per post, and the 404 page. Run npm ci, npm run build, playwright install chromium and the suite headless until it passes, then prettier --check on the new files, and open a pull request. Do not change files under src or content.",
"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
The pull request adds playwright.config.js, a tests directory with one spec per area, @playwright/test under devDependencies, the replaced test script and the updated package-lock.json. It changes no page, template, component or post. Its description lists each test with the route it hits and what it asserts, and quotes the Playwright summary from the run.
A reviewer opens the navigation spec first, since it encodes the ordering gatsby-node.js produces and would be the first to break when a post is added: it should derive which post is oldest and newest from the content rather than hard-coding slugs, or name the posts it assumes. Then they check that the feed test counts items against the posts in content/blog, and that the config runs npm run serve against public/ rather than gatsby develop, so the suite tests what a deploy ships.
The session keeps the build log, the Playwright output and every file the agent read before choosing its fixtures. A request to cover the using-typescript page or a new tag page is a follow-up message to the same session, and the agent extends the same branch.
Run it on every pull request
Once the suite exists, run it on every pull request from a GitHub Actions job: npm ci, npm run build, npx playwright install --with-deps chromium and npm test. This repository has no workflow yet, and the agent's pull request adds one when the prompt asks for it.
To have an agent write the same suite for each site started from this template, a handler on your server sends this request with the new repository in resources whenever one is created, using the repository name as the Idempotency-Key, and reads the pull request link from the run.completed webhook on the API key.
The use case this job follows, with its automation and trigger: Write the missing tests.
Why run it on Rush?
A Gatsby build with image processing is the slow part of writing end-to-end tests: build, serve, run, read the failure, fix a selector, build again. In its own sandbox the agent runs that loop on its own machine with its own Chromium, while your checkout and your gatsby develop server stay untouched.
The pull request comes with proof: the build log, the Playwright summary and the transcript showing which posts the agent read before asserting on their titles, dates and neighbours. Several sites built from the same starter can get the request at once, each in its own sandbox.
Frequently asked questions
Why run against gatsby serve instead of gatsby develop?
gatsby serve serves the public/ directory a build produced, which is what a deploy ships, including the processed images and the /rss.xml the feed plugin writes at build time. gatsby develop renders pages on demand and does not write the feed, so a test against it would skip the feed and could pass on pages the build would fail.
Will it change my pages or posts?
No. The diff is the Playwright config, the tests, the dev dependency, the lockfile and the test script that replaced the placeholder. A defect a test uncovers in a template is described in the pull request for a separate change.
What happens to the tests when I add a post?
The home page and feed tests count posts from content/blog rather than assuming three, and the navigation test identifies the oldest and newest post by date, so a new post changes the expected neighbours without editing the tests. The pull request says which assumptions, if any, are fixed to named posts.
Does it work with yarn or pnpm?
Yes. This repository has a package-lock.json, so the agent uses npm for the install, the build, the browser install and the lockfile. With a yarn.lock or pnpm-lock.yaml it uses that tool throughout and keeps that lockfile in the commit.