---
model: sonnet
---

# /tas-functest-report $ARGUMENTS

Role: SE / QA
Convert Playwright (web) or Detox (mobile) **functional** test execution output into a populated Feature-level test report using `.tas/templates/FeatureTestReport.md`.

## Scope
- Functional Feature tests only (Layer 2). Not unit, not E2E orchestration.
- Input: Playwright web or Detox mobile execution results (JUnit XML / JSON / logs).
- Output: one `{CODE}-FeatureTestReport.md` in the Feature directory.
- **Protocol is external.** Status semantics, severity, metric formulas, and merge gate live ONLY in `.tas/rules/common/test-report-protocol.md`. This command NEVER redefines them.

## Arguments

```text
/tas-functest-report <Feature-ID-or-FuncTest-path> [--framework playwright|detox|auto] [--results <path>] [--report-dir <path>] [--env local|dev|staging|prod] [--ci <url-or-id>]
```

Examples:
```text
/tas-functest-report F001 --framework playwright --results apps/web/reports/functional-results.xml
/tas-functest-report docs/features/AL-Feature-001-login/AL-FuncTest.md --framework detox --results apps/mobile/reports/functional-results.xml
/tas-functest-report F001 --framework auto
```

Defaults:
- `--framework auto` → infer from `--results` path, else from existing app report folders (web vs mobile).
- `--env` → `staging` (matches template frontmatter default).
- Report output → `{feature-dir}/{CODE}-FeatureTestReport.md`.

### Result artifact candidates (when `--results` omitted)
- **Web (Playwright):**
  - `apps/web/reports/functional-results.xml`
  - `apps/web/reports/e2e-results.xml`
  - `apps/web/playwright-report/` → evidence path only (not primary data)
- **Mobile (Detox):**
  - `apps/mobile/reports/functional-results.xml`
  - `apps/mobile/reports/e2e-results.xml`
  - `apps/mobile/artifacts/` → evidence path only

## Actions

### Step 1: Identify Feature
1. `$ARGUMENTS` first positional = Feature ID (e.g., `F001`) or a FuncTest path.
2. If a Feature ID: locate the Feature dir `docs/features/{CODE}-Feature-{NNN}-{slug}/`.
3. If a path: derive Feature dir + `{CODE}` from it.

### Step 2: Locate FuncTest (STOP gate)
1. FuncTest spec path: `docs/features/{CODE}-Feature-{NNN}-{slug}/{CODE}-FuncTest.md`.
2. If missing → report:
   > "No FuncTest spec for this Feature. Run `/tas-functest {Feature-ID}` first."
   > STOP. Do NOT create a report.

### Step 3: Read required sources (in order)
1. `.tas/rules/common/test-report-protocol.md` — **FIRST, always.** Governs status, severity, formulas, merge gate.
2. `.tas/templates/FeatureTestReport.md` — output structure.
3. Feature FuncTest markdown — §4 is the **TC SSoT**.
4. Matching `*-TestChecklist.md` — §2.1 is the **AC SSoT**.
5. `test-design.md` — ONLY when a category/platform NFR baseline lookup is needed (viewport list, SLA baselines, category→technique).

### Step 4: Detect framework + locate results
1. Resolve `--framework`: explicit → use it; `auto` → infer from `--results` path, else from which of `apps/web` / `apps/mobile` has report artifacts.
2. Resolve results file from `--results` or the candidate list above.
3. If no parseable results found → STOP, report which paths were checked. Do NOT fabricate results.

### Step 5: Parse results
Supported formats, in priority order:
1. **JUnit XML** (Playwright/Detox) — primary.
2. **Playwright JSON / blob report** — if present.
3. **CLI logs** — fallback ONLY when test titles embed TC IDs.
4. **HTML report / artifact folders** — evidence links, not primary data unless machine-parseable.

Extract per test: title (must map to a TC ID), status, duration, error message, viewport/device (if encoded).

**Title → TC ID parse rule (chain contract with `/tas-functest-web|mobile`):**
- The test title (JUnit `testcase@name`, or `describe > it` concatenation) begins with the FuncTest §4 TC ID. Parse it with `^(F\d+_AC\d+_[A-Z]+_\d+[a-z]?)`. The optional trailing letter is a BVA/EP variant (`F001_AC1_VAL_001a`) — it is a **distinct** TC ID in §4, NOT the same as `_001`; do not strip or collapse it.
- A bracketed suffix `[desktop]` / `[ios]` etc. marks a **viewport/device variant of the same TC ID** — capture it as the viewport/device for §1.4, do NOT treat it as a separate TC. Multiple variants of one TC ID roll up: the TC is PASS only if all its variants pass; any FAIL variant → the TC is FAIL (note failing viewport(s)).
- A title that does not match the regex → **unmatched** warning (Step 11); never invent a TC ID to force a match.

### Step 6: Build canonical TC map from FuncTest §4
For every TC row capture: TC ID · Test Type/Category · Description · Pre-Condition + `Depends:` · Expected Result · Priority · Autoable · Traceability/AC ID.
- FuncTest §4 is the **only** source of TC IDs. Never invent one.

### Step 7: Map execution → protocol status
Per protocol §1 (do not redefine — this is the mapping only):
- passed → `✅ PASS`
- failed / error → `❌ FAIL`
- skipped / pending → `⏭️ SKIP`
- did NOT run because a dependency TC (`Depends:`) already FAIL/BLOCKED → `⛔ BLOCKED` (note blocking TC)
- TC exists but fixture not implemented / Draft → `🔴 HOLD`
- Infra: ran + wrong result → `❌ FAIL[INFRA]`; couldn't run at all → `⛔ BLOCKED[INFRA]` (per protocol §1 key distinctions).

### Step 8: Populate report (safe derivation order)
Fill in this order so downstream sections read from upstream data:
1. **§2.1** detailed results table (one row per known TC — matched results + un-run Autoable TCs). When a TC has viewport/device variants, keep the single rolled-up row but record the per-variant pass/fail breakdown in its note (e.g. `desktop ✅ / tablet ✅ / mobile ❌`) so §1.4 can be computed from it.
2. **§2.2** failed-test RCA (Automation mode; one block per non-infra FAIL).
3. **§2.3** defect registry (Automation schema → protocol §5). Every FAIL non-infra gets a `DEF-NNN`.
4. **§1.1 / §1.2 / §1.3 / §1.4** metrics, AC traceability, priority distribution, viewport coverage — all computed FROM §2.1 + §2.3.
5. **§3** merge gate — apply protocol §4 Step 1 → Step 2 → Step 3.
6. **§4** sign-off placeholders.
7. **§5** autonomous log (only if `autonomous_run: true`).

### Step 9: Fill frontmatter
`project` (tas.yaml) · `feature_name` (FuncTest) · `platform` (FuncTest frontmatter) · `execution_mode: Automation` · `test_framework: Playwright|Detox` · `generated_by: /tas-functest-report` · `environment` (--env) · `ci_run_id` (--ci) · `status: Completed`.

### Step 10: Write report
Write to `{report-dir or feature-dir}/{CODE}-FeatureTestReport.md`.

### Step 11: Print summary
- output path
- total / pass / fail / skip / blocked / hold
- coverage rate + pass rate
- defects by severity (HIGH / MEDIUM)
- merge gate outcome (✅ / 🟡 / 🔴)
- warnings (unmatched result tests, missing Autoable TCs, triage-required defects)

## Key rules (encode, do NOT redefine)
- Read `.tas/rules/common/test-report-protocol.md` FIRST. Status, severity, formulas, merge gate come from there only.
- FuncTest §4 = TC SSoT; never invent TC IDs.
- TestChecklist §2.1 = AC SSoT.
- Every automation result MUST map to a known TC ID. Unmatched result tests → **warning** (never silently dropped).
- Known Autoable=YES/MAYBE TCs with no matching result MUST still appear as SKIP / BLOCKED / HOLD with a note.
- **Severity comes from protocol §3 Defect Triage Matrix by Defect Type — NOT from TC Priority or TC Blast-Radius.**
- Severity/Defect-Type ambiguous → mark **triage required**; gate must not auto-PASS (escalate to PE+SE).
- **Infrastructure failures** (`ECONNREFUSED`, staging down, CI timeout, simulator boot failure) → classify Infrastructure/Ops (protocol §3 Infra row). Do NOT count as feature severity; evidence still appears; does not gate merge.
- Compute formulas exactly per protocol §2:
  - `test_coverage_rate = (PASS + FAIL) / Total TCs`
  - `pass_rate = PASS / (PASS + FAIL)`
  - per-priority rates use the same denominator rule
  - Step 1 gate still FAILS on any P0/P1 TC status ≠ PASS even though such TCs are excluded from the pass-rate denominator.

## Validation gate (before reporting done)
Command MUST verify:
1. Frontmatter filled: `project`, `feature_name`, `platform`, `execution_mode: Automation`, `test_framework`, `generated_by`, `environment`, `ci_run_id`, `status: Completed`.
2. Every §2.1 TC exists in FuncTest §4.
3. Every Autoable=YES/MAYBE TC has exactly one §2.1 row.
4. §1.1 metric totals equal §2.1 status counts.
5. Every FAIL TC references a defect ID present in §2.3.
6. Every non-infra FAIL has a §2.2 RCA entry.
7. §3 gate outcome matches protocol §4 (Step 1 escalation → Step 2 → Step 3).
8. Unmatched / unknown result tests listed as warnings, not dropped.

## References
- `.tas/rules/common/test-report-protocol.md` — status, severity, formulas, merge gate (SSoT — read FIRST)
- `.tas/templates/FeatureTestReport.md` — output structure
- `{CODE}-FuncTest.md` §4 — TC SSoT (ID / category / priority / depends / autoable)
- `{CODE}-TestChecklist.md` §2.1 — AC SSoT
- `.tas/rules/common/test-design.md` — category→technique, Platform NFR baselines (viewport/SLA lookups only)
- `/tas-functest`, `/tas-functest-web`, `/tas-functest-mobile` — upstream spec + script generators
