Epic: Accessibility hardening (SonarQube a11y backlog — alt text, keyboard equivalents, ARIA) #732

Closed
opened 2026-07-20 04:05:51 +00:00 by spikerj · 5 comments
Owner

Epic: Accessibility hardening (SonarQube a11y findings)

During the SonarQube reliability-backlog triage of learn.spikersoft.com, a large share of the "bug"/reliability findings turned out to be legitimate accessibility gaps — not false positives and not runtime crashes, but real a11y debt that needs content/UX decisions rather than mechanical fixes. Grouping them here as an epic instead of closing or blindly patching them one-by-one in the bug loop.

Reliability-impact a11y findings (the a11y portion of the "285 bugs"):

Rule Count What it needs
Web:ImgWithoutAltCheck 72 alt text on <img> (content decision per image; alt="" for decorative)
Web:MouseEventWithoutKeyboardEquivalentCheck 26 keyboard handlers to pair (click)/mouse-only interactions
Web:S6845 (aria roles) 14 valid ARIA roles
Web:S6851 12 non-interactive elements w/ handlers need role/keyboard
Web:S6842 11 non-interactive elements shouldn't have interactive ARIA
Web:S6840 6 form field labels/aria
Web:S5256 / Web:S5257 / Web:S5255 ~13 table <th> headers, layout-table semantics

(A broader accessibility-tagged set exists — css:S7924 371, Web:S6819 119, etc. — mostly maintainability-impact; can fold in or split as a phase 2.)

Why an epic, not per-line triage

These are real (should not be marked false-positive) but each requires human judgment: which images are decorative vs meaningful, what keyboard interaction mirrors a given mouse gesture, correct ARIA semantics. That's a focused a11y pass (ideally with axe/Playwright a11y assertions added to CI for regression coverage), not bug-loop churn.

Suggested approach

  1. Add automated a11y checks to the e2e suite (axe-core) so fixes are regression-guarded.
  2. Batch by component area (blog, photo-gallery, games, dev-tools) — knock out ImgWithoutAlt + MouseEventWithoutKeyboard first (highest count, clearest fixes).
  3. Track sub-tasks under this epic.

SonarQube

learn.spikersoft.comhttps://sonarqube.spikersoft.com/dashboard?id=learn.spikersoft.com (filter tag accessibility)

Filed from the SonarQube reliability-backlog triage loop; these findings are intentionally LEFT OPEN (real work), not closed as false-positive.

### Epic: Accessibility hardening (SonarQube a11y findings) During the SonarQube reliability-backlog triage of `learn.spikersoft.com`, a large share of the "bug"/reliability findings turned out to be **legitimate accessibility gaps** — not false positives and not runtime crashes, but real a11y debt that needs content/UX decisions rather than mechanical fixes. Grouping them here as an epic instead of closing or blindly patching them one-by-one in the bug loop. **Reliability-impact a11y findings (the a11y portion of the "285 bugs"):** | Rule | Count | What it needs | |---|---|---| | `Web:ImgWithoutAltCheck` | 72 | `alt` text on `<img>` (content decision per image; `alt=""` for decorative) | | `Web:MouseEventWithoutKeyboardEquivalentCheck` | 26 | keyboard handlers to pair `(click)`/mouse-only interactions | | `Web:S6845` (aria roles) | 14 | valid ARIA roles | | `Web:S6851` | 12 | non-interactive elements w/ handlers need role/keyboard | | `Web:S6842` | 11 | non-interactive elements shouldn't have interactive ARIA | | `Web:S6840` | 6 | form field labels/aria | | `Web:S5256` / `Web:S5257` / `Web:S5255` | ~13 | table `<th>` headers, layout-table semantics | (A broader accessibility-tagged set exists — `css:S7924` 371, `Web:S6819` 119, etc. — mostly maintainability-impact; can fold in or split as a phase 2.) ### Why an epic, not per-line triage These are **real** (should not be marked false-positive) but each requires human judgment: which images are decorative vs meaningful, what keyboard interaction mirrors a given mouse gesture, correct ARIA semantics. That's a focused a11y pass (ideally with axe/Playwright a11y assertions added to CI for regression coverage), not bug-loop churn. ### Suggested approach 1. Add automated a11y checks to the e2e suite (axe-core) so fixes are regression-guarded. 2. Batch by component area (blog, photo-gallery, games, dev-tools) — knock out `ImgWithoutAlt` + `MouseEventWithoutKeyboard` first (highest count, clearest fixes). 3. Track sub-tasks under this epic. ### SonarQube `learn.spikersoft.com` — https://sonarqube.spikersoft.com/dashboard?id=learn.spikersoft.com (filter tag `accessibility`) _Filed from the SonarQube reliability-backlog triage loop; these findings are intentionally LEFT OPEN (real work), not closed as false-positive._
Author
Owner

Phase 1 shipped for review: spikersoft-angular PR #507 (see #772). Epic reshape: the 72-image alt pile was entirely the vendored Kenney Overview.html (now sonar-excluded) — real app debt is ~82 findings across ~40 files. axe-core gate now guards all public routes in CI (alt-class hard-fails, rest reported per-route). Batch 1: 18 fixed (chip keyboard activation, landmark labels, tablist roles), 4 accepted as correct WAI-ARIA splitter widgets. ~60 findings remain for future batches.

Phase 1 shipped for review: spikersoft-angular PR #507 (see #772). Epic reshape: the 72-image alt pile was entirely the vendored Kenney Overview.html (now sonar-excluded) — real app debt is ~82 findings across ~40 files. axe-core gate now guards all public routes in CI (alt-class hard-fails, rest reported per-route). Batch 1: 18 fixed (chip keyboard activation, landmark labels, tablist roles), 4 accepted as correct WAI-ARIA splitter widgets. ~60 findings remain for future batches.
Author
Owner

Batch 2 up for review: spikersoft-angular PR #508 — all 60 remaining Sonar a11y findings dispositioned (38 fixed incl. a real keyboard bug in git playground's file list; 22 FP/deferred, marked in SonarQube with rationale). Key FP discovery: Sonar reads Angular binding expressions as literal attribute text, which misfires the redundant-alt rule on every [alt]="photo.x" binding. With phase 1 + batch 2, the Sonar a11y reliability backlog is fully dispositioned; remaining epic work = the phase-2 maintainability-tagged set + the axe per-route annotations as living inventory.

Batch 2 up for review: spikersoft-angular PR #508 — all 60 remaining Sonar a11y findings dispositioned (38 fixed incl. a real keyboard bug in git playground's file list; 22 FP/deferred, marked in SonarQube with rationale). Key FP discovery: Sonar reads Angular binding expressions as literal attribute text, which misfires the redundant-alt rule on every [alt]="photo.x" binding. With phase 1 + batch 2, the Sonar a11y reliability backlog is fully dispositioned; remaining epic work = the phase-2 maintainability-tagged set + the axe per-route annotations as living inventory.
Author
Owner

Batch 2 merged (spikersoft-angular PR #508): the entire Sonar a11y reliability set is now dispositioned — phase 1 + batch 2 fixed 56 findings, 26 accepted with rationale, axe gate live in CI. Epic stays open for the phase-2 maintainability-tagged set and future axe-annotation-driven work.

Batch 2 merged (spikersoft-angular PR #508): the entire Sonar a11y reliability set is now dispositioned — phase 1 + batch 2 fixed 56 findings, 26 accepted with rationale, axe gate live in CI. Epic stays open for the phase-2 maintainability-tagged set and future axe-annotation-driven work.
Author
Owner

PHASE 2 COMPLETE (PR #509 pending merge): the 519 accessibility-tagged maintainability findings are fully dispositioned — 374 contrast findings accepted as translucent-compositing static-analysis misfires (runtime axe gate is the authoritative contrast check), 125 prefer-tag-over-role accepted as APG-valid custom widgets, 7 mechanical fixes shipped (label associations + destination-chips native list, incl. a real S6843 role conflict masking button semantics), 8 video-caption findings split to their own content/feature ticket. Once #509 merges, every Sonar a11y finding on learn.spikersoft.com is fixed, accepted-with-rationale, or tracked elsewhere — recommend closing this epic then.

PHASE 2 COMPLETE (PR #509 pending merge): the 519 accessibility-tagged maintainability findings are fully dispositioned — 374 contrast findings accepted as translucent-compositing static-analysis misfires (runtime axe gate is the authoritative contrast check), 125 prefer-tag-over-role accepted as APG-valid custom widgets, 7 mechanical fixes shipped (label associations + destination-chips native list, incl. a real S6843 role conflict masking button semantics), 8 video-caption findings split to their own content/feature ticket. Once #509 merges, every Sonar a11y finding on learn.spikersoft.com is fixed, accepted-with-rationale, or tracked elsewhere — recommend closing this epic then.
Author
Owner

PR #509 merged — epic complete. Final tally across the whole effort: ~150 reliability-tagged + 519 maintainability-tagged a11y findings all dispositioned — 63 code fixes across ~40 components (incl. three real defects: git-playground keyboard selection never worked, chip Space-scrolls-page activation, destination-chips role masking button semantics), ~528 accepted with written rationale (vendored page, translucent-compositing contrast misfires, APG-valid custom widgets, binding-expression misfires), video captions split to #777, and the axe-core WCAG-AA runtime gate now guards every public route in CI (alt-class hard-fails; other rules promotable as they're cleaned). Closing.

PR #509 merged — epic complete. Final tally across the whole effort: ~150 reliability-tagged + 519 maintainability-tagged a11y findings all dispositioned — 63 code fixes across ~40 components (incl. three real defects: git-playground keyboard selection never worked, chip Space-scrolls-page activation, destination-chips role masking button semantics), ~528 accepted with written rationale (vendored page, translucent-compositing contrast misfires, APG-valid custom widgets, binding-expression misfires), video captions split to #777, and the axe-core WCAG-AA runtime gate now guards every public route in CI (alt-class hard-fails; other rules promotable as they're cleaned). Closing.
Sign in to join this conversation.