一键导入
test-counsel
Test a project's features from 8 persona perspectives using browser, API, and documentation testing
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Test a project's features from 8 persona perspectives using browser, API, and documentation testing
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Reset the OpenRegister development environment (stop, remove volumes, restart, install apps)
Create a Pull Request from the current branch — runs local checks, picks target branch, and opens the PR on GitHub
Analyze a project's OpenSpec from 8 persona perspectives and suggest additional features
Iteratively run apply→verify in a loop until verify passes, then auto-archive — runs per-app in Docker context
Implement tasks from an OpenSpec change (Experimental)
Archive a completed change in the experimental workflow
| name | test-counsel |
| description | Test a project's features from 8 persona perspectives using browser, API, and documentation testing |
Test a project's implemented features from 8 persona perspectives using browser interaction, API testing, and documentation review — all driven by the project's OpenSpec specifications.
Input: Optional argument after /test-counsel:
opencatalogi, openregister)Available projects: Any directory under apps-extra with an openspec/ folder.
The Test Counsel uses 8 personas representing the full spectrum of Dutch public sector users. Each persona card is stored in .claude/personas/:
| Persona | File | Testing Focus |
|---|---|---|
| Henk Bakker | henk-bakker.md | Readability, text size, Dutch language, simple navigation, elderly UX |
| Fatima El-Amrani | fatima-el-amrani.md | Visual clarity, icon usage, mobile viewport, text density, literacy barriers |
| Sem de Jong | sem-de-jong.md | Performance, keyboard nav, dark mode, console errors, modern UX patterns |
| Noor Yilmaz | noor-yilmaz.md | Security controls, audit trails, RBAC, org isolation, data leaks, BIO2 |
| Annemarie de Vries | annemarie-de-vries.md | API standards, NLGov compliance, GEMMA mapping, OpenAPI spec, publiccode.yml |
| Mark Visser | mark-visser.md | Business workflows, CRUD efficiency, form clarity, status indicators, Dutch terms |
| Priya Ganpat | priya-ganpat.md | API quality via browser fetch(), DX, error responses, pagination, integration |
| Jan-Willem van der Berg | janwillem-van-der-berg.md | Plain language, jargon-free, findability, 3-click rule, contact info, help |
Ask the user about the target environment using AskUserQuestion:
"Which environment do you want to test against?"
If Custom, ask follow-up questions one at a time:
Store as {BACKEND}, {FRONTEND}, {TEST_USER}, {TEST_PASS}.
For Local development, use:
{BACKEND} = http://localhost:8080{FRONTEND} = http://localhost:8080 (or http://localhost:3000 if project has separate UI){TEST_USER} = admin{TEST_PASS} = adminIf no project was provided as argument, use AskUserQuestion to ask:
"Which project would you like the Test Counsel to test?"
List the available projects by checking which directories have openspec/ folders.
Store the chosen project as {PROJECT}.
Read the following files:
{PROJECT}/project.md — Project context, URLs, architecture{PROJECT}/openspec/specs/ — All spec files (what was specified){PROJECT}/openspec/changes/ — Active changes (recently added features)openspec/specs/ — Shared specs (api-patterns, nl-design, nextcloud-app)Build a test plan:
Check whether the project has saved test scenarios:
ls {PROJECT}/test-scenarios/TS-*.md 2>/dev/null
If scenario files exist, parse their frontmatter. Filter to those with status: active and test-commands containing test-counsel.
Group them by persona relevance using the personas frontmatter field:
Found {N} test scenario(s) for {PROJECT}:
Relevant to all personas:
TS-001 [HIGH] functional — Create a new register
Relevant to specific personas:
TS-002 [MED] api — API returns paginated results → Priya Ganpat, Annemarie de Vries
TS-003 [HIGH] security — Unauthenticated access blocked → Noor Yilmaz
TS-004 [LOW] accessibility — Form labels are readable → Henk Bakker, Fatima El-Amrani
Ask the user using AskUserQuestion:
"Test scenarios exist for this project. Include them in this test run?"
Store {INCLUDED_SCENARIOS} — a mapping of persona slug → list of relevant scenario objects (id, title, steps, preconditions, acceptance criteria).
Each persona sub-agent will receive only the scenarios matching their persona slug (or all scenarios if the user chose "include all" and no persona filter is set).
If no scenarios exist: proceed silently. Note at the end: "No test scenarios defined yet. Create them with /test-scenario-create."
Ask the user using AskUserQuestion:
"Which model should the persona agents use?"
| Model | Speed | Quota | Best for |
|---|---|---|---|
| Haiku | Fastest | Low | Parallel runs — broad coverage, efficient |
| Sonnet | Balanced | Moderate | Better reasoning, more nuanced findings |
| Opus | Slowest | High | Deepest analysis — for critical or final runs |
Store as {MODEL}:
"haiku""sonnet""opus"Launch 8 Task agents in parallel (all in a single message), one per persona. Each agent tests the live application from their persona's perspective. Use subagent_type: "general-purpose" and model: "{MODEL}" (from Step 1.5).
Browser assignment — each agent gets its own browser to avoid conflicts:
| Agent | Persona | Browser |
|---|---|---|
| 1 | Henk Bakker | browser-2 |
| 2 | Fatima El-Amrani | browser-3 |
| 3 | Sem de Jong | browser-4 |
| 4 | Noor Yilmaz | browser-5 |
| 5 | Annemarie de Vries | browser-7 |
| 6 | Mark Visser | browser-1 |
| 7 | Priya Ganpat | browser-2 (sequential after Henk) |
| 8 | Jan-Willem van der Berg | browser-3 (sequential after Fatima) |
Note: With 7 browsers and 8 agents, launch the first 6 in parallel, then the remaining 2 after the first batch completes. Or launch all 8 and let 2 share browsers sequentially.
Sub-agent prompt template (replace variables):
You are a Test Counsel agent testing the **{PROJECT}** application as **{PERSONA_NAME}**.
## Your Persona
Read the persona card at `.claude/personas/{PERSONA_FILE}` to understand your character completely. Stay fully in character throughout all testing.
## Browser
Use `browser-{N}` tools (`mcp__browser-{N}__*`) for all browser interactions.
## Environment
- **Backend**: {BACKEND}
- **Frontend**: {FRONTEND}
- **Login**: {TEST_USER} / {TEST_PASS}
## What to Test
Read the project specs to understand what features should exist:
1. `{PROJECT}/project.md`
2. All files in `{PROJECT}/openspec/specs/`
## Test Scenarios for Your Persona
{IF INCLUDED_SCENARIOS for this persona is non-empty:}
The following test scenarios were defined specifically for your persona. Execute these **first**, before free exploration — they represent the highest-priority flows to verify:
{For each scenario: ID, title, preconditions, Given-When-Then steps, acceptance criteria}
For each scenario:
1. Set up the preconditions
2. Follow the Given-When-Then steps exactly as written, using the provided test data
3. Verify each acceptance criterion — record PASS / FAIL / PARTIAL / BLOCKED
4. Screenshot each step: `{PROJECT}/test-results/screenshots/personas/{PERSONA_SLUG}/{SCENARIO_ID}-step-{N}.png`
5. Check `browser_console_messages` after each action
Include a **"## Test Scenario Results"** section in your report with a table:
| Scenario | Title | Criterion | Status | Observed |
|---|---|---|---|---|
{END IF}
---
## Testing Approach
### 1. Browser Testing (UI)
Log in and navigate through the application as your persona would:
- Navigate to {FRONTEND} (or {BACKEND}/index.php/apps/{PROJECT} for Nextcloud apps)
- Log in with the test credentials
- Visit every major page/section mentioned in the specs
- For each page:
- `browser_snapshot` — observe the page from your persona's perspective
- Test interactions your persona would attempt
- Check `browser_console_messages` for errors
- Note anything that doesn't match your persona's needs/expectations
### 2. API Testing (from browser)
Use `browser_evaluate` to test API endpoints mentioned in the specs:
```javascript
const response = await fetch('{BACKEND}/index.php/apps/{app}/api/{resource}', {
headers: { 'requesttoken': OC.requestToken }
});
return JSON.stringify({
status: response.status,
headers: Object.fromEntries(response.headers.entries()),
body: await response.json()
}, null, 2);
Test from your persona's perspective:
Check if documentation exists and serves your persona:
For each feature in the specs, verify:
Write your results as a structured report:
# Test Counsel Report: {PERSONA_NAME} — {PROJECT}
**Date:** {today's date}
**Environment:** {BACKEND}
**Persona:** {PERSONA_NAME} ({one-line description})
**Browser:** browser-{N}
## Summary
- **Features tested**: {count}
- **PASS**: {count}
- **PARTIAL**: {count}
- **FAIL**: {count}
- **NOT IMPLEMENTED**: {count}
## Feature Test Results
### {Spec Section / Feature Name}
| Aspect | Status | Notes |
|--------|--------|-------|
| Implemented? | YES/NO/PARTIAL | {details} |
| Works as specified? | YES/NO/PARTIAL | {details} |
| Serves {PERSONA_NAME}'s needs? | YES/NO/PARTIAL | {persona perspective} |
**{PERSONA_NAME}'s reaction**: "{in-character quote}"
{repeat for each feature}
## API Test Results (if applicable)
| Endpoint | Method | Status | Response | Persona Notes |
|----------|--------|--------|----------|--------------|
| /api/{resource} | GET | {code} | {summary} | {persona perspective} |
## Console Errors
| Page | Error | Severity |
|------|-------|----------|
| {page} | {error} | HIGH/MEDIUM/LOW |
## Persona-Specific Findings
### {PERSONA_FOCUS_AREA} Assessment
| Criterion | Status | Evidence | {PERSONA_NAME} would say... |
|-----------|--------|----------|----------------------------|
| {criterion} | PASS/FAIL | {what was observed} | "{in-character quote}" |
## Top Issues
| # | Issue | Severity | Category | Recommendation |
|---|-------|----------|----------|----------------|
| 1 | {issue} | CRITICAL/HIGH/MEDIUM/LOW | {category} | {suggestion} |
## {PERSONA_NAME}'s Verdict
"{A paragraph from the persona summarizing their overall experience testing this application}"
**Persona-specific testing focus:**
| Persona | Testing Focus Instructions |
|---------|--------------------------|
| Henk | Check text size (>=16px body), button size (>=44px), Dutch labels, simple navigation, clear errors, breadcrumbs, contrast ratios |
| Fatima | Set viewport to 375x812 mobile, check icon clarity, text density, visual hierarchy, color-coded status, touch targets, scrolling discovery |
| Sem | Measure page load time, test Tab/Escape/Enter/arrow keys, check dark mode, inspect console, monitor network requests, verify URL state management |
| Noor | Navigate to settings first, look for audit logs, test RBAC boundaries, try URL manipulation for org isolation, check PII in URLs, verify session controls |
| Annemarie | Test API endpoints for NLGov compliance, check pagination format, verify OpenAPI spec availability, look for publiccode.yml, assess GEMMA alignment |
| Mark | Test CRUD workflows for efficiency (count clicks), check form field clarity, verify status indicators, test search, check Dutch business terminology |
| Priya | Use browser_evaluate for API calls, test all CRUD via fetch(), verify error response format, check pagination/filtering/sorting, assess OpenAPI accuracy |
| Jan-Willem | Check for jargon on every page, test search with plain Dutch terms, count clicks to complete tasks, find contact info, verify B1 language level |
### Step 3: Synthesize Test Results
After all agents complete, read their reports and create a synthesized Test Counsel report.
**Write the synthesis to**: `{PROJECT}/test-results/test-counsel-report.md`
```markdown
# Test Counsel Report: {PROJECT}
**Date:** {today's date}
**Environment:** {BACKEND} / {FRONTEND}
**Method:** 8-persona browser, API, and documentation testing against OpenSpec specifications
**Personas:** Henk Bakker, Fatima El-Amrani, Sem de Jong, Noor Yilmaz, Annemarie de Vries, Mark Visser, Priya Ganpat, Jan-Willem van der Berg
---
## Overall Results
| Persona | Features Tested | PASS | PARTIAL | FAIL | Not Implemented |
|---------|----------------|------|---------|------|-----------------|
| Henk Bakker | {n} | {n} | {n} | {n} | {n} |
| Fatima El-Amrani | {n} | {n} | {n} | {n} | {n} |
...{all 8 personas}
| **Total** | {n} | {n} | {n} | {n} | {n} |
---
## Critical Issues (found by 3+ personas)
| # | Issue | Severity | Found by | Recommendation |
|---|-------|----------|----------|----------------|
| 1 | {issue} | CRITICAL/HIGH | {persona names} | {recommendation} |
---
## Spec vs Implementation Gap Analysis
| Spec Feature | Implemented? | Working? | Persona Feedback |
|-------------|-------------|---------|-----------------|
| {feature from spec} | YES/NO/PARTIAL | YES/NO | {summary of persona reactions} |
---
## Per-Persona Highlights
### Henk Bakker (Elderly Citizen)
- **Can Henk use this?** YES/WITH DIFFICULTY/NO
- **Top blocker**: {issue}
- **Quote**: "{in-character Dutch quote}"
### Fatima El-Amrani (Low-Literate Migrant)
...{repeat for all 8}
---
## Testing Categories
### Accessibility & Readability
| Issue | Severity | Personas | Spec Reference |
|-------|----------|----------|---------------|
| {issue} | {severity} | {who found it} | {spec section} |
### Security & Compliance
| Issue | Severity | Personas | Standard |
|-------|----------|----------|----------|
| {issue} | {severity} | {who found it} | {BIO2/AVG/etc} |
### API Quality & Standards
| Issue | Severity | Personas | NLGov Rule |
|-------|----------|----------|-----------|
| {issue} | {severity} | {who found it} | {rule} |
### UX & Performance
| Issue | Severity | Personas | Notes |
|-------|----------|----------|-------|
| {issue} | {severity} | {who found it} | {details} |
### Language & Content
| Issue | Severity | Personas | Notes |
|-------|----------|----------|-------|
| {issue} | {severity} | {who found it} | {details} |
---
## Console Errors Summary
| Error | Occurrences | Pages | Severity |
|-------|-------------|-------|----------|
| {error} | {count} | {pages} | {severity} |
---
## Recommendations
### CRITICAL (fix immediately)
1. {recommendation + which personas affected}
### HIGH (fix before next release)
1. {recommendation + which personas affected}
### MEDIUM (improve when possible)
1. {recommendation + which personas affected}
---
## Suggested OpenSpec Changes
| Change Name | Description | Related Issues | Personas Affected |
|-------------|-------------|---------------|------------------|
| {name} | {description} | {issue numbers from above} | {personas} |
Display a concise summary:
{PROJECT}/test-results/test-counsel-report.mdAfter testing completes, review what happened and append any new observations to learnings.md:
Each entry must include today's date. One insight per bullet. Skip if nothing new was learned.
After generating the report and summary, output a structured result line and return control:
COUNSEL_TEST_RESULT: PASS | FAIL CRITICAL_COUNT: <n> SUMMARY: <one-line summary>
If invoked from /opsx-apply-loop: your work is complete after outputting the result line. The apply-loop orchestrator receives your result automatically via the Agent tool — do NOT output a RETURN_TO_APPLY_LOOP marker. Do NOT offer to create OpenSpec changes, do NOT ask what to do next.