ワンクリックで
generate-tests
Use when you want to generate reusable Playwright .spec.ts test files from the app-navigator's app map and playbooks
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when you want to generate reusable Playwright .spec.ts test files from the app-navigator's app map and playbooks
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Retrieve defensible customer-voice evidence from BuildBetter MCP. Use when researching customer complaints, objections, praise, feature requests, needs, themes, exact quotes, account feedback, or changes over time, especially when direct external statements must be separated from internal commentary and supported with traceable signal or call evidence.
Use when you need to map the application's routes, pages, and components, build reusable Playwright playbooks, or perform a UI/UX audit across the application
Research BuildBetter data accurately through BuildBetter MCP. Use for open-ended questions about customer evidence, signals, calls, transcripts, people, companies, documents, knowledge pages, Projects Hub, or triage, and whenever an agent must choose reliable BuildBetter MCP read tools and return traceable evidence.
Use when working with BuildBetter's MCP server, bb CLI, Claude Code hooks, product-signal context, or preparing the BuildBetter Claude plugin for marketplace submission.
Use when working with BuildBetter's MCP server, bb CLI, Codex hooks, product-signal context, or preparing the BuildBetter Codex plugin for local sharing or submission.
Use when you need to map the application's routes, pages, and components, build reusable Playwright playbooks, or perform a UI/UX audit across the application
| name | generate-tests |
| description | Use when you want to generate reusable Playwright .spec.ts test files from the app-navigator's app map and playbooks |
| allowed-tools | Bash, Read, Write, Edit, Glob, Grep, Agent |
Generate reusable Playwright .spec.ts test files from your app-navigator map and playbooks.
Core principle: Mapped knowledge should produce executable tests. This skill reads what app-navigator discovered and writes a test suite that lives in your repo and runs with npx playwright test.
/app-navigator setup and you want persistent, rerunnable testsNot for: Backend/API tests, replacing hand-written integration tests, or one-shot verification (use trust-but-verify for that).
/generate-tests — generates smoke-depth tests (default)/generate-tests --depth functional — smoke + interaction tests/generate-tests --depth full — functional + edge cases + responsivedigraph generate_tests {
"Phase 1:\nPrerequisites" [shape=box];
"Phase 2:\nGenerate Auth" [shape=box];
"Phase 3:\nGenerate Page Tests" [shape=box];
"Phase 4:\nValidate (optional)" [shape=box];
"Done" [shape=doublecircle];
"Phase 1:\nPrerequisites" -> "Phase 2:\nGenerate Auth";
"Phase 2:\nGenerate Auth" -> "Phase 3:\nGenerate Page Tests";
"Phase 3:\nGenerate Page Tests" -> "Phase 4:\nValidate (optional)";
"Phase 4:\nValidate (optional)" -> "Done";
}
App map: Check ~/.claude/skills/app-navigator/app-map.md exists
/app-navigator setup first — I need the app map to generate tests." Offer to invoke it.Playwright installed: Check if @playwright/test is in root package.json devDependencies
pnpm add -D -w @playwright/test and npx playwright install chromiumConfig: Check if playwright.config.ts exists in the project root
import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.test.local' });
export default defineConfig({
testDir: './tests/e2e',
timeout: 30_000,
expect: { timeout: 10_000 },
fullyParallel: true,
retries: 1,
use: {
baseURL: process.env.BB_TEST_BASE_URL || 'http://localhost:5173',
trace: 'on-first-retry',
},
projects: [
{ name: 'setup', testMatch: /auth\.setup\.ts/, teardown: undefined },
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
storageState: 'tests/e2e/.auth/user.json',
},
dependencies: ['setup'],
},
],
});
Directories: Create tests/e2e/ and tests/e2e/.auth/ if they don't exist, then restrict auth artifacts:
mkdir -p tests/e2e/.auth
chmod 700 tests/e2e/.auth
Gitignore: Add tests/e2e/.auth/ and .env.test.local to .gitignore if not present
Read:
~/.claude/skills/app-navigator/playbooks/auth.md for the login flow~/.claude/projects/<project>/memory/reference_local_auth.md for credentialsCreate .env.test.local (gitignored) from memory credentials:
BB_TEST_EMAIL=<email from memory>
BB_TEST_PASSWORD=<password from memory>
BB_TEST_BASE_URL=<app URL from memory, default http://localhost:5173>
Use only local/test credentials. After writing .env.test.local, restrict it to the current user:
chmod 600 .env.test.local
Generate tests/e2e/auth.setup.ts:
BB_TEST_EMAIL and BB_TEST_PASSWORD from process.envhttp://localhost:5173/login)/auth/callback) back to the app domainBB_TEST_ORG env varstorageState to tests/e2e/.auth/user.json, then run chmod 600 tests/e2e/.auth/user.jsonThe auth setup captures cookies from all domains visited (app + auth), which preserves the auth session across tests. Treat tests/e2e/.auth/user.json as a local secret because it can contain bearer-equivalent session cookies.
Important: The exact login flow (field names, redirect chain, org selector) comes from playbooks/auth.md. Read it carefully — don't assume a generic login form.
Read:
~/.claude/skills/app-navigator/app-map.md — routes, key elements, interactions~/.claude/skills/app-navigator/playbooks/navigation.md — how to navigate~/.claude/skills/app-navigator/playbooks/interactions.md — common UI patternsFor each route in the app map, generate tests/e2e/<page-slug>.spec.ts.
Every generated file starts with:
// AUTO-GENERATED by generate-tests skill from app-navigator map
// Regenerate with: /generate-tests --depth <level>
// Last generated: YYYY-MM-DD
Depth: smoke (default)
test.describe('Page Name', () => {
test('page loads', async ({ page }) => {
await page.goto('/route');
await expect(page.locator('text=Expected Heading')).toBeVisible();
});
test('key elements present', async ({ page }) => {
await page.goto('/route');
// Assert 2-3 key elements from app-map "Key Elements" field
await expect(page.getByRole('button', { name: 'Create' })).toBeVisible();
});
});
Depth: functional — adds interaction tests:
test('create button opens dropdown', async ({ page }) => {
await page.goto('/route');
await page.getByRole('button', { name: 'Create' }).click();
await expect(page.getByText('Create Document')).toBeVisible();
});
Depth: full — adds edge cases + responsive:
test('responsive: mobile layout', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
await page.goto('/route');
await expect(page.locator('text=Expected Heading')).toBeVisible();
});
Test conventions:
// --- SMOKE ---, // --- FUNCTIONAL ---, // --- FULL ---storageState from the setup project — no re-logingetByRole, getByText, getByLabel — resilient to DOM changessettings.spec.tsAfter generating, offer:
"Tests generated. Want me to run them to make sure they pass?"
If yes:
npx playwright testIf no: files are ready. Do NOT auto-commit — let the user decide.
Running /generate-tests again overwrites all files with the AUTO-GENERATED header. Hand-written test files without the header are NOT touched.
.env.test.local — it contains real credentials.tests/e2e/.auth/ — it contains authenticated browser state."Tests generated at
tests/e2e/. Run them withnpx playwright test.Want to verify your current feature branch against its plan? Run
/trust-but-verify."
If the user says yes, invoke the trust-but-verify skill.
reference_local_auth.md in project memory → .env.test.local