---
name: e2e-plan
description: Explore a module with Playwright MCP and produce a structured spec markdown file
---

# /e2e-plan - Explore Module and Create Spec

Generate or update `<workspace>/specs/{module}.spec.md` by exploring the running app with Playwright MCP.

## Workspace

This skill supports two layouts:

- **Single-app** (`<root>/e2e/playwright.config.ts`): resolve `<workspace>/` to `e2e/`.
- **Multi-app** (`<root>/<app>/playwright.config.ts` per app, e.g. `web/`, `backoffice/`): resolve `<workspace>/` to that app's folder.

Detect by probing for `playwright.config.ts`. If multiple apps match (or none), ASK the user which workspace to target before proceeding.

## Scope

- Works inside the resolved E2E workspace.
- Produces planning output only. Do not generate tests here.

## Knowledge References

### Required

1. `knowledge/writing-tests/test-organization.md`
2. `knowledge/humand/conventions.md`
3. `knowledge/humand/configuration.md`

### Conditional

1. `knowledge/writing-tests/forms.md`
2. `knowledge/patterns/page-objects.md`
3. `knowledge/patterns/react-patterns.md`
4. `knowledge/patterns/authentication.md`

Resolve which conditional docs apply before editing the spec, and list them in your working response.

Also follow:

- `rules/playwright-planner.mdc`

## Inputs

- `module` (required)
- `url` (required)
- `app` (required for multi-app, optional for single-app)
- `community` (required) — tenant key from `shared/communities.ts` the suite will target. If the module needs a new tenant, agree on the key + Humand `displayName` before continuing.
- `roles` (required when the workspace exposes a `role` fixture option, e.g. `shared/roles.ts`) — one or more role keys (`admin`, `leader`, `collaborator-1`, `collaborator-2`, etc.). Capture the role per scenario when the suite needs more than one perspective.
- `owner` (optional, default `unassigned`)

If a required input is missing, ask once and continue.

## Workflow

### 0) Resolve app context

Read `.e2e/context.local.json`. If missing, suggest running `/e2e-setup` first. If the dev opts to proceed without it, run in **degraded mode** — explore the live UI but do not cross-reference app source code.

When the target workspace matches an `apps[<name>]` key (e.g. workspace `web` ↔ `apps.web`), use that app's `repoPath` to validate route names, feature naming, and to read translation files when locating UI labels.

### 1) Resolve the workspace

- Detect single-app vs multi-app.
- For multi-app, confirm the target `<app>` from the `app` input or ask once.

### 2) Inspect the local contract

Read:

- the local `package.json` (workspace root in single-app, repo root in multi-app)
- `<workspace>/playwright.config.ts`
- `<workspace>/tests/auth.setup.ts`
- `<workspace>/fixtures/base.fixture.ts`
- existing module files under `<workspace>/specs/`, `<workspace>/tests/`, and `<workspace>/pages/` when present

Use that context to align locale, auth, fixture boundaries, and benchmark-reset assumptions before exploring.

### 3) Explore with MCP

- Confirm the app is reachable.
- Navigate to the target URL.
- Use snapshots and interactions to discover visible states, main actions, validations, and permission-dependent behavior.
- Prefer observable behavior over implementation detail.
- Do not guess selectors for complex regions that are not reliably inspectable.

### 4) Build the scenario set

**Critical-flow gate (do this first).** E2E is the top of the pyramid: it only
covers **critical business flows** — an end-to-end sequence that changes state
and has user/business value (create/edit/delete and verify the effect, complete
a multi-step flow, a cross-app hand-off). Granular UI behavior — a field
renders, a button is disabled, a selector lists the right options, copy is
correct, a single step or route navigates — belongs to **unit / component
tests**, not E2E.

For each candidate behavior you discovered while exploring, decide:

- _"Does this verify a flow that changes business state, or just UI rendering /
  form validation / navigation?"_
- Clear critical flow → keep it.
- Clearly granular → drop it (do not add it to the spec; no need to catalogue it).
- **Ambiguous → ASK the user** before adding it: briefly state the candidate and
  why it's borderline, and let them confirm whether it earns an E2E test. When in
  doubt, open the discussion rather than silently padding the suite.

Only scenarios that pass this gate proceed to classification. The goal is the
filter itself: keep simple, non-critical checks out of the E2E suite.

Then classify the surviving scenarios with Humand tags:

- `@smoke`
- `@regression`
- `@functional`

Include edge cases only when they are relevant and observable.

### 5) Write the spec

Use this canonical structure:

1. Title
2. Owner
3. Module
4. Base URL
5. `## Preconditions`
6. `## Smoke`
7. `## Regression`
8. `## Functional`
9. `## Data dependencies / notes`

Each scenario must include:

- ID
- Name
- Tags
- Steps
- Expected result

### 6) Quality gate

Before finishing, verify:

- no duplicate scenarios
- the scope stays inside the target module
- preconditions include real data or permission dependencies when needed
- the spec is precise enough for `/e2e-generate` to consume without reinterpretation

### 7) Cleanup

Exploration writes throwaway page snapshots and console logs to `<root>/.playwright-mcp/`. Once the spec is written:

- call `browser_close` to end the MCP session and trigger any consumer hooks
- delete the `.playwright-mcp/` directory at the project root (or its contents)

These artifacts are not consumed by `/e2e-generate` and should not be committed.

## MCP tools used

- `browser_navigate`
- `browser_snapshot`
- `browser_click`
- `browser_type`
- `browser_close`

## Out of scope

- generating `.spec.ts` files
- updating page objects
- running Playwright suites
