.agents/skills/ibm-a11y-level1-audit/SKILL.md
Audit → report → fix → verify. Scope is IBM Equal Access Toolkit v7.3 Level 1 only. Do not expand into Level 2/3 unless the user asks.
| Skill | Use for |
|---|---|
| frontend-a11y-check | How to write/run axe + IBM scans, baselines, component gotchas |
| ibm-a11y-automation | Python route scanner + Markdown/HTML report generation |
| frontend-i18n | Any new/changed accessible names or UI strings |
src/frontend/tests/a11y/ibm-able-level-1-requirements.md — 21 requirements from the IBM Able UI Level 1 filter. Prefer the engineering guide when the two disagree on pace; still map findings to both IDs when useful.src/frontend/tests/a11y/ — Playwright specs, baselines, README. Confirm this path exists before claiming coverage.Copy and track:
Level 1 Audit Progress:
- [ ] 1. Scope the surface
- [ ] 2. Scan (IBM + axe as applicable)
- [ ] 3. Map findings to Level 1 criteria
- [ ] 4. Write the report
- [ ] 5. Fix violations
- [ ] 6. Verify with tests/a11y
- [ ] 7. Re-scan and update report status
Identify what to audit from the user request:
src/frontendRead src/frontend/tests/a11y/README.md and list existing specs that already cover the surface.
Run both engines when the surface is interactive UI (see frontend-a11y-check):
# Playwright IBM scans (live DOM / stateful)
cd src/frontend
RUN_A11Y=true RUN_A11Y_ASSERT=true npx playwright test tests/a11y/<feature>.a11y.spec.ts --project=chromium --workers=5
# Optional: HTML triage report
npm run a11y:html-report --silent
# → coverage/accessibility-reports/index.html
# Ad-hoc route batch (default-loaded page only)
uv run --with playwright python scripts/a11y/a11y_scan.py \
--url http://localhost:3000 \
--routes-file scripts/a11y/a11y_routes.json \
--route-group static \
--out /tmp/langflow-a11y.json \
--markdown /tmp/langflow-a11y.md \
--html /tmp/langflow-a11y.html \
--timeout-ms 45000
For component-only changes, also run Jest axe where a __tests__/*.a11y.test.tsx exists.
Do not invent findings. Prefer scanner output + manual Level 1 checks scanners miss (keyboard trap both directions, focus restore, reflow at 320px, color-not-only cues).
For each issue, assign:
2.1.1, 4.1.2)aria_accessiblename_exists, element_tabbable_role_valid, …)violation | potentialviolation | manualUse references/report-template.md. Deliver the report in the chat (and write a file only if the user asks for a path).
Required sections: Summary, Scope, Findings table, Fixes applied / proposed, Verification, Remaining risk / baselines.
When this skill is invoked for audit+fix (default), fix in-scope Level 1 violations:
frontend-a11y-check (AG Grid, Radix asChild, focus restore, icon-only aria-label).aria-labels through frontend-i18n.src/frontend/tests/a11y/baselines/ only for documented framework debt (see frontend-a11y-check).If the user asked for report only, stop after step 4 and list proposed fixes without editing.
tests/a11yConfirm path: src/frontend/tests/a11y/.
| Surface | Spec to run / update |
|---|---|
| Static routes | static-routes.a11y.spec.ts (+ scripts/a11y/a11y_routes.json if new route) |
| Auth | auth-pages.a11y.spec.ts |
| Core pages | core-pages.a11y.spec.ts |
| Data-rich (files, API keys, globals) | files.a11y.spec.ts, api-keys.a11y.spec.ts, global-variables.a11y.spec.ts |
| Other data-rich | data-rich-routes.a11y.spec.ts |
| Baselines | baselines/*.json |
Commands:
cd src/frontend
RUN_A11Y=true RUN_A11Y_ASSERT=true npx playwright test tests/a11y/<relevant>.a11y.spec.ts --project=chromium --workers=5
If coverage is missing for a fixed state, add a scan (and keyboard test when custom keyboard behavior was fixed) following files.a11y.spec.ts / api-keys.a11y.spec.ts patterns.
Re-run the same scans. Update the report: each finding → fixed | baselined | open. State commands run and whether IBM assert mode passed.
Scanners miss some Level 1 tasks — spot-check when relevant:
When auditing or fixing settings tables (especially /settings/global-variables) and similar AG Grid + modal flows, treat these as Level 1 best practices (2.1.1 / 2.4.3) — not edge-case gotchas.
Reference implementation: GlobalVariablesPage + tests/a11y/global-variables.a11y.spec.ts.
| Key | Behavior |
|---|---|
| Space | Toggle the row selection checkbox (do not open edit) |
| Enter | Open the Update Variable modal for the focused row |
Implementation notes:
onCellKeyDown only (do not change shared TableComponent defaults for other grids unless the product asks for the same map).suppressKeyboardEvent on that page’s column defs for Enter/Space so AG Grid’s built-in Space selection does not fight the custom handler.node.setSelected so toolbar delete enablement updates (TableOptions.hasSelection is read at render time).rowIndex + colId).api.setFocusedCell + DOM .focus(), using a few requestAnimationFrames to outlast Radix dialog focus cleanup.DialogTrigger exists).document.activeElement is still that cell (or its col-id), then Enter can open again without a manual mouse re-focus.For AG Grid pagination/tab traps, Radix asChild, and popover Esc restore details, see frontend-a11y-check (Gotchas vs Best practices sections).