skills/uat-parallel/SKILL.md
Runs UAT (User Acceptance Testing) cases in TRUE PARALLEL using Playwright Test runner with isolated browser contexts per worker (separate cookies, localStorage, sessionStorage). Solves the two main limits of /user-test: (1) sequential single-page execution that does not scale beyond a few cases, and (2) one stuck case blocking the rest of the run. Reuses 100% of the /user-test UAT case Markdown+YAML format under docs/tests/uat-cases/, runs them via `npx playwright test --workers=N`, and emits the same report layout (index.html + issues.md + session.json + screenshots/) under docs/tests/uat-reports/. Use when the user asks to "run UAT in parallel", "speed up UAT", "test multi-user", "song song", "uat parallel", or runs /uat-parallel. Distinct from /user-test (sequential Chrome MCP, supports interactive mode), /test-run (developer integration tests), /test-scenario (scenario authoring).
npx skillsauth add astra-technology-company-limited/astra-methodology uat-parallelInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Runs UAT cases concurrently using Playwright Test workers. Each worker holds an isolated browser context, so authentication, cookies, and localStorage do not leak between cases. Cases that hang are killed by per-step / per-case timeouts and never block other workers.
This skill is the parallel sibling of /user-test. Use /user-test for interactive ad-hoc testing or when you do not have Playwright installed; use /uat-parallel for batch regression runs.
| Aspect | /user-test | /uat-parallel |
|---|---|---|
| Driver | Chrome MCP (in-Claude tool calls) | Playwright CLI (subprocess) |
| Concurrency | 1 page, sequential | N workers, parallel |
| Browser state | Shared across cases | Isolated per worker |
| Per-case timeout | None (Claude must self-abort) | Hard timeout enforced by Playwright |
| Interactive mode | Yes (URL + Vietnamese flow) | No (auto-batch only) |
| Trace / replay | Static screenshots only | Playwright trace viewer (.zip) |
| Bootstrap cost | Zero | One-time npm i -D @playwright/test |
| Case format | docs/tests/uat-cases/*.md | Same files, no migration |
Detailed references (load on demand):
references/parallel-guide.md — worker count tuning, isolation guarantees, debugging flaky cases.../user-test/references/assertion-guide.md — assertion grammar and severity rules (reused as-is).../user-test/references/i18n-strings.md — vi/en/ko translation table (shared SSoT; the merge script reads UAT_LANG and renders accordingly).Check whether Playwright is available:
npx --no-install playwright --version 2>/dev/null
If the command exits non-zero or package.json does not contain @playwright/test:
Ask the user via AskUserQuestion:
"Skill này cần Playwright để chạy song song. Cài
@playwright/test+ Chromium ngay không? (~150 MB)"
Đã huỷ. Chạy thủ công: npm i -D @playwright/test && npx playwright install chromiumOn confirmation:
# In project root
if [ ! -f package.json ]; then npm init -y >/dev/null; fi
npm i -D @playwright/test
npx playwright install chromium
Verify: npx playwright --version must succeed.
Once installed, skip bootstrap on subsequent runs.
| Flag | Default | Meaning |
|---|---|---|
| --workers N | min(4, max(1, cpu/2)) | Number of parallel workers |
| --from {glob} | docs/tests/uat-cases/*.md | Restrict case files |
| --priority X | none | Filter by frontmatter priority |
| --feature Y | none | Filter by frontmatter feature |
| --timeout 30s | 30s per step, 300s per case | Hard timeouts |
| --headed | false (headless) | Show browser windows |
| --browser X | chromium | chromium | firefox | webkit |
| --lang X | resolved at Step 0 | Report-output language (vi | en | ko) |
Determine LANG_CODE ∈ {vi, en, ko} — used for index.html (<html lang> + visible labels), issues.md headings, and console log messages. UAT case file contents are not translated.
Resolution order:
--lang flag in $ARGUMENTS → normalize case-insensitive (vi|vie|vietnamese → vi; en|eng|english → en; ko|kor|korean → ko). If recognized, skip to Step 1.CLAUDE.md ## Language → if it resolves to ko, vi, or en, use it silently.AskUserQuestion with the trilingual prompt below; default selection Vietnamese.Chọn ngôn ngữ cho báo cáo UAT.
Select the language for the UAT report.
UAT 보고서 언어를 선택하세요.
Options (single-select, header Lang):
Tiếng Việt — Vietnamese (Recommended)English — English한국어 — KoreanMap: Tiếng Việt → vi, English → en, 한국어 → ko.
The merge script (uat-parallel-report.sh) consumes LANG_CODE via the UAT_LANG environment variable in Step 5.
--from (default docs/tests/uat-cases/*.md).--priority and --feature filters.Không tìm thấy UAT case phù hợp.Tìm thấy {N} test case, sẽ chạy song song với {W} workers.SESSION_ID = {YYYY-MM-DD-HHmm}
SESSION_DIR = docs/tests/uat-reports/{SESSION_ID}/
Create:
{SESSION_DIR}/screenshots/{SESSION_DIR}/traces/{SESSION_DIR}/raw/ (Playwright JSON output lands here)The runner files live at .astra/uat/ in the project. On every invocation, copy from the plugin (overwrite — these are managed files):
| Source (plugin) | Destination (project) |
|---|---|
| $CLAUDE_PLUGIN_ROOT/skills/uat-parallel/assets/uat-runner.spec.ts | .astra/uat/uat-runner.spec.ts |
| $CLAUDE_PLUGIN_ROOT/skills/uat-parallel/assets/playwright.config.ts | .astra/uat/playwright.config.ts |
Add .astra/uat/ to .gitignore if missing.
Set environment variables that the runner spec reads, then invoke:
cd <project-root>
UAT_SESSION_DIR="{absolute SESSION_DIR}" \
UAT_CASES_GLOB="{--from glob or default}" \
UAT_FILTER_PRIORITY="{--priority value or empty}" \
UAT_FILTER_FEATURE="{--feature value or empty}" \
UAT_STEP_TIMEOUT_MS="{step ms}" \
UAT_CASE_TIMEOUT_MS="{case ms}" \
npx playwright test \
--config .astra/uat/playwright.config.ts \
--workers {N} \
--browser {browser} \
{--headed if requested} \
--reporter json,html \
--output {SESSION_DIR}/raw
The runner spec writes per-case results into {SESSION_DIR}/raw/results/{case-id}.json plus screenshots into {SESSION_DIR}/screenshots/{case-id}/step-NN.png. Failed cases also produce traces at {SESSION_DIR}/traces/{case-id}.zip.
Do not abort on non-zero exit — Playwright returns non-zero whenever any case FAILs, which is normal.
Invoke the merge helper. Pass UAT_LANG (the LANG_CODE from Step 0) and UAT_WORKERS (worker count) as environment variables so the script can localize HTML + issues.md:
UAT_LANG="{LANG_CODE}" \
UAT_WORKERS="{N}" \
bash $CLAUDE_PLUGIN_ROOT/skills/uat-parallel/scripts/uat-parallel-report.sh \
"{SESSION_DIR}" \
"$CLAUDE_PLUGIN_ROOT/skills/user-test/assets/report-template.html"
The script:
{SESSION_DIR}/raw/results/*.json.{SESSION_DIR}/index.html from the user-test template (reused) — substitutes {{SESSION_ID}}, {{MODE}} = "auto-parallel (W workers)", summary stats, {{TEST_CASES_HTML}}, {{ISSUES_HTML}}.{SESSION_DIR}/issues.md if any FAIL exists, using the same schema as /user-test:
## Issue #N — {SEVERITY}
**Test Case**: {UAT-ID} - {name}
**Bước**: {step_num}/{total} — {step_name}
### Expected ...
### Actual ...
### Lý do gán {SEVERITY}
### Screenshot
### Trace (Playwright)
`npx playwright show-trace ./traces/{case-id}.zip`
{SESSION_DIR}/session.json with summary, cases, issues.{SESSION_DIR}/raw/ after a successful merge.Print using the L_DONE_PARALLEL string for the resolved LANG_CODE. Example for vi:
▶ Hoàn thành (parallel, {W} workers).
📊 {PASS} PASS / {FAIL} FAIL · {DURATION}
📄 {SESSION_DIR}/index.html
🐛 issues.md có {M} issue ({severity breakdown})
🎞️ Trace replay: npx playwright show-trace {SESSION_DIR}/traces/{first-failed}.zip
For en use ▶ Done (parallel, {W} workers) + issues.md has {M} issues; for ko use ▶ 완료 (병렬, {W} workers) + issues.md에 {M}건의 이슈. Skip the issues.md and trace lines when no FAIL.
100% identical to /user-test — no migration required. See skills/user-test/SKILL.md §3. Recap:
---
id: UAT-001
name: Đăng ký tài khoản
priority: critical
feature: auth
base_url: https://staging.fect.app
---
## Bước 1: Mở trang chủ
**Action**: navigate `{base_url}`
**Expected**:
- url: equals `{base_url}/`
- dom: `button:has-text("Đăng ký")` exists
Action verbs (navigate, click, fill, wait, press, hover) and assertion kinds (url, network, dom, console) are interpreted by .astra/uat/uat-runner.spec.ts. The grammar reference is shared with /user-test at skills/user-test/references/assertion-guide.md.
docs/tests/uat-reports/2026-05-29-1830/
├── index.html # Same look as /user-test report
├── issues.md # Only if FAIL > 0
├── session.json
├── screenshots/
│ └── UAT-001/
│ ├── step-01.png
│ └── step-02.png
└── traces/ # Only for failed cases
└── UAT-001.zip
# Run all cases with default workers
/uat-parallel
# Run with 6 workers, only critical priority
/uat-parallel --workers 6 --priority critical
# Single case, headed mode for visual debugging
/uat-parallel --from docs/tests/uat-cases/dang-ky.md --headed --workers 1
# Cross-browser regression
/uat-parallel --browser firefox --workers 3
# Generate report in English / Korean
/uat-parallel --lang en
/uat-parallel --workers 6 --priority critical --lang ko
--lang flag → CLAUDE.md ## Language → AskUserQuestion → default vi). Passed to the merge script via UAT_LANG. The script embeds an inline mirror of the skills/user-test/references/i18n-strings.md dictionary (the SSoT file is documentation; the runtime values live inside the Node heredoc) and substitutes every visible string in index.html + issues.md accordingly. When adding or changing strings, update both the SSoT and the script. /uat-parallel does not render M_DEV_HINT (the Playwright runner has no LLM to author per-failure hints) and uses M_ISSUES_REPORT_TITLE_PARALLEL instead of the base title key. File slugs always use ASCII./user-test assets: do NOT duplicate the HTML template or assertion grammar — load from skills/user-test/ paths. Future updates to /user-test's template propagate automatically./user-test. URL / Network / DOM / Console only.references/assertion-guide.md §3. The runner emits the raw failure; the merge script applies the severity rules.BrowserContext across cases. The runner enforces this via Playwright's per-test context fixture.--timeout.issues.md, same as /user-test v2+..astra/uat/ files from the plugin on every run — they are managed artifacts, not user-editable./user-test./test-scenario first./test-run.toHaveScreenshot() is supported by Playwright itself, but this skill enforces hard assertions only.| Symptom | Likely cause | Remedy |
|---|---|---|
| Bootstrap fails: EACCES on npm i | Permission on node_modules/ | Run sudo chown -R $USER node_modules |
| npx playwright install hangs | Network blocked | Set HTTPS_PROXY or pre-download browsers |
| All cases fail with "timeout waiting for selector" | base_url unreachable | Verify dev server, prefer staging URL in frontmatter |
| Worker count higher than CPU → slower run | Context switching overhead | Lower --workers to cpu/2 |
| Auth state leaks across cases | Manual context reuse in spec | Should not happen — re-install .astra/uat/ files from plugin |
| Trace files missing | --trace on-first-retry skipped | Re-run with --workers 1 to force trace on first attempt |
tools
Performs end-user UAT (User Acceptance Testing) by driving a real browser through Chrome MCP, self-verifying each step with hard assertions (DOM / Network / URL / Console), auto-assigning severity on failure, and emitting an HTML report plus issues.md into a timestamped session folder. Supports two modes: interactive (URL + Vietnamese natural-language flow description) and --auto (batch-run pre-authored test cases under docs/tests/uat-cases/). Use when the user asks for "UAT", "user acceptance test", "kiểm thử người dùng", "regression test", or runs /user-test, /uat. Distinct from /test-run (developer-authored technical integration testing) and /test-scenario (scenario authoring from blueprints).
tools
Authors and validates LLM tool descriptions and input schemas (Anthropic Tool Use, MCP servers, LangChain @tool, Pydantic, Zod). Use when the user mentions "tool description", "function calling", "MCP tool", "Pydantic schema", "Zod schema", "@tool decorator", "input_schema", "tool spec", "툴 정의", "함수 호출 스키마", or when editing files that define LLM tool surfaces. Enforces the six required attributes (one-line summary, anti-pattern, synonyms, parameter examples, enum constraints, return shape) and blocks the seven known failure modes — wrong-tool selection, skipped tool, malformed arguments, retry loops, user-intent bypass, wrong side-effect, and un-auditable traces. For authoring ASTRA SKILL.md files use /skill-author instead — this skill is for *runtime* LLM tool surfaces, not for skill files themselves.
development
Creates new SKILL.md files or refactors existing skills to comply with the ASTRA skill best practices guide (docs/development/skill-best-practices.md). Use when user mentions "new skill", "create skill", "SKILL.md", "skill authoring", "스킬 작성", "스킬 만들기", or when editing any file matching skills/**/SKILL.md.
tools
Audits existing UI components/pages/CSS against docs/design-system/DESIGN.md and applies fixes to restore design consistency. Uses design-token-validator to detect hardcoded color/font/spacing violations, and invokes designer-persona to report a senior-perspective score (0-10) and anti-AI aesthetic violations (generic shadcn look, purple gradient cliché). Fixes are applied automatically (--apply) or proposed as a PR (--pr); after changes, design-token-validator is re-run and must PASS before completion. Input: target directory (e.g., src/components/Button), single file, or git diff. Output: audit report (docs/design-system/audit-{date}.md) + fix proposals + application results.