Files
2026-07-02 10:14:34 +01:00

382 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SchoolCompare UX/UI Audit Execution Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Execute the journey-led UX/UI audit of live schoolcompare.co.uk defined in `docs/superpowers/specs/2026-07-02-ux-audit-design.md`, producing a prioritized (P0P3) audit report at `docs/superpowers/specs/2026-07-02-ux-audit-report.md`.
**Architecture:** Five journey walk-throughs (traffic-ordered) at two viewports using Playwright browser tools against the live site, each producing a committed notes file with friction points, "works well" observations, and axe-core scan results. A cross-cutting cohesion pass compares components across pages. A final synthesis task converts notes into the prioritized report.
**Tech Stack:** Playwright MCP browser tools (`mcp__plugin_playwright_playwright__*`), axe-core 4.x injected from CDN, markdown notes committed to git.
## Global Constraints
- Audit the **live site** `https://schoolcompare.co.uk` — do not start any local server (CLAUDE.md).
- Viewports: **mobile 390×844 (primary)** and **desktop 1440×900**. Mobile findings weigh more (56% of traffic).
- A finding is valid only if it cites: a Nielsen/NN-g heuristic violation, a WCAG 2.2 AA failure, a mobile-usability standard, or an observed task-flow obstruction. No taste-only findings.
- Every finding: **evidence → argument (why it hurts parents) → recommendation → uplift indication** (which analytics number moves, direction, small/moderate/large band with reasoning — never invented percentages).
- Read-only with respect to the site: browse and inspect only; never submit forms that create/modify data (search and filter interactions are fine).
- Notes live in `docs/superpowers/specs/2026-07-02-ux-audit-notes/`; screenshots go to the session scratchpad (referenced by filename in notes, not committed).
- Analytics baseline for weighting (30 days): entries `/` 63%, `/compare` 20%, `/rankings` 6%; exits `/` 46%, `/compare` 32%, `/rankings` 13%; views `/` 52%, `/compare` 27%, `/rankings` 12%, `/admissions` 5%; school pages ~1% each (SEO long tail); 56% mobile.
**Note on tool schemas:** Playwright tools are deferred. Before first use in any task, load them:
`ToolSearch` with query `select:mcp__plugin_playwright_playwright__browser_navigate,mcp__plugin_playwright_playwright__browser_resize,mcp__plugin_playwright_playwright__browser_snapshot,mcp__plugin_playwright_playwright__browser_take_screenshot,mcp__plugin_playwright_playwright__browser_evaluate,mcp__plugin_playwright_playwright__browser_click,mcp__plugin_playwright_playwright__browser_type,mcp__plugin_playwright_playwright__browser_press_key,mcp__plugin_playwright_playwright__browser_console_messages`
---
### Task 1: Audit scaffolding + axe-core harness verified on the homepage
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js`
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md`
**Interfaces:**
- Produces: `axe-snippet.js` — a self-contained async JS function body for `browser_evaluate` that loads axe-core from CDN (idempotent) and returns `{violationCount, violations: [{id, impact, description, nodes: count, sampleTargets}]}` filtered to WCAG 2.2 A/AA rules. All journey tasks run this verbatim on each page state.
- Produces: `TEMPLATE.md` — the notes-file structure every journey task copies.
- [ ] **Step 1: Write the axe harness snippet**
Create `docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js`:
```js
// Body for playwright browser_evaluate: () => { ...this content... }
// Loads axe-core 4.x from CDN (skips if already present), runs WCAG A/AA scan.
return (async () => {
if (!window.axe) {
await new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = 'https://cdn.jsdelivr.net/npm/axe-core@4.10.2/axe.min.js';
s.onload = resolve;
s.onerror = () => reject(new Error('axe failed to load'));
document.head.appendChild(s);
});
}
const results = await window.axe.run(document, {
runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'] }
});
return {
url: location.pathname,
violationCount: results.violations.length,
violations: results.violations.map(v => ({
id: v.id,
impact: v.impact,
description: v.help,
nodes: v.nodes.length,
sampleTargets: v.nodes.slice(0, 3).map(n => n.target.join(' '))
}))
};
})();
```
- [ ] **Step 2: Write the notes template**
Create `docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md`:
```markdown
# Journey N: <name> — audit notes
**Pages visited:** <paths>
**Viewports:** 390×844, 1440×900
## Task attempt log
<What was attempted, step by step, and where time/attention went. Note seconds-to-goal where measurable.>
## Friction points
For each:
- **F<N>. <short title>**
- Evidence: <screenshot filename(s), observed behaviour, axe rule id if applicable>
- Criterion violated: <heuristic / WCAG SC / mobile standard / task obstruction>
- Argument: <why this hurts a parent completing the task>
- Severity guess: <P0/P1/P2/P3 — provisional, finalized in synthesis>
## Works well — keep
- <observation, with why it works>
## Axe results
- <path> @ <viewport>: <violationCount> violations — <ids with impact>
## Manual WCAG spot checks
- Touch targets ≥24px on interactive elements: <pass/fail + examples>
- Keyboard: tab order, focus visibility (desktop only): <pass/fail + examples>
- Zoom 200% text reflow (desktop only): <pass/fail>
## Screenshots
- <filename>: <what it shows>
```
- [ ] **Step 3: Verify the harness against the live homepage**
Load Playwright tool schemas (see Global Constraints note). Then:
1. `browser_resize` to 390×844.
2. `browser_navigate` to `https://schoolcompare.co.uk/`.
3. `browser_evaluate` with the contents of `axe-snippet.js` as the function body.
Expected: a JSON result with `violationCount` (any number ≥ 0) and no thrown error. If the CDN is blocked, switch the `src` to `https://unpkg.com/axe-core@4.10.2/axe.min.js` in the file and re-verify.
- [ ] **Step 4: Take a baseline screenshot to confirm capture works**
`browser_take_screenshot` with filename `home-mobile-baseline.png`. Expected: file saved, path returned.
- [ ] **Step 5: Commit**
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/
git commit -m "chore(audit): axe harness and notes template for UX audit"
```
---
### Task 2: Journey 1 — Home → find my school (63% of entries, 46% exits)
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-1-home-find-school.md` (copy structure from `TEMPLATE.md`)
**Interfaces:**
- Consumes: `axe-snippet.js` via `browser_evaluate`; `TEMPLATE.md` structure.
- Produces: `journey-1-home-find-school.md` — notes consumed by Task 8 synthesis.
- [ ] **Step 1: Mobile walk-through (390×844)**
1. `browser_resize` 390×844, `browser_navigate` `https://schoolcompare.co.uk/`.
2. `browser_snapshot` — record what is above the fold: is the search input visible without scrolling? What competes for attention? Screenshot `j1-home-mobile-fold.png`.
3. Scroll the full page (`browser_press_key` End or evaluate `window.scrollTo`), screenshot `j1-home-mobile-full.png`. Note content order: does featured/secondary content precede the primary task?
4. **Task attempt A (school by name):** type a real school name into search, e.g. `Welland Primary` (known from analytics). Record: keystrokes-to-results, result quality (is the right school first?), loading feedback, and taps needed to reach `/school/146678-welland-primary-school`. Screenshot the results state `j1-search-results-mobile.png`.
5. **Task attempt B (postcode):** return home, search a plausible postcode (e.g. `B91 3` area for Solihull, or any valid UK postcode like `SW1A 1AA`). Record: is postcode search discoverable/labelled? Distance shown? Sensible ordering? Screenshot `j1-postcode-results-mobile.png`.
6. Record time-to-school-page for both attempts against the spec's ~15s target.
7. Run axe snippet on: home (initial) and home (results visible). Record results.
- [ ] **Step 2: Desktop walk-through (1440×900)**
Repeat Step 1's navigation and task attempt A at 1440×900 (screenshots `j1-home-desktop-fold.png`, `j1-search-results-desktop.png`). Additionally: tab through the page with keyboard — record focus visibility and whether search → results → school link is keyboard-operable. Test 200% zoom (`browser_evaluate` `document.body.style.zoom` is NOT valid for this — instead resize to 720×450 which approximates 200% reflow at 1440) and note any loss of content/overlap.
- [ ] **Step 3: Write notes file**
Fill `journey-1-home-find-school.md` per template. Every friction point needs evidence + criterion + argument. Explicitly answer: "why do 46% of visitors exit at home?" — list the plausible causes observed.
- [ ] **Step 4: Commit**
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-1-home-find-school.md
git commit -m "docs(audit): journey 1 notes — home to school search"
```
---
### Task 3: Journey 2 — Cold landing on a school detail page (SEO long tail)
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-2-school-detail-cold.md`
**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-2-school-detail-cold.md` for Task 8.
- [ ] **Step 1: Mobile cold landing (390×844)**
Navigate **directly** (no prior site context — this simulates a Google arrival) to `https://schoolcompare.co.uk/school/136916-the-castle-school`. Then assess in order:
1. First-screen orientation: within one screen, can a parent tell what site this is, what school this is, and what the site offers? Screenshot `j2-school-mobile-fold.png`.
2. Scroll the entire page. Screenshots at each major section (`j2-school-mobile-<section>.png`). For each data block (results, Ofsted, characteristics, admissions): is it comprehensible to a non-specialist? Is jargon (RWM, expected standard, progress scores) explained in place?
3. Next-step paths: is there an obvious "compare this school" and "schools near this one" action? How many taps to a comparison including this school? Record the exact path or its absence.
4. Repeat the cold landing for a contrasting school `https://schoolcompare.co.uk/school/146678-welland-primary-school` (different data availability) — note any layout breakage or missing-data handling. Screenshot anomalies only.
5. Run axe snippet on both school pages. Record results.
- [ ] **Step 2: Desktop pass (1440×900)**
Reload `.../136916-the-castle-school` at desktop. Screenshot `j2-school-desktop-fold.png`. Check: hero/map rendering, chart legibility, keyboard focus through interactive elements, link affordance (do school-page links look clickable?).
- [ ] **Step 3: Write notes file**
Fill `journey-2-school-detail-cold.md`. Explicitly answer: "a parent lands here from Google — what would make them stay and use the site rather than bounce back to search results?"
- [ ] **Step 4: Commit**
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-2-school-detail-cold.md
git commit -m "docs(audit): journey 2 notes — cold landing on school detail"
```
---
### Task 4: Journey 3 — Building a comparison (27% of views, 32% exits)
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-3-compare.md`
**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-3-compare.md` for Task 8.
- [ ] **Step 1: Mobile walk-through (390×844)**
1. Navigate to `https://schoolcompare.co.uk/compare` **directly** (20% of sessions enter here). Screenshot empty state `j3-compare-empty-mobile.png`. Is the empty state instructive — does it tell a parent what to do first?
2. Add two schools via whatever mechanism the page offers (search within compare, or navigate to school pages and use their compare action — record which paths exist). Count taps from empty state to a two-school comparison. Screenshot `j3-compare-two-schools-mobile.png`.
3. Assess the comparison output on mobile: are charts/tables legible at 390px? Horizontal scrolling? Can you tell which school is which (colour + label, not colour alone — WCAG 1.4.1)? Are metric names explained?
4. Remove a school; add a third. Any state loss, confusing controls, or dead ends? Does the selection persist if you navigate away and back?
5. Run axe snippet on empty state and populated state. Record results.
- [ ] **Step 2: Desktop pass (1440×900)**
Repeat comparison-building at desktop. Screenshot `j3-compare-two-schools-desktop.png`. Keyboard-operate the add/remove flow; record focus behaviour. Check chart tooltips/legends for mouse-only interactions.
- [ ] **Step 3: Write notes file**
Fill `journey-3-compare.md`. Explicitly answer: "compare is 32% of exits — is that task-complete satisfaction (fine) or abandonment (problem)? What observed evidence points either way?"
- [ ] **Step 4: Commit**
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-3-compare.md
git commit -m "docs(audit): journey 3 notes — building a comparison"
```
---
### Task 5: Journey 4 — Rankings → shortlist (12% of views)
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-4-rankings.md`
**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-4-rankings.md` for Task 8.
- [ ] **Step 1: Mobile walk-through (390×844)**
1. Navigate to `https://schoolcompare.co.uk/rankings`. Screenshot default state `j4-rankings-mobile.png`.
2. Is the default ranking explained (which metric, which year, what the numbers mean)? Would a parent understand what "top" means here?
3. Filter to a local authority (e.g. Solihull). Count taps; is the filter discoverable on mobile? Screenshot filtered state `j4-rankings-filtered-mobile.png`.
4. Change the ranking metric. Is the metric picker comprehensible (plain-language labels vs. jargon)?
5. Tap through to a school from the list; navigate back — is filter state preserved? (Back-navigation state loss is a classic mobile task-killer.)
6. Run axe snippet on default and filtered states. Record results.
- [ ] **Step 2: Desktop pass (1440×900)**
Repeat at desktop, screenshot `j4-rankings-desktop.png`. Check table semantics (real `<table>` with headers vs. divs — screen-reader implications), sortability affordances, keyboard operation of filters.
- [ ] **Step 3: Write notes file + commit**
Fill `journey-4-rankings.md`.
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-4-rankings.md
git commit -m "docs(audit): journey 4 notes — rankings"
```
---
### Task 6: Journey 5 — Admissions content (5% of views, light pass)
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-5-admissions.md`
**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-5-admissions.md` for Task 8.
- [ ] **Step 1: Single mobile pass (390×844)**
1. Navigate to `https://schoolcompare.co.uk/admissions`. Screenshot `j5-admissions-mobile.png`.
2. Light checks only: readability (line length, heading hierarchy), whether the recently added SchoolCompare tool cross-links are present and useful, whether the page's look matches the rest of the site (this feeds the cohesion pass), and one axe scan.
3. Check discoverability in reverse: from the home page, how does a parent find this content at all? (5% views may be a discoverability problem rather than a demand problem — note evidence either way.)
- [ ] **Step 2: Write notes file + commit**
Fill `journey-5-admissions.md` (shorter than the others is expected).
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-5-admissions.md
git commit -m "docs(audit): journey 5 notes — admissions"
```
---
### Task 7: Cross-cutting cohesion pass
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/cohesion-pass.md`
**Interfaces:**
- Consumes: all journey screenshots (scratchpad) and notes files; live site; optionally `nextjs-app` source for token verification.
- Produces: `cohesion-pass.md` for Task 8.
- [ ] **Step 1: Component comparison across pages**
Using the screenshots already captured plus targeted re-visits, compare across `/`, `/compare`, `/rankings`, `/admissions`, and a school page:
1. **Typography:** collect computed styles via `browser_evaluate` on each page — e.g. `[...document.querySelectorAll('h1,h2,h3,body p, button, a')].slice(0,40).map(e => ({tag: e.tagName, size: getComputedStyle(e).fontSize, weight: getComputedStyle(e).fontWeight, family: getComputedStyle(e).fontFamily.split(',')[0]}))` — and diff the scales page-to-page. Record any page using off-scale sizes.
2. **Colour:** same technique for `color`, `backgroundColor` on buttons/links/chips; flag near-duplicate colours (e.g. two blues doing the same job) and any accent colour used inconsistently.
3. **Components:** buttons, chips, cards, empty states, loading states — screenshot side-by-side candidates and note variant drift (different radii, padding, casing, icon usage for the same semantic role).
4. **Navigation & page furniture:** header/footer consistency, page-title patterns, back-link behaviour, breadcrumbs presence/absence across page types.
5. **Recent additions check (from spec):** map-blended hero, characteristic chips, admissions cross-links — do they feel native to the rest of the site?
- [ ] **Step 2: Verify against source where ambiguous**
Where a visual inconsistency could be intentional, check `nextjs-app` styles (grep for the relevant component/tokens) to determine whether a design token exists and is being bypassed, or no token exists. Record which — it changes the recommendation (enforce token vs. create token).
- [ ] **Step 3: Write notes file + commit**
Fill `cohesion-pass.md` with the same evidence → criterion → argument structure (criterion here is typically "consistency and standards" heuristic).
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/cohesion-pass.md
git commit -m "docs(audit): cross-cutting cohesion pass notes"
```
---
### Task 8: Synthesis — prioritized audit report
**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-report.md`
- Read: all files in `docs/superpowers/specs/2026-07-02-ux-audit-notes/`, spec `docs/superpowers/specs/2026-07-02-ux-audit-design.md`
**Interfaces:**
- Consumes: journey notes 15, cohesion notes.
- Produces: the final deliverable report.
- [ ] **Step 1: Consolidate and deduplicate findings**
Read all six notes files. Merge duplicate findings (same root cause observed in several journeys becomes one finding listing all occurrences). Discard any finding lacking evidence or a cited criterion — the spec forbids taste-only findings.
- [ ] **Step 2: Assign final priorities and uplift indications**
For each finding assign P0P3 per the spec's definitions (traffic-weighted impact × severity), and an uplift line: **metric** (one of: home 46% exit rate; share of sessions reaching a school page; compare 32% exit rate; rankings→school click-through; school-page bounce-back-to-Google; accessibility compliance), **direction**, **band** (small/moderate/large) **with one-sentence reasoning**. Sanity rules: a P0/P1 must sit on `/`, `/compare`, `/rankings`, or the school-page template; admissions-only findings cap at P2 unless a WCAG failure.
- [ ] **Step 3: Write the report**
Structure (from spec):
```markdown
# SchoolCompare UX/UI Audit — 2026-07-02
## Method summary
<viewports, journeys, tools, analytics baseline — half a page>
## What works today — keep
<explicit list with why; protects against change-for-change's-sake>
## Findings
### P0 — Urgent
<each: title, evidence (screenshots/axe ids), criterion, argument, recommendation, uplift>
### P1 — High
### P2 — Medium
### P3 — Nice-to-have
## Accessibility summary
<axe violation table by page/viewport + manual check results; overall WCAG 2.2 AA posture>
## Suggested implementation sequence
<grouped batches of related fixes, ordered by uplift-per-effort; each batch sized as a plausible follow-up project>
```
- [ ] **Step 4: Self-check the report against the spec**
Verify: every finding has all four elements (evidence/argument/recommendation/uplift); "works well" section is non-empty; uplift bands never state invented percentages; P0/P1 findings all sit on high-traffic paths; report answers the spec's three goals (a) speed-to-information, (b) end-to-end cohesion, (c) standards compliance. Fix inline.
- [ ] **Step 5: Commit**
```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-report.md
git commit -m "docs(audit): prioritized UX/UI audit report"
```