Receber por email
← Voltar para o catálogo

verify

Verify frontend changes against spec acceptance criteria. Uses Playwright MCP for browser interaction.

114estrelas
Atualizado há 6 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add opslane/opslane

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/verify-opslane/svg)](https://www.skillteca.com.br/skills/verify-opslane)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

/verify

Verify your frontend changes before pushing.

Prerequisites

  • Dev server running (e.g. npm run dev)
  • Playwright MCP configured in Claude Code (see install section below)
  • Auth set up if app requires login (/verify-setup)

Playwright MCP Install

If Playwright MCP is not available, show this:

/verify requires Playwright MCP for browser interaction.
Install:
```
claude mcp add playwright -- npx @playwright/mcp@next --storage-state .verify/auth.json --isolated --caps=devtools --output-dir .verify/mcp-output
```
@next is required — video + trace tools ship only in the alpha. --caps=devtools exposes them; --output-dir pins a known drop zone.
Restart Claude Code, then re-run /verify.

Conversation Flow

This skill is turn-based. Each turn has a trigger and a bounded set of actions. Never skip ahead.

Turn 1: Spec Intake

Trigger: User invokes /verify.

Check for arguments first. If the user passed a file path as an argument (e.g. /verify path/to/spec.md), skip this turn entirely — go straight to Turn 2 using that path.

Otherwise, try smart spec discovery first:

find . -maxdepth 3 -name "*.md" \( -name "*spec*" -o -name "*plan*" -o -name "*requirements*" -o -name "*acceptance*" \) -not -path "./.verify/*" -not -path "./node_modules/*" -not -path "./.git/*" 2>/dev/null | head -5
  • If exactly 1 file found: suggest it. "Found a likely spec: path/to/spec.md. Use this? (y/n)"
  • If multiple files found: show the list and ask the user to pick one.
  • If no files found: "What spec are you verifying? Paste the spec content or give a file path."

Do not call any other tools. End your response and wait.

Turn 2: Pre-flight + MCP Check

Trigger: User has provided a spec (pasted content, file path, or confirmed a discovered file).

  1. If they gave a file path — read the file with the Read tool.
  2. If they pasted content — mkdir -p .verify then write to .verify/spec.md.

MCP preflight: Check if Playwright MCP is available:

Use ListMcpResourcesTool with server="playwright"
  • If the server exists → Playwright MCP is available, proceed.
  • If "Server not found" → show the install instructions from the Prerequisites section. Stop.
  • If MCP is configured but non-responsive (e.g. connection error), show: "Playwright MCP is configured but not responding. Try restarting Claude Code."

Dev server check:

BASE_URL=$(cat .verify/config.json 2>/dev/null | grep -o '"baseUrl"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o 'http[^"]*' || echo "http://localhost:3000")
curl -sf "$BASE_URL" > /dev/null 2>&1 || { echo "Dev server not running at $BASE_URL"; exit 1; }

Auth check: Navigate to the app and check if you're logged in:

Use mcp__playwright__browser_navigate to go to $BASE_URL
Use mcp__playwright__browser_snapshot to read the page

If the page shows a login/signup form instead of authenticated content, try these sources in order:

1. Credentials file referenced from .verify/config.json. Check for a credentials field:

python3 -c "import json; c=json.load(open('.verify/config.json')); print(c.get('credentials',''))" 2>/dev/null

If the printed path is non-empty AND starts with .verify/ (the skill's allowed file zone — reject anything outside), use the Read tool to read the file directly. Parse the email and password in-head — never echo them to the shell or print them to stdout.

Supported formats:

  • key=value (one per line):

`` email=user@example.com password=secret ``

  • JSON: {"email": "user@example.com", "password": "secret"}

Then log in via Playwright:

  • mcp__playwright__browser_type into the email textbox (use the ref from the snapshot) — pass the email as the text argument
  • mcp__playwright__browser_type into the password textbox — pass the password as the text argument
  • mcp__playwright__browser_click on the submit button (usually labeled "Sign In", "Log in", or equivalent)
  • mcp__playwright__browser_snapshot — confirm the page URL no longer matches /signin//login//auth

Tell the user briefly: "Logged in using credentials from {CREDS_FILE}." Never include the email or password in any output, result.json, or report.

2. User-provided credentials in chat. If no credentials field is set (or the file is missing / unreadable), fall back to asking:

"You're not logged in. Either add a credentials field to .verify/config.json pointing at a file under .verify/, or paste an email/password here and I'll log in via the browser."

If the user pastes creds, use the same Playwright type+click sequence to log in, then snapshot to confirm.

3. Neither worked. Write verdict auth_expired for each AC and stop — tell the user to set up credentials and retry.

Proceed to Turn 3.

Turn 3: Spec Interpreter

Trigger: Pre-flight passed.

Review the spec inline. For each AC, check:

  1. Reveal action — does it say "shown/displayed/visible" without saying how? → flag
  2. Preconditions — requires specific data to exist? → flag
  3. Target — UI element identifiable by label or text? If too vague → flag
  4. Success — clear pass/fail? If not → flag

If no ambiguities: skip Turn 4, go directly to Turn 5. If ambiguities found: ask the first flagged question. End response and wait.

Turn 4: Clarification Loop

Trigger: User answered a clarifying question.

Keep a running list of AC annotations, e.g.:

  • AC3: expiry date revealed via hover on Pending badge
  • AC1: expiration field is inline in the send dialog

Note the answer and add it to the list. If more ambiguities remain — ask the next one and wait.

When all answered — proceed to Turn 5.

Turn 5: Extract ACs + Verify with Playwright MCP

Trigger: All ambiguities resolved (or there were none).

This turn has three phases: AC extraction, verification, and reporting.

Phase 1: Extract Acceptance Criteria

Read the spec content and any clarifications. Also read context files if they exist:

  • .verify/app.json — known routes, use for specific navigation paths in AC descriptions
  • .verify/seed-data.txt — actual database records, use for specific data references (limit: first 8000 chars)
  • .verify/learnings.md — corrections from past verification runs

Extract testable ACs. Each AC must be concrete enough for browser verification:

AC quality standard — this is critical:

  • BAD: "The settings form shows an expiration field"
  • GOOD: "The team document settings page (/t/{teamUrl}/settings/document) shows a 'Default Envelope Expiration' combobox with options 'Never expires' and 'Custom duration'"

USE THE SEED DATA. If the spec says "a document with expiration set" and seed data shows a recipient "recipient-expiry@test.documenso.com", reference those exact values.

USE THE ROUTES. If app routes show /t/personal_xyz/settings/document, reference that navigation path.

Extraction rules:

  • Each AC: one specific testable behavior
  • Skip ACs requiring external services (Stripe, email, OAuth)
  • Pure UI ACs with multiple checks on the same page should be split into individual ACs (one behavior each)
  • NEVER use template variables like {envId}, {orgId} — resolve to actual values from routes or seed data

Present the AC list to the user: "I've extracted N acceptance criteria. Here's the plan: [list ACs]. Starting verification now."

Phase 2: Verify Each AC with Playwright MCP

Set up the evidence directory:

RUN_ID=$(date +%Y%m%d-%H%M%S)
mkdir -p .verify/runs/$RUN_ID/evidence
mkdir -p .verify/mcp-output/traces
# Purge stale artifacts from prior crashed runs so this run's recordings don't collide
rm -f .verify/mcp-output/*.webm 2>/dev/null || true
rm -f .verify/mcp-output/traces/trace-*.trace .verify/mcp-output/traces/trace-*.network .verify/mcp-output/traces/trace-*.stacks 2>/dev/null || true

For EACH acceptance criterion, fo

Compartilhar X LinkedIn