/arc:testing
Run & fix tests
—What it does
Testing runs your test suite and helps fix what's broken. For unit tests (vitest, jest), it's straightforward—run, read failures, fix. For e2e tests (playwright), it spawns a dedicated agent that can handle the verbose output, retry flaky tests, and work through failures methodically. Includes specialized guidance for auth testing with Clerk and WorkOS.
—Why it exists
E2e tests are painful—slow, flaky, verbose output that fills your context. Testing handles this by running playwright in a background agent that can retry, screenshot failures, and fix issues without overwhelming your main session. Auth testing gets special treatment because mocking Clerk/WorkOS is tricky.
—Design decisions
- —Framework detection is automatic. It finds your test config and runs the right thing.
- —E2e tests get special treatment. Background agent handles retries and verbose output.
- —Auth testing guidance built in. Clerk mocks, WorkOS mocks, test bypass endpoints.
—Agents
Source document
Testing Strategy Workflow
Create comprehensive test strategies covering the full test pyramid. Execute with specialist agents.
Agents
This skill uses 3 writers + 2 runners:
| Agent | Model | Purpose | Framework |
|---|---|---|---|
unit-test-writer | sonnet | Write unit tests | vitest |
integration-test-writer | sonnet | Write integration tests (API, auth) | vitest + MSW |
e2e-test-writer | opus | Write E2E tests | Playwright |
test-runner | haiku | Run vitest, analyze failures | vitest |
e2e-runner | opus | Run Playwright, fix issues, iterate | Playwright |
Test Pyramid:
/\
/ \ E2E (few)
/────\ - Critical user journeys
/ \ - Auth flows
/────────\ Integration (some)
/ \ - API interactions
/────────────\ - Component + state
/ \ Unit (many)
/────────────────\- Pure functions
- Isolated components
Process
Step 1: Determine Intent
AskUserQuestion:
question: "What would you like to do?"
header: "Testing Intent"
options:
- label: "Create test strategy"
description: "Full test plan across unit, integration, and E2E — then dispatch agents"
- label: "Run tests"
description: "Execute existing tests with the appropriate runner"
- label: "Fix failing tests"
description: "Dispatch debugger or e2e-runner to fix broken tests"
- label: "Review coverage"
description: "Analyze gaps in test coverage and recommend improvements"
Step 2: Understand What's Being Tested
Gather context:
- What feature or component?
- Does it have auth? (Clerk, WorkOS, custom)
- Does it call APIs?
- Does it have critical user flows?
- What's the risk level?
Step 3: Create Test Plan
For each feature, plan across all levels:
## Test Plan: [Feature Name]
### Risk Assessment
- **Criticality**: [high/medium/low]
- **Has Auth**: [yes/no — Clerk/WorkOS/custom]
- **Has API Calls**: [yes/no]
- **User-Facing**: [yes/no]
### Unit Tests (vitest)
**Agent:** unit-test-writer
| Test Case | What it Verifies |
|-----------|------------------|
| `should [behavior]` | [Pure function/component behavior] |
| `should [behavior]` | [Edge case handling] |
| `should [behavior]` | [Error throwing] |
**Files to create:**
- `src/[path]/[module].test.ts`
### Integration Tests (vitest + MSW)
**Agent:** integration-test-writer
| Test Case | What it Verifies |
|-----------|------------------|
| `should [behavior]` | [Component + API interaction] |
| `should [behavior]` | [Auth state handling] |
| `should [behavior]` | [Error from API] |
**Mocking required:**
- API endpoints: [list]
- Auth: [Clerk/WorkOS mock setup]
**Files to create:**
- `src/[path]/[feature].integration.test.ts`
### E2E Tests (Playwright)
**Agent:** e2e-test-writer
| Test Case | What it Verifies |
|-----------|------------------|
| `should [complete flow]` | [Happy path journey] |
| `should [handle error]` | [User-visible error] |
| `should [auth flow]` | [Login/logout if applicable] |
**Auth setup required:**
- Provider: [Clerk/WorkOS/none]
- Test user: [env var names]
**Files to create:**
- `tests/[feature].spec.ts`
- `tests/auth.setup.ts` (if auth needed)
Step 4: Execute Test Plan
Dispatch specialists in order:
1. Unit tests first (fastest feedback):
Task [unit-test-writer] model: sonnet: "Write unit tests for [feature].
Test cases from plan:
[paste unit test cases]
Files to create: [paths]
Follow vitest patterns from testing-patterns.md"
2. Integration tests second:
Task [integration-test-writer] model: sonnet: "Write integration tests for [feature].
Test cases from plan:
[paste integration test cases]
Auth: [Clerk/WorkOS/none]
API mocking: [endpoints to mock]
Files to create: [paths]"
3. E2E tests last:
Task [e2e-test-writer] model: opus: "Write E2E tests for [feature].
Test cases from plan:
[paste e2e test cases]
Auth: [Clerk/WorkOS/none]
Fixtures needed: [list]
Files to create: [paths]"
Step 5: Run and Verify
Unit + Integration (inline):
pnpm vitest run
E2E (background agent — avoids terminal issues):
Task [e2e-runner] model: opus: "Run E2E tests and fix any failures.
Test files: [list]
Iterate until green or report blockers."
Auth Testing Quick Reference
Clerk Testing
Integration tests (vitest):
- Mock
useAuthanduseUserhooks - Test loading, signed in, signed out states
- Mock
getTokenfor API calls
E2E tests (Playwright):
- Create
tests/auth.setup.tsfor login flow - Store session in
playwright/.auth/user.json - Use
storageStatein playwright.config.ts
Common issues:
- ❌ Trying to mock ClerkProvider (mock hooks instead)
- ❌ Not handling
isLoaded: falsestate - ❌ Hardcoding tokens (use
getTokenmock)
WorkOS Testing
Integration tests (vitest):
- Mock
getUserfrom@workos-inc/authkit-nextjs - Test with full user object including
organizationId,role,permissions - Test SSO redirect behavior
E2E tests (Playwright):
- SSO flows are slow — consider test bypass endpoint
- Create
/api/auth/test-loginfor faster auth (test env only) - Store session state after auth
Common issues:
- ❌ Forgetting
organizationIdin mock (required for org-level features) - ❌ Not testing permission checks
- ❌ SSO redirect timing issues (add proper waits)
Bypass Auth for Speed
For faster E2E tests, create a test-only auth endpoint:
// app/api/auth/test-login/route.ts
// ONLY available in test/development
export async function POST(request: Request) {
if (process.env.NODE_ENV === "production") {
return new Response("Not found", { status: 404 });
}
// Create session directly without SSO flow
}
Test Patterns
What to Test at Each Level
| Level | Test | Don't Test |
|---|---|---|
| Unit | Pure functions, isolated components, hooks | API calls, multi-component flows |
| Integration | Component + API, auth states, form submissions | Full user journeys |
| E2E | Critical paths, auth flows, checkout/signup | Every possible input |
Coverage Guidelines
| Feature Type | Unit | Integration | E2E |
|---|---|---|---|
| Utility functions | ✅ heavy | ❌ none | ❌ none |
| UI components | ✅ rendering | ✅ with state | ❌ only if critical |
| Forms | ✅ validation | ✅ submission | ✅ critical forms |
| API routes | ✅ handlers | ✅ with mocking | ❌ via E2E |
| Auth flows | ❌ none | ✅ mock states | ✅ real flow |
| Checkout/payment | ✅ calculations | ✅ flow | ✅ full journey |
Fail-Fast Configuration
Tests must fail fast. Never:
- Global timeout of minutes
- 5+ retries to mask flakiness
- Arbitrary sleeps
Playwright config:
export default defineConfig({
timeout: 30_000, // 30s max per test
expect: {
timeout: 5_000, // 5s for assertions
},
use: {
actionTimeout: 10_000, // 10s per action
},
});