131 lines
5.0 KiB
Markdown
131 lines
5.0 KiB
Markdown
# Report Spec (WE-R)
|
||
|
||
## Overview
|
||
|
||
Assembles all collected data into a single Markdown file optimised for Claude
|
||
to read. Findings are phrased in a pre-interpreted tone: each issue explains
|
||
what it means and what to do about it, not just that a value is absent or wrong.
|
||
|
||
## Responsibilities
|
||
|
||
- Accept LighthouseResult[] and DomData as inputs
|
||
- Produce a single Markdown string
|
||
- Apply severity grading to Lighthouse scores
|
||
- Categorise findings as Critical (must fix) / Warning (should fix) / Info
|
||
- Write the report in the defined section order
|
||
- Deduplicate findings that appear in both desktop and mobile audits
|
||
|
||
Delegates to: nothing (pure function, no I/O)
|
||
|
||
## Dependencies
|
||
|
||
Read [lighthouse.md](lighthouse.md) for `LighthouseResult` shape.
|
||
Read [dom-analysis.md](dom-analysis.md) for `DomData` shape.
|
||
|
||
## Data Model
|
||
|
||
### Score grading
|
||
|
||
| Score | Grade | Colour label |
|
||
|---|---|---|
|
||
| 90–100 | A | Good |
|
||
| 75–89 | B | Needs improvement |
|
||
| 50–74 | C | Poor |
|
||
| 0–49 | F | Critical |
|
||
|
||
### Severity rules
|
||
|
||
- **Critical (must fix):** Lighthouse finding with `score === 0` in any preset
|
||
- **Warning (should fix):** Lighthouse finding with `0 < score < 0.9` in any preset; or DOM issues (missing description, heading skips, missing alt)
|
||
- **Info:** Minor or informational items
|
||
|
||
## Requirements
|
||
|
||
**WE-R-1:** The report begins with a level-1 heading: `# Website Evaluation: {hostname}`.
|
||
Hostname is extracted from the URL (no scheme, no path).
|
||
|
||
**WE-R-2:** A generation line follows: `_Generated: {ISO date} · Audited: {full URL}_`
|
||
|
||
**WE-R-3:** Section order (all sections always present, even if empty):
|
||
1. Lighthouse Scores (desktop + mobile tables)
|
||
2. Core Web Vitals (desktop + mobile tables)
|
||
3. Critical Issues
|
||
4. Warnings
|
||
5. Info
|
||
6. Page Structure
|
||
7. Screenshots reference
|
||
8. Raw Data reference
|
||
|
||
**WE-R-4:** Lighthouse score tables have columns: Category | Desktop | Mobile | Desktop Grade | Mobile Grade.
|
||
Why: Side-by-side makes it easy to spot mobile regressions.
|
||
|
||
**WE-R-5:** Core Web Vitals tables have columns: Metric | Desktop | Mobile | Status.
|
||
Status is the worst of the two presets for that metric (e.g., if desktop is "good"
|
||
but mobile is "needs-improvement", show "needs-improvement").
|
||
|
||
**WE-R-6:** Each finding is rendered as a Markdown checkbox list item:
|
||
```
|
||
- [ ] **{title}** — {pre-interpreted explanation with fix guidance}
|
||
```
|
||
The title comes from `audit.title`. The explanation is built from `audit.description`
|
||
(stripped of Markdown links) plus any savings estimate.
|
||
|
||
**WE-R-7:** If the same audit ID appears as a finding in both desktop and mobile
|
||
results, it appears once in the report (not duplicated). The severity is the worst
|
||
across both presets.
|
||
|
||
**WE-R-8:** DOM issues (missing meta description, heading skips, missing alt text,
|
||
missing noopener) are included in the Warnings section with pre-interpreted phrasing.
|
||
Exact phrasing:
|
||
- Missing meta description: "Meta description missing — search engines will auto-generate one, often poorly. Add a 155-char summary."
|
||
- Heading skip: "Heading hierarchy skips {skip} — this confuses screen readers and weakens document structure."
|
||
- Missing alt: "{n} image(s) lack alt text — WCAG 1.1.1 violation (Level A); screen readers will skip them entirely."
|
||
- Missing noopener: "{n} link(s) open in a new tab without `rel=\"noopener\"` — the opened page can access `window.opener`."
|
||
|
||
**WE-R-9:** Page Structure section lists:
|
||
- Title (value + char count + assessment: "good" if 30–65 chars, "too short" / "too long" otherwise)
|
||
- Meta description (value or "missing")
|
||
- Canonical (value or "not set")
|
||
- Heading counts per level (e.g., "H1×1, H2×4, H3×7")
|
||
- Images (total, missing alt count)
|
||
- Links (total, external, new-tab-no-opener count)
|
||
- Structured data (types detected or "none")
|
||
- Open Graph (present/absent)
|
||
|
||
**WE-R-10:** Screenshots section contains Markdown image references:
|
||
```markdown
|
||

|
||

|
||
```
|
||
|
||
**WE-R-11:** If all Critical, Warning, and Info sections are empty, replace each
|
||
with `_None detected._`.
|
||
|
||
**WE-R-12:** The function signature is:
|
||
```js
|
||
assembleReport(url, lighthouseResults, domData) → string
|
||
```
|
||
It is a pure function — no file I/O, no side effects.
|
||
|
||
## Scenarios
|
||
|
||
### Scenario: Score table format
|
||
**Given:** Desktop performance 87, mobile performance 62
|
||
**When:** Report is assembled
|
||
**Then:** Score table shows desktop 87 (B), mobile 62 (C) in the same row
|
||
|
||
### Scenario: Finding deduplication
|
||
**Given:** `meta-description` audit fails (score 0) in both desktop and mobile results
|
||
**When:** Report is assembled
|
||
**Then:** The meta-description finding appears exactly once in Critical Issues
|
||
|
||
### Scenario: Empty sections
|
||
**Given:** All Lighthouse audits pass (score ≥ 0.9), no DOM issues
|
||
**When:** Report is assembled
|
||
**Then:** Critical Issues, Warnings, and Info sections each contain `_None detected._`
|
||
|
||
### Scenario: Title assessment
|
||
**Given:** Page title is 14 chars ("Example Domain")
|
||
**When:** Page Structure section is built
|
||
**Then:** Title line shows `"Example Domain" (14 chars — too short)`
|