@roopesh.yadava/qa-pack 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/bin/postinstall.js +151 -0
- package/claude/commands/bug-report.md +185 -0
- package/claude/commands/qa-agent.md +12 -0
- package/claude/commands/write-acceptance-criteria.md +167 -0
- package/claude/settings.json +13 -0
- package/claude/settings.local.json.example +19 -0
- package/claude/skills/SKILLS_CONTEXT.md +194 -0
- package/claude/skills/accessibility-testing/SKILL.md +317 -0
- package/claude/skills/accessibility-testing/WCAG_CHECKS.md +478 -0
- package/claude/skills/automation/BDD_TEMPLATES.md +237 -0
- package/claude/skills/automation/LOCATOR_PATTERNS.md +169 -0
- package/claude/skills/automation/SKILL.md +364 -0
- package/claude/skills/bug-reporting/SKILL.md +257 -0
- package/claude/skills/delete-files/SKILL.md +141 -0
- package/claude/skills/manual-testing/SKILL.md +493 -0
- package/claude/skills/qa-agent/SKILL.md +391 -0
- package/claude/skills/qa-agent/product_context/CONTEXT_SCHEMA.md +58 -0
- package/claude/skills/qa-agent/product_context/README.md +19 -0
- package/claude/skills/test-charter/SKILL.md +300 -0
- package/claude/skills/ui-test-figma/COMPARISON_PATTERNS.md +300 -0
- package/claude/skills/ui-test-figma/SKILL.md +234 -0
- package/package.json +29 -0
- package/templates/CLAUDE.md +41 -0
- package/templates/cucumber.cjs +7 -0
- package/templates/mcp.json +18 -0
- package/templates/settings.local.json.example +19 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# QA Skills — Context Map
|
|
2
|
+
<!-- Generated by graphify from .claude/skills. Load this instead of individual SKILL.md files
|
|
3
|
+
when you only need pipeline structure. Load a specific SKILL.md only when executing that skill. -->
|
|
4
|
+
|
|
5
|
+
## Global Token Rules — All Skills Must Follow
|
|
6
|
+
|
|
7
|
+
These rules apply to every skill, every run. Violating them is the single biggest source of token waste.
|
|
8
|
+
A 10-test run with `browser_snapshot()` per test = ~100k wasted tokens.
|
|
9
|
+
|
|
10
|
+
### Browser tool rules
|
|
11
|
+
|
|
12
|
+
| Operation | USE | NEVER USE | Token cost of violation |
|
|
13
|
+
|-----------|-----|-----------|------------------------|
|
|
14
|
+
| Screenshots | `npx playwright screenshot --full-page URL file.png` | `browser_screenshot()` | ~3k per image |
|
|
15
|
+
| DOM reading | `browser_evaluate` with targeted CSS/JS | `browser_snapshot()` | ~10k per call |
|
|
16
|
+
| Login selectors | ONE `browser_snapshot()` at login URL only | `browser_snapshot()` on any other page | one-time cost justified |
|
|
17
|
+
| Session reuse | `--storage-state .playwright-session.json` for all CLI calls | Re-logging in each run | login round-trip wasted |
|
|
18
|
+
|
|
19
|
+
### Context output rules
|
|
20
|
+
|
|
21
|
+
| Content | Output to | Never output to |
|
|
22
|
+
|---------|-----------|-----------------|
|
|
23
|
+
| Full test reports | File (`outputs/`) | Chat |
|
|
24
|
+
| Full bug descriptions | Jira via MCP | Chat |
|
|
25
|
+
| Gherkin feature files | Write tool (disk) | Pasted in full to chat |
|
|
26
|
+
| Step definitions | Write tool (disk) | Pasted in full to chat |
|
|
27
|
+
| POM class | Write tool (disk) | Pasted in full to chat |
|
|
28
|
+
| Token tracking output | Suppressed entirely | Chat |
|
|
29
|
+
|
|
30
|
+
**Chat shows only:** phase announcements (1 line each), running test count, failure IDs, bug keys, final summary table.
|
|
31
|
+
|
|
32
|
+
### Static file load rules
|
|
33
|
+
|
|
34
|
+
| File | Load | Frequency |
|
|
35
|
+
|------|------|-----------|
|
|
36
|
+
| `BDD_TEMPLATES.md` | Once at Phase 1 start | Never reload in the same run |
|
|
37
|
+
| `LOCATOR_PATTERNS.md` | Once at Phase 1 start | Never reload in Phase 2 or 3 |
|
|
38
|
+
| `WCAG_CHECKS.md` | Once at skill start | Never reload |
|
|
39
|
+
| `test-charter.md` | Once when charter starts | Never reload |
|
|
40
|
+
| `context.md` | Once at qa-agent Step 0 | Never reload |
|
|
41
|
+
|
|
42
|
+
After loading, reference rules by name only (e.g. "per Locator Priority Rule 1").
|
|
43
|
+
**Never re-quote static content** in follow-up messages — it is already in context.
|
|
44
|
+
|
|
45
|
+
### Prompt structure for cache efficiency
|
|
46
|
+
|
|
47
|
+
Structure every skill invocation in this order so the stable prefix can be cached by Anthropic:
|
|
48
|
+
```
|
|
49
|
+
[1] STABLE (cache-eligible — never changes between runs on same product)
|
|
50
|
+
Product context (context.md) + skill instructions (SKILL.md) + static templates loaded at start
|
|
51
|
+
|
|
52
|
+
[2] VARIABLE (changes every run — goes last)
|
|
53
|
+
Card ID + fetched card data + test results + current session data
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The stable block qualifies for Anthropic prompt caching when it exceeds 1024 tokens.
|
|
57
|
+
Cache TTL is 5 minutes. Keep the stable block identical across runs for the same product.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Pipeline Overview
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Jira Card ID (Atlassian MCP)
|
|
65
|
+
│
|
|
66
|
+
▼
|
|
67
|
+
┌──────────────┐
|
|
68
|
+
│ qa-agent │ ← entry point for all paths
|
|
69
|
+
└──────┬───────┘
|
|
70
|
+
│
|
|
71
|
+
┌────┴────┐
|
|
72
|
+
▼ ▼
|
|
73
|
+
[AUTO] [MANUAL]
|
|
74
|
+
│ │
|
|
75
|
+
▼ ▼ ─────────────────────────────┐
|
|
76
|
+
automation ui-test-figma (Figma MCP + Playwright CLI)
|
|
77
|
+
│ │
|
|
78
|
+
│ manual-testing (Playwright MCP)
|
|
79
|
+
│ │
|
|
80
|
+
│ bug-reporting (Atlassian MCP)
|
|
81
|
+
│ │
|
|
82
|
+
│ test-charter (REST API publish)
|
|
83
|
+
│ │
|
|
84
|
+
└────────────┘
|
|
85
|
+
│
|
|
86
|
+
Save Product Context
|
|
87
|
+
(product_context/{PRODUCT}/context.md)
|
|
88
|
+
│
|
|
89
|
+
End-to-End Testing complete
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Skills — One-Line Summary
|
|
93
|
+
|
|
94
|
+
| Skill | Input | Output | MCP Needed |
|
|
95
|
+
|-------|-------|--------|------------|
|
|
96
|
+
| `qa-agent` | Jira card ID or menu choice | Dispatches to correct skill | Atlassian |
|
|
97
|
+
| `automation` | Jira card ID | Gherkin + Step Defs + POM + dry-run | Atlassian, Playwright |
|
|
98
|
+
| `manual-testing` | Jira card ID + app URL | Execution report + bugs + charter | Atlassian, Playwright |
|
|
99
|
+
| `ui-test-figma` | Figma URL + app URL | UI mismatch report, Jira comment | Playwright (CLI+MCP), Figma (optional) |
|
|
100
|
+
| `accessibility-testing` | Full page URL + Jira card (optional) | WCAG 2.1 A/AA report + Jira bugs | Playwright (CLI+MCP), Atlassian |
|
|
101
|
+
| `bug-reporting` | Bug description | Bug filed on Jira card | Atlassian |
|
|
102
|
+
| `test-charter` | Execution report MD file | Charter MD + published to API | Playwright (login) |
|
|
103
|
+
|
|
104
|
+
## God Nodes (highest connectivity — touch these carefully)
|
|
105
|
+
|
|
106
|
+
1. `automation` — 13 edges (Gherkin→StepDefs→POM chain, token tracking, Playwright MCP)
|
|
107
|
+
2. `manual-testing` — 12 edges (orchestrates ui-test-figma, bug-reporting, test-charter)
|
|
108
|
+
3. `qa-agent` — 7 edges (dispatches all paths, owns Full E2E Pipeline)
|
|
109
|
+
4. `test-charter` — 6 edges (reads execution report, publishes to Decision Record API)
|
|
110
|
+
5. `ui-test-figma` — 6 edges (Figma MCP preferred, Playwright CLI fallback)
|
|
111
|
+
|
|
112
|
+
## Dispatch Map (qa-agent routes)
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
"automate CARD" → automation
|
|
116
|
+
"manual test" → manual-testing (calls ui-test-figma → bug-reporting → test-charter internally)
|
|
117
|
+
"ui test" → ui-test-figma (standalone)
|
|
118
|
+
"accessibility test" → accessibility-testing (standalone, URL + optional Jira card)
|
|
119
|
+
"file bug" → bug-reporting (standalone)
|
|
120
|
+
"charter" → test-charter (standalone)
|
|
121
|
+
"full QA" → automation THEN manual-testing → End-to-End complete
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Playwright Usage Guide (token budget)
|
|
125
|
+
|
|
126
|
+
### Expensive (avoid unless needed)
|
|
127
|
+
- `browser_snapshot()` — returns full DOM tree (10k+ tokens). Use only to read login form selectors.
|
|
128
|
+
- `browser_screenshot()` without saving — returns base64 (3k+ tokens). Always save to file.
|
|
129
|
+
|
|
130
|
+
### Cheap — prefer these
|
|
131
|
+
- `npx playwright screenshot --browser chromium --full-page <url> <file.png>` — 0 response tokens, saves to disk
|
|
132
|
+
- `browser_evaluate(targeted JS)` — targeted selector query, small response
|
|
133
|
+
- `npx playwright screenshot --storage-state <auth.json> --full-page <url> <file.png>` — with session
|
|
134
|
+
|
|
135
|
+
### Session save pattern (save once, reuse)
|
|
136
|
+
```bash
|
|
137
|
+
# After MCP login, save session to disk:
|
|
138
|
+
browser_evaluate("() => JSON.stringify({ls: {...localStorage}, ss: {...sessionStorage}})")
|
|
139
|
+
# Write result to .playwright-session.json
|
|
140
|
+
# Later CLI screenshots use: --storage-state .playwright-session.json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Token Tracking — canonical pattern (all skills follow this)
|
|
144
|
+
|
|
145
|
+
**Rules:** Silent background task. Never mention in conversation. Replace `CARD_ID` with the actual card ID.
|
|
146
|
+
Scripts live at `/home/user/projects/Smart-testing-with-AI-Agents/`.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
PROJECT=/home/user/projects/Smart-testing-with-AI-Agents
|
|
150
|
+
|
|
151
|
+
# Entry (before any work)
|
|
152
|
+
SNAP=$(python3 $PROJECT/context_snapshot.py --phase start) && \
|
|
153
|
+
python3 $PROJECT/track_tokens.py start --card CARD_ID $SNAP --model claude-sonnet-4-6
|
|
154
|
+
|
|
155
|
+
# After each phase (repeat per checkpoint, replacing PHASE_NAME)
|
|
156
|
+
SNAP=$(python3 $PROJECT/context_snapshot.py --phase PHASE_NAME) && \
|
|
157
|
+
python3 $PROJECT/track_tokens.py phase --card CARD_ID --name PHASE_NAME $SNAP
|
|
158
|
+
|
|
159
|
+
# Exit (after skill completes)
|
|
160
|
+
SNAP=$(python3 $PROJECT/context_snapshot.py --phase end) && \
|
|
161
|
+
python3 $PROJECT/track_tokens.py end --card CARD_ID $SNAP --model claude-sonnet-4-6 && \
|
|
162
|
+
python3 $PROJECT/track_tokens.py report && \
|
|
163
|
+
python3 $PROJECT/track_tokens.py session
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Phase names by skill:**
|
|
167
|
+
- automation: `start` → `jira_fetch` → `gherkin_generation` → `step_definitions` → `pom_generation` → `end`
|
|
168
|
+
- manual-testing: `start` → `jira_fetch` → `ui_testing` → `test_execution` → `end`
|
|
169
|
+
- ui-test-figma: `start` → `login` → `comparison` → `end`
|
|
170
|
+
- accessibility-testing: `start` → `login` → `a11y_checks` → `end`
|
|
171
|
+
- test-charter: `start` → `end`
|
|
172
|
+
|
|
173
|
+
**Tracking cache efficiency:**
|
|
174
|
+
|
|
175
|
+
The `track_tokens.py report` output includes `cache_efficiency_pct` — what percentage of input tokens were served from Anthropic's prompt cache rather than re-processed.
|
|
176
|
+
|
|
177
|
+
Also check `token_usage_log.json` for `cache_read_input_tokens` per phase to see exactly where cache hits occur.
|
|
178
|
+
|
|
179
|
+
Target: `cache_efficiency_pct` ≥ 70 after the first run on a given product.
|
|
180
|
+
First run will always be 0% (cold cache). Second and subsequent runs should cache the stable block (product context + skill instructions).
|
|
181
|
+
|
|
182
|
+
## Artifact Locations
|
|
183
|
+
|
|
184
|
+
| Artifact | Path |
|
|
185
|
+
|----------|------|
|
|
186
|
+
| Test execution report | `outputs/test-execution-[CARD]-[date].md` |
|
|
187
|
+
| Test charter | `outputs/charters/[slug].md` |
|
|
188
|
+
| Bug screenshots | `outputs/screenshots/T-[N]-[status].png` |
|
|
189
|
+
| Accessibility report | `outputs/a11y-report-[slug]-[date].md` |
|
|
190
|
+
| Accessibility baseline screenshot | `outputs/screenshots/a11y-baseline-[slug].png` |
|
|
191
|
+
| Auth session | `.playwright-session.json` (gitignored) |
|
|
192
|
+
| Token analytics | `~/.claude/token_analytics.png` |
|
|
193
|
+
| Knowledge graph | `graphify-out/graph.html` (open in browser) |
|
|
194
|
+
| Product QA context | `.claude/skills/qa-agent/product_context/[PRODUCT]/context.md` |
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: accessibility-testing
|
|
3
|
+
description: >
|
|
4
|
+
Tests a live web page against WCAG 2.1 Level A and AA criteria. Injects axe-core via
|
|
5
|
+
browser_evaluate for automated rule checks, then runs manual keyboard, focus, skip-link,
|
|
6
|
+
heading, and alt-text checks via Playwright MCP. Accepts a full page URL, logs in with
|
|
7
|
+
Playwright MCP (OTP always 999999), navigates to the target page, runs all checks, saves
|
|
8
|
+
a structured report to outputs/, and files violations as Jira bugs on the provided card.
|
|
9
|
+
Uses Playwright CLI for zero-token screenshots. Token tracking enabled.
|
|
10
|
+
Standalone or callable from qa-agent.
|
|
11
|
+
Trigger: "accessibility test", "a11y test", "run accessibility", "check WCAG",
|
|
12
|
+
"accessibility [URL]", "a11y [JIRA-KEY]", "test accessibility for [page]",
|
|
13
|
+
or "check accessibility".
|
|
14
|
+
compatibility: >
|
|
15
|
+
Playwright MCP must be running. axe-core injected at runtime from CDN — no install needed.
|
|
16
|
+
OTP always 999999. Playwright CLI (npx playwright) must be available.
|
|
17
|
+
user-invocable: true
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Accessibility Testing Skill — WCAG 2.1 Level A/AA
|
|
21
|
+
|
|
22
|
+
## Token Budget Rules — enforce throughout this skill
|
|
23
|
+
|
|
24
|
+
| Operation | USE | NEVER USE |
|
|
25
|
+
|-----------|-----|-----------|
|
|
26
|
+
| Page screenshots | `npx playwright screenshot --full-page URL file.png` | `browser_screenshot()` |
|
|
27
|
+
| DOM reading | `browser_evaluate` with targeted JS only | `browser_snapshot()` |
|
|
28
|
+
| Login form selectors | `browser_snapshot()` — **one time only** at login screen | Any other snapshot |
|
|
29
|
+
| axe-core checks | `browser_evaluate` injection + run | External a11y CLI tools |
|
|
30
|
+
|
|
31
|
+
## Token Tracking
|
|
32
|
+
|
|
33
|
+
Silent background task — follow the **Token Tracking** pattern in `SKILLS_CONTEXT.md`.
|
|
34
|
+
Checkpoints: `start` → `login` → `a11y_checks` → `end + report + session`.
|
|
35
|
+
Use `CARD_ID` if Jira card provided, else `"a11y-test"`. Never show tracking output to user.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Pipeline
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Full Page URL (input)
|
|
43
|
+
↓
|
|
44
|
+
[Step 0] Collect Inputs — URL, credentials, Jira card
|
|
45
|
+
↓
|
|
46
|
+
[Step 1] Login via Playwright MCP (skip if session active)
|
|
47
|
+
↓
|
|
48
|
+
[Step 2] Navigate to Target Page + Baseline Screenshot
|
|
49
|
+
↓
|
|
50
|
+
[Step 3] axe-Core Automated Checks (WCAG 2.1 A + AA)
|
|
51
|
+
↓
|
|
52
|
+
[Step 4] Manual Checks — keyboard, focus, skip link, headings, alt text
|
|
53
|
+
↓
|
|
54
|
+
[Step 5] Generate + Save Report → outputs/a11y-report-[slug]-[date].html
|
|
55
|
+
↓
|
|
56
|
+
[Step 6] File Jira Bugs (critical/serious → individual bugs; moderate/minor → comment)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Step 0 — Collect Inputs
|
|
62
|
+
|
|
63
|
+
Run token tracking `start` checkpoint.
|
|
64
|
+
|
|
65
|
+
Ask questions **one at a time**. Wait for each answer before asking the next.
|
|
66
|
+
|
|
67
|
+
**Question 1 — Page URL:**
|
|
68
|
+
> "Please paste the **full URL of the page** you want to accessibility-test.
|
|
69
|
+
> (e.g. `https://app.example.com/dashboard/settings`)"
|
|
70
|
+
|
|
71
|
+
Store as `TARGET_URL`.
|
|
72
|
+
Extract `BASE_URL` = scheme + host (e.g. `https://app.example.com`).
|
|
73
|
+
Extract `URL_SLUG` = last 2 meaningful path segments, lowercase, hyphens, strip UUIDs.
|
|
74
|
+
|
|
75
|
+
**Question 2 — Jira Card:**
|
|
76
|
+
> "Do you have a **Jira card ID** to file bugs against? (e.g. `QA-123`)
|
|
77
|
+
> Type `skip` to only generate the report."
|
|
78
|
+
|
|
79
|
+
- If provided: store `JIRA_CARD_ID`, set `FILE_JIRA = true`
|
|
80
|
+
- If skipped: set `FILE_JIRA = false`
|
|
81
|
+
|
|
82
|
+
**Question 3 — Check if login is needed:**
|
|
83
|
+
|
|
84
|
+
`browser_navigate(url: BASE_URL)` then `browser_wait_for(state: "networkidle")`.
|
|
85
|
+
|
|
86
|
+
Check the current URL:
|
|
87
|
+
- Redirected to `/login`, `/sign-in`, `/auth` → session not active, ask for credentials.
|
|
88
|
+
- Dashboard / main nav visible → session already active, skip to Step 2.
|
|
89
|
+
|
|
90
|
+
If login needed:
|
|
91
|
+
> "What is the **email** for login?"
|
|
92
|
+
> (after answer) "And the **password**?"
|
|
93
|
+
|
|
94
|
+
Store: `EMAIL`, `PASSWORD`.
|
|
95
|
+
|
|
96
|
+
Once all inputs collected:
|
|
97
|
+
> "Got it — logging in and starting the accessibility checks..."
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Step 1 — Login to the Application
|
|
102
|
+
|
|
103
|
+
**Skip entirely if Step 0 Q3 confirmed session already active.**
|
|
104
|
+
|
|
105
|
+
1. `browser_wait_for(state: "networkidle")`
|
|
106
|
+
2. `browser_snapshot()` — **one allowed snapshot** to read login form selectors
|
|
107
|
+
3. `browser_fill` email field using selector found
|
|
108
|
+
4. `browser_fill` password field using selector found
|
|
109
|
+
5. `browser_click` login / sign-in button
|
|
110
|
+
6. `browser_wait_for(state: "networkidle")`
|
|
111
|
+
|
|
112
|
+
**If OTP screen appears** (6-digit input / PIN boxes):
|
|
113
|
+
7. `browser_click` first OTP input box
|
|
114
|
+
8. `browser_type(text: "999999")` — always this value, auto-advances through boxes
|
|
115
|
+
9. `browser_click` Verify / Confirm button
|
|
116
|
+
10. `browser_wait_for(state: "networkidle")`
|
|
117
|
+
|
|
118
|
+
Confirm login success: main nav or dashboard visible → proceed.
|
|
119
|
+
Still on login page → stop and report: `"Login failed — please verify credentials."`
|
|
120
|
+
|
|
121
|
+
**Save authenticated session to disk:**
|
|
122
|
+
```javascript
|
|
123
|
+
browser_evaluate({
|
|
124
|
+
expression: `JSON.stringify({
|
|
125
|
+
localStorage: Object.fromEntries(Object.entries(localStorage)),
|
|
126
|
+
sessionStorage: Object.fromEntries(Object.entries(sessionStorage)),
|
|
127
|
+
cookies: document.cookie
|
|
128
|
+
})`
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
Write result to `.playwright-session.json`.
|
|
132
|
+
|
|
133
|
+
Run `login` token checkpoint.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Step 2 — Navigate to Target Page + Baseline Screenshot
|
|
138
|
+
|
|
139
|
+
1. `browser_navigate(url: TARGET_URL)`
|
|
140
|
+
2. `browser_wait_for(state: "networkidle")`
|
|
141
|
+
3. Take baseline screenshot via Playwright CLI (zero response tokens):
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
mkdir -p outputs/screenshots
|
|
145
|
+
npx playwright screenshot \
|
|
146
|
+
--browser chromium \
|
|
147
|
+
--full-page \
|
|
148
|
+
--viewport-size "1920,1080" \
|
|
149
|
+
--wait-for-timeout 3000 \
|
|
150
|
+
"TARGET_URL" \
|
|
151
|
+
outputs/screenshots/a11y-baseline-URL_SLUG.png
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Store as `BASELINE_SCREENSHOT = outputs/screenshots/a11y-baseline-[URL_SLUG].png`.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Step 3 — axe-Core Automated Checks
|
|
159
|
+
|
|
160
|
+
Load `.claude/skills/accessibility-testing/WCAG_CHECKS.md` now.
|
|
161
|
+
|
|
162
|
+
### 3a — Inject axe-core
|
|
163
|
+
|
|
164
|
+
Run the **axe-Core Injection Script** from `WCAG_CHECKS.md` via `browser_evaluate`.
|
|
165
|
+
|
|
166
|
+
- Returns `"loaded"` or `"already loaded"` → proceed to 3b.
|
|
167
|
+
- Returns rejection / CDN error → set `AXE_BLOCKED = true`, add note to report:
|
|
168
|
+
`"axe-core CDN blocked by CSP — automated checks skipped, manual checks only."`,
|
|
169
|
+
skip to Step 4.
|
|
170
|
+
|
|
171
|
+
### 3b — Run axe-core
|
|
172
|
+
|
|
173
|
+
Run the **axe-Core Run Script** from `WCAG_CHECKS.md` via `browser_evaluate`.
|
|
174
|
+
Parse the returned JSON. Store as `AXE_RESULT`.
|
|
175
|
+
|
|
176
|
+
Bucket violations by impact:
|
|
177
|
+
- `CRITICAL_VIOLATIONS` — impact: `"critical"`
|
|
178
|
+
- `SERIOUS_VIOLATIONS` — impact: `"serious"`
|
|
179
|
+
- `MODERATE_VIOLATIONS` — impact: `"moderate"`
|
|
180
|
+
- `MINOR_VIOLATIONS` — impact: `"minor"`
|
|
181
|
+
|
|
182
|
+
Show one-line tally in chat:
|
|
183
|
+
> `"axe-core: [N] critical | [N] serious | [N] moderate | [N] minor violations found."`
|
|
184
|
+
|
|
185
|
+
Run `a11y_checks` token checkpoint.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Step 4 — Manual Checks
|
|
190
|
+
|
|
191
|
+
Load `.claude/skills/accessibility-testing/WCAG_CHECKS.md`.
|
|
192
|
+
|
|
193
|
+
Run each script via `browser_evaluate`. Store results for the report.
|
|
194
|
+
|
|
195
|
+
### Check A — Keyboard Traversal (WCAG 2.1.1)
|
|
196
|
+
Run **Check A — Keyboard Traversal Script**.
|
|
197
|
+
Record: total focusable count, elements removed from tab order, first 10 elements.
|
|
198
|
+
Flag if: focusableCount = 0, or interactive elements like buttons/inputs appear in `removedFromTab`
|
|
199
|
+
that should be reachable.
|
|
200
|
+
|
|
201
|
+
### Check B — Focus Visibility (WCAG 2.4.7)
|
|
202
|
+
Run **Check B — Focus Visibility Script**.
|
|
203
|
+
Flag if: `outlineNoneCount > 0` (outline suppressed on focused elements) or `totalFocusRules = 0`.
|
|
204
|
+
Note if `hasFocusVisible = true` (modern `:focus-visible` present — good practice).
|
|
205
|
+
|
|
206
|
+
### Check C — Skip Navigation Link (WCAG 2.4.1)
|
|
207
|
+
Run **Check C — Skip Navigation Link Script**.
|
|
208
|
+
Flag if: `hasSkipLink = false`.
|
|
209
|
+
|
|
210
|
+
### Check D — Heading Hierarchy (WCAG 1.3.1)
|
|
211
|
+
Run **Check D — Heading Hierarchy Script**.
|
|
212
|
+
Report all issues from `issues[]` array.
|
|
213
|
+
Flag if: `h1Count ≠ 1` or `levelSkips.length > 0`.
|
|
214
|
+
|
|
215
|
+
### Check E — Image Alt Text (WCAG 1.1.1) — cross-check against axe
|
|
216
|
+
Run **Check E — Image Alt Text Script**.
|
|
217
|
+
Flag if: `missingAlt > 0`. Note `emptyAlt` (decorative images with empty alt = OK if intentional).
|
|
218
|
+
Flag if: `svgMissingLabel > 0` (inline SVGs without accessible name).
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Step 5 — Generate + Save Report
|
|
223
|
+
|
|
224
|
+
Load the **Report Template** from `WCAG_CHECKS.md`.
|
|
225
|
+
|
|
226
|
+
Build the full report using:
|
|
227
|
+
- `AXE_RESULT` — all violation buckets
|
|
228
|
+
- Manual check results from Steps A–E
|
|
229
|
+
- `BASELINE_SCREENSHOT` path
|
|
230
|
+
- `WCAG Criterion Quick Reference` and `Severity Mapping` from `WCAG_CHECKS.md`
|
|
231
|
+
|
|
232
|
+
Derive filename: `outputs/a11y-report-[URL_SLUG]-[YYYYMMDD].html`
|
|
233
|
+
|
|
234
|
+
Save the file. Tell user (one line):
|
|
235
|
+
> `"Report saved: outputs/a11y-report-[URL_SLUG]-[YYYYMMDD].html"`
|
|
236
|
+
|
|
237
|
+
Run `end + report + session` token close-out.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Step 6 — Jira Bug Filing
|
|
242
|
+
|
|
243
|
+
**Skip entirely if `FILE_JIRA = false`.**
|
|
244
|
+
|
|
245
|
+
> `"[Step 6] Filing accessibility bugs on [JIRA_CARD_ID]..."`
|
|
246
|
+
|
|
247
|
+
Use `getJiraIssue` to confirm `JIRA_CARD_ID` exists. Extract `PROJECT_KEY`.
|
|
248
|
+
|
|
249
|
+
### Critical + Serious → individual Jira Bugs
|
|
250
|
+
|
|
251
|
+
For each violation in `CRITICAL_VIOLATIONS` and `SERIOUS_VIOLATIONS`:
|
|
252
|
+
|
|
253
|
+
Create a Jira Bug using the **Jira Bug Template** from `WCAG_CHECKS.md`:
|
|
254
|
+
- **Issue type:** Bug
|
|
255
|
+
- **Summary:** `[A11Y-{IMPACT}] [WCAG {criterion}] — {rule description} on /{URL_SLUG}`
|
|
256
|
+
- **Priority:** Critical → P1 Blocker | Serious → P2 High
|
|
257
|
+
- **Labels:** `accessibility`, `wcag-2.1`, `a11y-{impact}`
|
|
258
|
+
- **Link to:** `JIRA_CARD_ID` ("relates to")
|
|
259
|
+
|
|
260
|
+
Parallelize bug creation where possible.
|
|
261
|
+
|
|
262
|
+
### Moderate + Minor → single summary comment
|
|
263
|
+
|
|
264
|
+
Use the **Jira Comment Template** from `WCAG_CHECKS.md`.
|
|
265
|
+
Post via `addCommentToJiraIssue` on `JIRA_CARD_ID`.
|
|
266
|
+
|
|
267
|
+
### Completion comment on JIRA_CARD_ID
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
♿ Accessibility Testing Complete — WCAG 2.1 AA
|
|
271
|
+
|
|
272
|
+
Page: [TARGET_URL]
|
|
273
|
+
Results: [N] critical | [N] serious | [N] moderate | [N] minor
|
|
274
|
+
|
|
275
|
+
Bugs filed: [PROJ-xxx], [PROJ-yyy]
|
|
276
|
+
Report: outputs/a11y-report-[URL_SLUG]-[YYYYMMDD].html
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Final Chat Summary
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
Accessibility Testing Complete
|
|
285
|
+
Page : [TARGET_URL]
|
|
286
|
+
WCAG Level : 2.1 AA
|
|
287
|
+
|
|
288
|
+
Critical : N violations
|
|
289
|
+
Serious : N violations
|
|
290
|
+
Moderate : N violations
|
|
291
|
+
Minor : N violations
|
|
292
|
+
|
|
293
|
+
Keyboard : OK / N interactive elements unreachable
|
|
294
|
+
Focus styles : OK / outline:none found on N selectors
|
|
295
|
+
Skip link : Present / Missing (WCAG 2.4.1)
|
|
296
|
+
Heading order : OK / [issues]
|
|
297
|
+
Image alt : OK / N missing alt attributes
|
|
298
|
+
|
|
299
|
+
Jira bugs : [keys] / skipped
|
|
300
|
+
Report : outputs/a11y-report-[URL_SLUG]-[YYYYMMDD].html
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Error Handling
|
|
306
|
+
|
|
307
|
+
| Situation | Action |
|
|
308
|
+
|-----------|--------|
|
|
309
|
+
| Login fails | Stop — `"Login failed, please check credentials."` |
|
|
310
|
+
| TARGET_URL not reachable after login | Stop — check URL and auth redirect |
|
|
311
|
+
| axe-core CDN blocked (CSP) | Flag in report, continue with manual checks only |
|
|
312
|
+
| `axe.run()` throws / times out | Retry scoped to `main` or `#content` only, note partial result |
|
|
313
|
+
| `browser_evaluate` returns null | Log "script returned null" for that check, continue |
|
|
314
|
+
| Jira card not found | Ask to verify key; offer to save report only |
|
|
315
|
+
| Jira bug creation fails | Note failure, continue remaining bugs, report failures at end |
|
|
316
|
+
| OTP screen appears unexpectedly | Type `"999999"`, proceed |
|
|
317
|
+
| Page requires further navigation after login | Follow redirect, confirm TARGET_URL loads |
|