playwright-evidence · git:20260806.b506b65 · 2026-08-06 · sha256 db6218a93d6501df
playwright-evidence git:20260806.b506b65A
Immutable. This exact content never changes and is served at /api/v1/blob/db6218a93d6501df.
---
name: playwright-evidence
description: >
Use when capturing E2E test evidence (screenshots, videos, traces) and storing
them in .copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/{story}/evidence/ for agents to consume. Covers
Playwright setup, on-failure capture, trace collection, and evidence manifest
generation.
---
# Playwright Evidence Skill
## Overview
This skill captures evidence and stores it under `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/{story}/evidence/`,
keeping the story key consistent with all other SDLC phase artefacts. Agents read the
manifest and decide what to publish.
```
E2E Test Run → Capture Evidence → Write Manifest → Agent publishes
Playwright screenshots .copilot-tracking/skraft-plans/{projectSlug}/ (orchestrator
(on failure) videos deliver/{story}/ or other agent)
traces evidence/
report manifest.md
```
`{story}` is the story slug passed as `SKRAFT_STORY_ID` env var (e.g. `42-add-eligibility-check`).
All other phases follow the same convention: `discuss/ac-draft-{story}.md`, `design/diagrams-{story}.md`,
`distill/impl-plan-{story}.md` — evidence is no exception.
**Scope of this skill:** capture, name, store, and list evidence. Publishing is the agent's responsibility.
## Docker Dependency Freshness (MANDATORY)
Before running ANY e2e verification — first run or re-run after a fix — rebuild and restart every
Docker Compose / Testcontainers dependency the suite talks to (`docker compose down && docker compose
up -d --build`, or the equivalent Testcontainers container recreation). Do NOT reuse a container left
running from a previous session or a previous story.
**Why:** a stale container silently passes tests against yesterday's image — the suite is green but
proves nothing about the current code. This exact failure mode (e2e passing against an out-of-date
dependency container) reached DELIVER undetected on a prior epic and was only caught by a manual
rework pass. Treat it as a checklist item, not an optional troubleshooting step:
1. Tear down existing dependency containers for this story before the FIRST test run of the session.
2. Rebuild images (`--build` / equivalent) so local code/config changes are actually picked up.
3. Re-run the full e2e suite after every dependency rebuild — a partial re-run against a mixed
old/new environment is worse than no run, since it produces a false-positive green.
4. Record the rebuild in the evidence manifest run notes (e.g. `containers: rebuilt`) so reviewers
can see freshness was verified, not assumed.
## Playwright Setup (TypeScript)
Install dependencies:
```bash
npm install -D @playwright/test
npx playwright install --with-deps chromium
```
Configure via `playwright.config.ts` at project root. Reference `references/playwright-ts-setup.md`
for full configuration options, parallel settings, and browser lifecycle management.
## Screenshot Capture
Wire an `afterEach` hook to capture on failure:
```typescript
import { test, expect } from '@playwright/test';
test.afterEach(async ({ page }, testInfo) => {
if (testInfo.status !== testInfo.expectedStatus) {
const screenshotPath = `evidence/screenshots/${testInfo.title.replace(/\s+/g, '-')}-${Date.now()}.png`;
await page.screenshot({ path: screenshotPath, fullPage: true });
testInfo.attachments.push({ name: 'screenshot', path: screenshotPath, contentType: 'image/png' });
}
});
```
Naming convention: `{test-title}-{timestamp}.png`. Output dir: `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/{story}/evidence/screenshots/`.
`{story}` comes from the `SKRAFT_STORY_ID` environment variable.
Using `testInfo.attachments` makes the screenshot appear inline in the HTML report.
Reference `references/screenshot-and-video.md` for all `page.screenshot()` options and
on-failure hook patterns.
## Video Recording
Set `video: 'retain-on-failure'` in `playwright.config.ts`:
```typescript
use: {
video: { mode: 'retain-on-failure', size: { width: 1280, height: 720 } },
}
```
CLI override: `npx playwright test --video=retain-on-failure`
Set `outputDir` in `playwright.config.ts` to `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/${process.env.SKRAFT_STORY_ID}/evidence`
so Playwright writes all test-results (videos, traces) under the story-keyed path.
No manual context management required — the test runner handles lifecycle.
Reference `references/screenshot-and-video.md` for all video config options.
## Trace Files
Set `trace: 'retain-on-failure'` in `playwright.config.ts` for automatic capture:
```typescript
use: {
trace: 'retain-on-failure',
}
```
CLI: `npx playwright test --trace=on` to capture traces for all tests.
For manual control within a test:
```typescript
await context.tracing.start({ screenshots: true, snapshots: true, sources: true });
// ... test steps ...
await context.tracing.stop({ path: `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/${process.env.SKRAFT_STORY_ID}/evidence/traces/trace.zip` });
```
View a trace locally: `npx playwright show-trace evidence/traces/trace.zip`
Traces contain DOM snapshots, network requests, console logs, and source context. Prefer traces
over screenshots when diagnosing flaky tests. Reference `references/trace-viewer.md` for all options.
## Test Report Generation
Configure multi-reporter output in `playwright.config.ts`:
```typescript
reporter: [
['html', { outputFolder: `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/${process.env.SKRAFT_STORY_ID}/evidence/reports` }],
['junit', { outputFile: `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/${process.env.SKRAFT_STORY_ID}/evidence/reports/results.xml` }],
],
// SKRAFT_STORY_ID must be set before running: e.g. SKRAFT_STORY_ID=42-add-eligibility-check npx playwright test
```
CLI equivalents:
```bash
npx playwright test --reporter=html
npx playwright test --reporter=junit
npx playwright show-report
```
The HTML report is uploaded as a CI artifact. The JUnit XML is consumed by CI status checks.
## Evidence Manifest
After the test run, write `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/{story}/evidence/manifest.md` so agents know what was captured.
The story key makes the manifest unambiguous when multiple stories run in sequence:
```markdown
# Evidence Manifest
## Run
- timestamp: 2026-05-15T10:30:00Z
- status: failed (2 failures, 8 passed)
- duration: 45s
- containers: rebuilt
## Files
| Type | Path | Test |
|---|---|---|
| screenshot | .copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/42-add-eligibility-check/evidence/screenshots/underage-driver-rejected-1715770200000.png | underage driver should be rejected |
| trace | .copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/42-add-eligibility-check/evidence/traces/policy-flow-1715770200000.zip | full policy flow |
| report | .copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/42-add-eligibility-check/evidence/reports/index.html | — |
| junit | .copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/42-add-eligibility-check/evidence/reports/results.xml | — |
```
The orchestrator reads this manifest by looking up the active story from `state.md` and resolving
`.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/{story}/evidence/manifest.md`.
## CI Configuration
Structure the GitHub Actions job:
1. `actions/setup-node@v4` with Node 20
2. `npm ci`
3. `npx playwright install --with-deps chromium` (cache `~/.cache/ms-playwright`)
4. `npx playwright test --reporter=html,junit`
5. `actions/upload-artifact@v4` — upload `.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/` on failure
Agents that consume the manifest handle publishing (GitHub comment, PR annotation, etc.).
Reference `references/ci-configuration.md` for the full workflow YAML.
## Evidence Retention Policy
Add to `.gitignore`:
```
.copilot-tracking/skraft-plans/{projectSlug}/changes/{date}/evidence/
playwright-report/
test-results/
```
In CI, set `retention-days: 7` on `upload-artifact` for failure evidence. In test code, skip
writing evidence files when `testInfo.status === testInfo.expectedStatus` (test passed) to
avoid accumulating passing-run artifacts.
## References
- `references/playwright-ts-setup.md` — npm install, CLI, `playwright.config.ts`, parallel settings
- `references/screenshot-and-video.md` — `page.screenshot()` options, video recording, on-failure hooks
- `references/trace-viewer.md` — tracing config, `context.tracing` API, trace viewer CLI
- `references/ci-configuration.md` — full GitHub Actions workflow YAML, caching, secrets
## Examples
- `examples/01-basic-screenshot.md` — `afterEach` on-failure screenshot with eligibility test
- `examples/02-video-on-failure.md` — `retain-on-failure` video config, accessing video path
- `examples/03-trace-upload.md` — manual trace capture with all options, stop and save
- `examples/04-evidence-manifest.md` — writing the manifest after a test run