scaffold-e2e
Skill106 starsChanged 7 months agoMITView on GitHub
Set up Playwright for a pracht app with a config that boots `pracht dev` or `pracht preview`, plus a smoke test per route for status, title, console errors, and navigation. Use for "scaffold E2E", "set up Playwright", "add browser tests", "smoke test my routes".
- Reads credentials
- Installs packages
In this repository33 other files it gives its agents.
- AGENTS.mdAGENTS.md
- add-authSkill
- add-capabilitiesSkill
- add-contentSkill
- add-dbSkill
- add-i18nSkill
- add-imagesSkill
- add-observabilitySkill
- add-openapiSkill
- audit-a11ySkill
- audit-agent-surfaceSkill
- audit-authSkill
- audit-bundlesSkill
- audit-csrfSkill
- audit-depsSkill
- audit-headersSkill
- audit-islandsSkill
- audit-loadersSkill
- audit-redirectsSkill
- audit-secretsSkill
- audit-seoSkill
- audit-shellsSkill
- configure-isgSkill
- migrate-nextjsSkill
- pracht-debugSkill
- pracht-deploySkill
- pracht-scaffoldSkill
- pracht-test-apiSkill
- pre-deploySkill
- scaffold-testsSkill
- tune-render-modeSkill
- typed-routesSkill
- upgrade-prachtSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 1 is distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 27
Ask the user (default: dev):
- Very specific: line 46
Add firefox and webkit only if the user requests them.
- Very specific: line 79
If playwright.config.ts already exists, merge — do not clobber.
- Very specific: line 132
If any route is render: "ssr" or "ssg"/"isg":
- Very specific: line 155
If an e2e script already exists in the project, confirm before overwriting.
- Distinctive: line 165
If specs fail on first run, report.
- Very specific: line 175
Never overwrite an existing playwright.config.ts without diffing first.
- Very specific: line 176
If the app uses typed routes, run pracht typegen --check before generating specs and prefer imported href() for test URLs in app-owned …
- Very specific: line 177
Use webServer to boot pracht dev or pracht preview so CI works out-of-the-box.
- Very specific: line 181
Wait for window.__PRACHT_ROUTER_READY__ before interacting with the page in any spec that relies on client-side navigation.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Pracht Scaffold E2E
Generate a Playwright suite that exercises the live app. Aligns with https://pracht.resynapse.dev/docs/recipes/testing.md.
Step 1: Decide which build the tests run against
Ask the user (default: dev):
pracht dev— fast, HMR, but can mask production-only bugs (different bundling, different SSG/ISG flow).- Production runtime —
pracht preview: purpose-built, it builds and serves the production output locally for both Node and Cloudflare targets (Vercel prints guidance instead). Usepracht preview --skip-buildto serve an existing build after an explicitpracht build. Prefer this over hand-rollingnode dist/server/server.js, which is Node-adapter-only and skips the build. - External URL — user provides
BASE_URL; tests do not boot the server.
Step 2: Install
pnpm add -D @playwright/test
pnpm exec playwright install chromiumAdd firefox and webkit only if the user requests them.
Step 3: Write playwright.config.ts
import { defineConfig, devices } from "@playwright/test";
const PORT = Number(process.env.PORT ?? 3000);
export default defineConfig({
testDir: "./e2e",
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
reporter: process.env.CI ? "github" : "list",
use: {
baseURL: process.env.BASE_URL ?? `http://localhost:${PORT}`,
trace: "on-first-retry",
screenshot: "only-on-failure",
},
webServer: process.env.BASE_URL
? undefined
: {
command: "pnpm dev", // or "pracht preview" for the production runtime — choose at scaffold time
url: `http://localhost:${PORT}`,
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},
projects: [
{ name: "chromium", use: devices["Desktop Chrome"] },
],
});If playwright.config.ts already exists, merge — do not clobber.
Step 4: Generate per-route smoke tests
MCP: if pracht dev-mcp is registered, prefer its inspect_*, generate_*, doctor, and verify tools to the CLI.
pracht inspect routes --jsonFor every route entry, generate one spec under e2e/smoke/. Skip routes with
dynamic segments unless the user provides example params (ask via
AskUserQuestion).
Per-route template:
import { test, expect } from "@playwright/test";
test.describe("smoke: <path>", () => {
test("loads with 200 and a title", async ({ page }) => {
const errors: string[] = [];
page.on("console", (msg) => {
if (msg.type() === "error") errors.push(msg.text());
});
page.on("pageerror", (err) => errors.push(err.message));
const response = await page.goto("<path>");
expect(response?.status(), "HTTP status").toBeLessThan(400);
await expect(page).toHaveTitle(/.+/);
expect(errors, "no console errors").toEqual([]);
});
});Step 5: Generate a navigation crawl
A single e2e/navigation.spec.ts that:
- Visits the home route.
- Waits for hydration with the documented readiness idiom before touching
anything — otherwise the crawl races hydration and clicks fall through to
full page loads:
await page.waitForFunction(() => (window as any).__PRACHT_ROUTER_READY__); - Collects every same-origin
<a href>. - Clicks each in turn, asserts no console errors, no 4xx/5xx.
This catches client-router intercept regressions and broken links.
Step 6: Generate a hydration check (optional)
If any route is render: "ssr" or "ssg"/"isg":
test("server HTML matches client render", async ({ page }) => {
const errors: string[] = [];
page.on("console", (m) => m.type() === "error" && errors.push(m.text()));
await page.goto("<path>");
await page.waitForLoadState("networkidle");
expect(errors.filter((e) => /Hydration|hydrat/i.test(e))).toEqual([]);
});Step 7: Wire package.json
{
"scripts": {
"e2e": "playwright test",
"e2e:ui": "playwright test --ui"
}
}If an e2e script already exists in the project, confirm before
overwriting.
Step 8: Run
pnpm e2e
pracht verify --jsonIf specs fail on first run, report. Common first-run failures:
- Port collision (already-running dev server).
- Missing browser binary (
playwright install chromium). - Strict CSP blocking inline test scripts (rare).
Rules
- Source of routes is
pracht inspect routes --json. Do not globsrc/routes/**. - Skip dynamic-segment routes unless example params are provided.
- Never overwrite an existing
playwright.config.tswithout diffing first. - If the app uses typed routes, run
pracht typegen --checkbefore generating specs and prefer importedhref()for test URLs in app-owned route fixtures. - Use
webServerto bootpracht devorpracht previewso CI works out-of-the-box. - Console-error capture is mandatory — silent JS errors are the most common pracht hydration regression.
- Wait for
window.__PRACHT_ROUTER_READY__before interacting with the page in any spec that relies on client-side navigation.
$ARGUMENTS
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

