| name | ui-test-builder |
| description | Bootstrap and maintain Playwright UI test coverage for a web app. Triangulates docs, codebase, and live-app exploration into a Flow Map (structured catalog of user behaviors worth testing), then generates Playwright tests from it batch by batch. Use when the user wants to add UI tests, map out their app's flows for testing, or update tests against an evolved app. Runs across many sessions over many days — eager persistence to the Flow Map, the repo's docs location, and the repo's test directory. |
| metadata | {"version":"1.0.0"} |
UI Test Builder
Bootstraps and maintains UI test coverage by producing a Flow Map — a structured catalog of
every user-facing behavior worth testing — and then generating a Playwright test suite from it.
When to use
- The user wants to add UI test coverage to an app that lacks it.
- The user wants only a Flow Map (no tests yet).
- The user wants to regenerate tests against an app that has evolved.
- The user wants help understanding what flows their app even has.
Choosing a workflow
This skill exposes two workflows. Detect the state of the repo and route:
| Repo state | User intent | Workflow |
|---|
| No Flow Map | Any | FlowMap — discover + reconcile (docs–reconcile) |
| Flow Map exists, tests incomplete | Continue building tests | Tests — capability resolution + test generation (resolve–generate) |
| Flow Map exists, app has changed | Update | FlowMap in regeneration mode, then Tests |
The user invokes this skill once. The agent reads the repo state, opens with a stateful recap (see
Sessions.md), and routes to the right workflow. If state is ambiguous, ask —
recommend-then-ask.
Core principles
- The Flow Map is the coverage definition. Every Flow in the Map gets a test; nothing outside it
does.
- Triangulate, don't trust one source. Docs, codebase, and browser exploration each see
different things. Disagreements are often where the value is.
- Conversational, not CLI. No flags. Decisions are made inline.
- Eager persistence. Every decision lands in a canonical artifact as it's made — no
session-state file. If a decision matters across sessions, it lands in an artifact; if it doesn't
land in an artifact, it didn't happen.
Interaction style
- Recommend-then-ask. Do the analysis, present a conclusion, the user confirms or redirects.
User effort scales with disagreement, not with the number of decisions.
- Surface every decision — even when deciding autonomously. Decide visibly when the answer is
clearly low-stakes and inferable; confirm when there's a strong default but the user should have a
chance to redirect; ask when there's a real trade-off or the answer requires domain knowledge the
agent lacks. A blocked phase (missing inputs, unreachable service, failed prerequisite) is itself
a decision — announce what's blocked, why, and propose concrete remedies. Never let a phase
silently no-op.
- One question per turn. Absolute rule. No batched "I have 10 questions" moments, no "also,
while we're here…" follow-ups. If two questions seem related, ask the first, wait for the answer,
then ask the second — the user's answer often changes the second question. Filesystem checkpoints
handle interruption, so pacing doesn't have to compensate. Decisions are paced inline at the
moment of need.
- Rationale capture for significant decisions only — skipping a section, an unusual Capability
strategy, a
skipped Flow. Bar: would future-me wonder why? Don't ask for rationale on every
routine decision; that's friction.
- Sub-agents are off-the-shelf. Use stock
Explore (codebase analysis) and general-purpose
(everything else). No custom agent definitions, no promotion path — detailed instructions live in
the workflow prompts.
- Don't push through context fade. When a session is running long, propose a break at the next
natural threshold. See Sessions.md.
Terminology
- User Flow — atomic, intent-oriented unit (a single user goal). Described in intent terms,
never UI/selector terms. A Flow ends when its named intent is achieved or definitively blocked; if
you can't write a one-sentence success assertion for a candidate, it's too big or too vague —
split or sharpen. The Flow's name is its canonical identifier — must be unique within the Map;
renames during reconcile cascade through downstream references (Journeys, tests, strategy doc).
- Branch — named error/edge path attached to a step of a parent Flow. Each Branch becomes its
own
test() block in generated tests so failures point at a specific branch.
- Journey — named composition of Flows for a higher-level goal. References Flows by name; has no
steps of its own. Not itself a Flow; does not appear in the test generation list.
- Capability — shared prerequisite implemented as code (auth, data cleanup, fixtures, flags).
Tagged on Flows during discovery against the Capabilities catalog, resolved as
a strategy in resolve. Qualification rule: see Capabilities.md.
- Provenance — sources that contributed a Flow (e.g. "extracted from README", "discovered via
browser exploration", "implied by codebase route", "stated by user in interview").
- Status — per-Flow workflow marker:
discovered → confirmed → tested | skipped. Drives
resumption across sessions.
Persistence
The skill defines the Flow Map's shape but not the surrounding doc layout. The target repo's
existing documentation conventions — where docs live (root markdown, docs/, wiki/, etc.), how
they're styled, what filenames are conventional — are surfaced as a side-effect of docs (which reads
existing docs) and browser/code (which read the running app and codebase). Use what's discovered:
write all decisions into the repo's docs location in whatever style the repo already uses.
The Flow Map is the one artifact whose name is canonical (default ui-flow-map.md); cross-cutting
decisions, characterization, and scope land alongside the repo's other docs as project-shaped prose.
If a repo has no documentation convention yet, propose one and confirm with the user before writing.
| Artifact | Where |
|---|
| Flow Map | Repo's docs location, ui-flow-map.md |
| Cross-cutting decisions (scope, characterization, capability strategies, skip rationale) | Repo's docs location, conventional filename |
| App-testability suggestions | Repo's docs location, app-testability-suggestions.md |
| Capability code | Repo's test directory (Playwright convention for the project's language) |
| Generated tests | Repo's test directory |
The skill does not modify the app under test. When the skill hits a wall that is an app-side
problem (a resource that can't be deleted, missing data-testid conventions, no programmatic state
reset, etc.), it captures the issue as an entry in app-testability-suggestions.md rather than
working around it in test code. The suggestions doc is a punch list for the app team — not a
deliverable this skill implements.
The project's docs and test code are the source of truth — no session-state file. Hand-edits between
sessions are the new truth; the agent reads artifacts fresh at session start and adapts.
Inputs
Discover first → confirm if uncertain → ask if missing. See Inputs.md for the full
discovery matrix, scope handling, and environment tolerance.
Multi-session reality
A run of this pipeline spans many sessions across many days. Each workflow opens with a stateful
recap derived from the Flow Map and cross-cutting decisions doc, marks Flow status as it goes, and
emits a one-line summary on close. See Sessions.md.