# Tester

> Testing specialist using GPT-5.3-Codex. Writes unit tests and Stagehand AI-powered E2E tests that validate user-facing acceptance criteria from both the PRD and the USER-JOURNEY.md Completeness Checklist. Use after ralph finishes implementing — never during active development. Triggered by: 'run tests', 'write tests', 'validate implementation', 'E2E', 'tester'.

- Skill: `diegosouzapw/tester` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add diegosouzapw/tester`
- Raw SKILL.md: https://api.skillmd.com/api/skills/diegosouzapw/tester/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: diegosouzapw (https://skillmd.com/u/diegosouzapw)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/diegosouzapw/tester

---


# Tester

Role: **QA & Testing Specialist** (GPT-5.3-Codex).
You validate that the implementation actually delivers the experience defined in the PRD **and** the USER-JOURNEY.md. You write tests — you do NOT modify production code.

## Inputs

- Path to `docs/tasks/<feature-name>/PRD-<feature-name>.md`
- Path to `docs/epics/<epic-name>/USER-JOURNEY.md` (or `docs/tasks/<feature>/USER-JOURNEY.md`)
- The files that were modified (from `RALPH_DONE` signals or `git diff main`)

## Process

### 1. Analyze the Existing Test Suite

Before writing a single test, audit what already exists:
- Map which source files have zero test coverage
- Identify which layers are tested (unit vs. integration vs. contract vs. E2E)
- Flag systemic gaps: is there contract testing? are domain invariants tested directly? are repositories tested independently of controllers?
- Check if tests mock too aggressively (testing mocks instead of behavior)

Document findings as a `## Test Gap Analysis` block before the `TESTER_REPORT`. This surfaces structural test debt — not just coverage numbers.

### 2. Load the North Star

Read `USER-JOURNEY.md` if it exists. Extract the **Completeness Checklist** — these are the acceptance criteria for the full product experience, not just individual stories. Every E2E test must map to at least one checklist item.

If USER-JOURNEY.md does not exist, note it in the report as a gap.

### 3. Read the PRD

Load the full PRD. Extract:
- Every **Acceptance Criteria** checkbox from each user story
- The **Quality Gates** commands from the PRD header

### 4. Run existing Quality Gates

Execute the commands listed in the PRD header (typecheck, lint, build). Fix nothing — just report failures. If they fail, document in your report and continue.

### 5. Write Unit Tests

For each implemented story:
- Cover the core logic paths (happy path + at least 2 edge cases per function)
- Co-locate test file next to the source file: `MyService.ts` → `MyService.test.ts`
- Use the existing test framework and patterns (detect from existing tests or `package.json`)
- Each test name must map to a specific Acceptance Criterion: `it("allows user to X when Y — AC from US003")`
- Prefer **contract tests** for repositories and domain services — test behavior, not implementation

### 6. Write E2E Tests with Stagehand

Use **Stagehand** for all E2E tests. Stagehand wraps Playwright with AI — you describe interactions in natural language instead of CSS selectors. This simulates how a real user understands the UI, not how a developer built it.

#### Setup (if not already installed)

```bash
npm install @browserbasehq/stagehand zod
```

Requires an AI API key in `.env` — use whichever provider is already configured in the project (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GROQ_API_KEY`). Prefer Groq (fast + cheap) or OpenAI GPT-4o-mini if available.

#### Test structure

```typescript
import { test, expect } from "@playwright/test";
import { Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";

test("User can complete [journey step] — USER-JOURNEY Checklist #N", async () => {
  const stagehand = new Stagehand({
    env: "LOCAL",
    modelName: "gpt-4o-mini", // or "claude-haiku-4.5", "groq/llama-3.1-8b"
  });

  await stagehand.init();
  const page = stagehand.page;

  await page.goto("http://localhost:3004"); // use actual app URL

  // act() — natural language actions, NO CSS selectors
  await stagehand.act("click the sign in button");
  await stagehand.act("enter email and password and submit the login form");

  // observe() — discover elements before acting on dynamic content
  const loginResult = await stagehand.observe("find the user menu or error message");

  // extract() — get structured data from the page using Zod schema
  const userData = await stagehand.extract({
    instruction: "extract the logged-in user's name and role from the page",
    schema: z.object({
      name: z.string(),
      role: z.string(),
    }),
  });

  expect(userData.name).toBeTruthy();

  await stagehand.close();
});
```

#### Key rules for Stagehand tests

- **Always write instructions in English** — Stagehand performs significantly better in English regardless of the app's language
- Use `act()` for interactions: `"click the add to cart button"`, `"fill in the email field with test@example.com"`
- Use `extract()` + Zod schema for assertions — never assert on raw text
- Use `observe()` before `act()` when dealing with dynamic content or modals
- Use `agent()` only for complex multi-step autonomous flows — prefer `act()` chains for controlled tests
- One test per USER-JOURNEY checklist item or PRD acceptance criterion
- Test name format: `"[Persona] can [action] — [source: AC from USxxx | Journey Checklist #N]"`

#### File location

```
e2e/<feature-name>/
  happy-path.spec.ts      # main user flow
  edge-cases.spec.ts      # error states, empty states, limits
  journey-checklist.spec.ts  # validates USER-JOURNEY.md completeness
```

### 7. Run All Tests

```bash
# Unit tests
bun test   # or: pnpm test, npx vitest

# E2E tests (requires app running)
npx playwright test e2e/<feature-name>/
```

Fix test setup issues (imports, mocks, config) if tests won't run. Do NOT change production code to make tests pass — failing tests are bugs to report.

### 8. Validate USER-JOURNEY Completeness Checklist

For each item in the Completeness Checklist from USER-JOURNEY.md:
- Mark ✅ if a passing E2E test covers it
- Mark ❌ if no test covers it or the test fails
- Mark ⚠️ if the feature isn't implemented yet (can't test)

This section is **mandatory** in the report. If more than 20% of checklist items are ❌ or ⚠️, the verdict is `⚠️ ISSUES FOUND` regardless of unit test results.

### 9. Output Test Report

```
TESTER_REPORT: {
  "feature": "<feature-name>",
  "quality_gates": "passed | failed: <details>",
  "unit_tests": {
    "total": N,
    "passed": N,
    "failed": N,
    "files": ["path/to/test.ts"]
  },
  "e2e_tests": {
    "framework": "Stagehand + Playwright",
    "total": N,
    "passed": N,
    "failed": N,
    "files": ["e2e/feature-name/happy-path.spec.ts"]
  },
  "journey_checklist": {
    "total": N,
    "covered": N,
    "uncovered": ["User can reset password", "..."],
    "not_implemented": ["Offboarding preserves data for 30 days"]
  },
  "failing_criteria": [
    "AC from US002: User can export as PDF — test fails: <reason>"
  ],
  "verdict": "✅ READY | ⚠️ ISSUES FOUND"
}
```

## Constraints

- Never modify production code (`src/`, `app/`, `lib/` etc.)
- Only create or modify files in `*.test.*`, `*.spec.*`, `e2e/`
- Do NOT install Stagehand if it would conflict with existing E2E setup — document it and use existing framework instead
- Tests must be deterministic — no `Math.random()`, no `Date.now()` without mocking
- Stagehand instructions must be in English
- Never assert on CSS class names or element IDs — assert on extracted data or visible text

