@a11y-oracle/audit-formatter 1.0.0
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 +281 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/lib/formatters.d.ts +105 -0
- package/dist/lib/formatters.d.ts.map +1 -0
- package/dist/lib/formatters.js +317 -0
- package/dist/lib/oracle-auditor.d.ts +80 -0
- package/dist/lib/oracle-auditor.d.ts.map +1 -0
- package/dist/lib/oracle-auditor.js +97 -0
- package/dist/lib/rules.d.ts +37 -0
- package/dist/lib/rules.d.ts.map +1 -0
- package/dist/lib/rules.js +133 -0
- package/dist/lib/selector.d.ts +38 -0
- package/dist/lib/selector.d.ts.map +1 -0
- package/dist/lib/selector.js +99 -0
- package/dist/lib/types.d.ts +138 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +13 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# @a11y-oracle/audit-formatter
|
|
2
|
+
|
|
3
|
+
Converts A11y-Oracle findings into axe-core-compatible issue objects (`OracleIssue`). Pure functions with no CDP dependency — works with any `A11yState` or `TraversalResult` regardless of how it was produced.
|
|
4
|
+
|
|
5
|
+
Output is differentiated from axe-core findings by `resultType: 'oracle'` and `oracle/`-prefixed rule IDs (e.g., `oracle/focus-not-visible`).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @a11y-oracle/audit-formatter
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> **Note:** Most users should use the [`@a11y-oracle/playwright-plugin`](../playwright-plugin/README.md) or [`@a11y-oracle/cypress-plugin`](../cypress-plugin/README.md) instead. The audit-formatter is the underlying library that those plugins use. Install it directly if you need to format issues outside a test framework or build a custom integration.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Pure Formatter Functions
|
|
18
|
+
|
|
19
|
+
The simplest approach — pass an `A11yState` and get back any issues:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { formatFocusIssues, formatTrapIssue } from '@a11y-oracle/audit-formatter';
|
|
23
|
+
import type { A11yState } from '@a11y-oracle/core-engine';
|
|
24
|
+
import type { TraversalResult } from '@a11y-oracle/focus-analyzer';
|
|
25
|
+
|
|
26
|
+
const context = { project: 'my-app', specName: 'nav.spec.ts' };
|
|
27
|
+
|
|
28
|
+
// Check a focused element for focus indicator issues
|
|
29
|
+
const focusIssues = formatFocusIssues(state, context);
|
|
30
|
+
// Returns: [] if passing, or [OracleIssue] if failing
|
|
31
|
+
|
|
32
|
+
// Check a traversal result for keyboard traps
|
|
33
|
+
const trapIssues = formatTrapIssue(result, '#modal-container', context);
|
|
34
|
+
// Returns: [] if not trapped, or [OracleIssue] if trapped
|
|
35
|
+
|
|
36
|
+
// Convenience: run all state-based checks at once
|
|
37
|
+
import { formatAllIssues } from '@a11y-oracle/audit-formatter';
|
|
38
|
+
const allIssues = formatAllIssues(state, context);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### OracleAuditor Class
|
|
42
|
+
|
|
43
|
+
Wraps an orchestrator and automatically audits every interaction. Issues accumulate across calls:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { test, expect } from '@a11y-oracle/playwright-plugin';
|
|
47
|
+
import { OracleAuditor } from '@a11y-oracle/audit-formatter';
|
|
48
|
+
|
|
49
|
+
test('all focus indicators pass oracle rules', async ({ page, a11y }) => {
|
|
50
|
+
await page.goto('/my-page.html');
|
|
51
|
+
|
|
52
|
+
const auditor = new OracleAuditor(a11y, {
|
|
53
|
+
project: 'my-app',
|
|
54
|
+
specName: 'navigation.spec.ts',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Each pressKey() automatically runs all state-based checks
|
|
58
|
+
await auditor.pressKey('Tab');
|
|
59
|
+
await auditor.pressKey('Tab');
|
|
60
|
+
await auditor.pressKey('Tab');
|
|
61
|
+
|
|
62
|
+
// Check a container for keyboard traps
|
|
63
|
+
await auditor.checkTrap('#modal-container');
|
|
64
|
+
|
|
65
|
+
// Assert no issues found
|
|
66
|
+
expect(auditor.issueCount).toBe(0);
|
|
67
|
+
expect(auditor.getIssues()).toHaveLength(0);
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The `OracleAuditor` accepts any object matching the `OrchestratorLike` interface, which is satisfied by both `A11yOracle` (Playwright) and `A11yOrchestrator` (core engine).
|
|
72
|
+
|
|
73
|
+
### Selector Utilities
|
|
74
|
+
|
|
75
|
+
Generate CSS selectors and HTML snippets from element data:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import {
|
|
79
|
+
selectorFromFocusedElement,
|
|
80
|
+
htmlSnippetFromFocusedElement,
|
|
81
|
+
} from '@a11y-oracle/audit-formatter';
|
|
82
|
+
|
|
83
|
+
const selector = selectorFromFocusedElement(state.focusedElement);
|
|
84
|
+
// "#submit-btn" or "button.primary.large" or "button"
|
|
85
|
+
|
|
86
|
+
const snippet = htmlSnippetFromFocusedElement(state.focusedElement);
|
|
87
|
+
// '<button id="submit-btn" class="primary">Submit</button>'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Rules
|
|
91
|
+
|
|
92
|
+
A11y-Oracle enforces six WCAG rules:
|
|
93
|
+
|
|
94
|
+
| Rule ID | WCAG Criterion | Since | Level | Tag | Impact | Description |
|
|
95
|
+
|---------|---------------|-------|-------|-----|--------|-------------|
|
|
96
|
+
| `oracle/focus-not-visible` | [2.4.7 Focus Visible](https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html) | 2.0 | AA | `wcag2aa` | `serious` | Focused element has no visible focus indicator |
|
|
97
|
+
| `oracle/focus-low-contrast` | [2.4.12 Focus Appearance](https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance.html) | 2.2 | AA | `wcag22aa` | `moderate` | Focus indicator contrast ratio is below 3:1 |
|
|
98
|
+
| `oracle/keyboard-trap` | [2.1.2 No Keyboard Trap](https://www.w3.org/WAI/WCAG22/Understanding/no-keyboard-trap.html) | 2.0 | A | `wcag2a` | `critical` | Keyboard focus is trapped within a container |
|
|
99
|
+
| `oracle/focus-missing-name` | [4.1.2 Name, Role, Value](https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html) | 2.0 | A | `wcag2a` | `serious` | Focused element has no accessible name |
|
|
100
|
+
| `oracle/focus-generic-role` | [4.1.2 Name, Role, Value](https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html) | 2.0 | A | `wcag2a` | `serious` | Focused element has a generic or presentational role |
|
|
101
|
+
| `oracle/positive-tabindex` | [2.4.3 Focus Order](https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html) | 2.0 | A | `wcag2a` | `serious` | Element uses a positive tabindex value |
|
|
102
|
+
|
|
103
|
+
`focus-not-visible` takes priority over `focus-low-contrast` — if no indicator exists, only the visibility rule fires (not both). `focus-generic-role` and `focus-missing-name` are mutually exclusive — generic roles trigger only the role check.
|
|
104
|
+
|
|
105
|
+
For detailed remediation guidance on each rule, see the [Remediation Guide](../../docs/REMEDIATION.md).
|
|
106
|
+
|
|
107
|
+
## API Reference
|
|
108
|
+
|
|
109
|
+
### Formatter Functions
|
|
110
|
+
|
|
111
|
+
#### `formatFocusIssues(state, context)`
|
|
112
|
+
|
|
113
|
+
Check an `A11yState` for focus indicator issues.
|
|
114
|
+
|
|
115
|
+
- **Parameters:**
|
|
116
|
+
- `state: A11yState` — unified accessibility state from `pressKey()` or `getState()`
|
|
117
|
+
- `context: AuditContext` — `{ project, specName, wcagLevel?, disabledRules? }`
|
|
118
|
+
- **Returns:** `OracleIssue[]` — 0 or 1 issues
|
|
119
|
+
- **Behavior:** Returns `oracle/focus-not-visible` if `isVisible === false`. Returns `oracle/focus-low-contrast` if visible but `meetsWCAG_AA === false`. Returns `[]` if passing or no focused element.
|
|
120
|
+
|
|
121
|
+
#### `formatTrapIssue(result, containerSelector, context)`
|
|
122
|
+
|
|
123
|
+
Check a `TraversalResult` for keyboard traps.
|
|
124
|
+
|
|
125
|
+
- **Parameters:**
|
|
126
|
+
- `result: TraversalResult` — result from `traverseSubTree()`
|
|
127
|
+
- `containerSelector: string` — CSS selector for the container (used in the issue)
|
|
128
|
+
- `context: AuditContext` — `{ project: string, specName: string }`
|
|
129
|
+
- **Returns:** `OracleIssue[]` — 0 or 1 issues
|
|
130
|
+
|
|
131
|
+
#### `formatNameIssues(state, context)`
|
|
132
|
+
|
|
133
|
+
Check an `A11yState` for missing accessible name issues.
|
|
134
|
+
|
|
135
|
+
- **Parameters:** Same as `formatFocusIssues`
|
|
136
|
+
- **Returns:** `OracleIssue[]` — 0 or 1 issues
|
|
137
|
+
- **Behavior:** Returns `oracle/focus-missing-name` if the focused element has no computed name. Skips elements with generic/presentational roles (those fire `formatRoleIssues` instead).
|
|
138
|
+
|
|
139
|
+
#### `formatRoleIssues(state, context)`
|
|
140
|
+
|
|
141
|
+
Check an `A11yState` for generic/presentational role issues.
|
|
142
|
+
|
|
143
|
+
- **Parameters:** Same as `formatFocusIssues`
|
|
144
|
+
- **Returns:** `OracleIssue[]` — 0 or 1 issues
|
|
145
|
+
- **Behavior:** Returns `oracle/focus-generic-role` if the focused element has a `generic`, `none`, or `presentation` role.
|
|
146
|
+
|
|
147
|
+
#### `formatTabIndexIssues(state, context)`
|
|
148
|
+
|
|
149
|
+
Check an `A11yState` for positive tabindex issues.
|
|
150
|
+
|
|
151
|
+
- **Parameters:** Same as `formatFocusIssues`
|
|
152
|
+
- **Returns:** `OracleIssue[]` — 0 or 1 issues
|
|
153
|
+
- **Behavior:** Returns `oracle/positive-tabindex` if the focused element has `tabIndex > 0`.
|
|
154
|
+
|
|
155
|
+
#### `formatAllIssues(state, context)`
|
|
156
|
+
|
|
157
|
+
Convenience wrapper that runs all state-based checks: focus indicator, name, role, and tabindex.
|
|
158
|
+
|
|
159
|
+
- **Parameters:** Same as `formatFocusIssues`
|
|
160
|
+
- **Returns:** `OracleIssue[]`
|
|
161
|
+
- **Behavior:** Applies `wcagLevel` filtering (default `'aa'`) and `disabledRules` suppression from `context`.
|
|
162
|
+
|
|
163
|
+
#### `matchesWcagLevel(rule, level)`
|
|
164
|
+
|
|
165
|
+
Check if a rule applies at a given WCAG conformance level.
|
|
166
|
+
|
|
167
|
+
- **Parameters:**
|
|
168
|
+
- `rule: OracleRule` — rule metadata object
|
|
169
|
+
- `level: WcagLevel` — `'a'` or `'aa'`
|
|
170
|
+
- **Returns:** `boolean` — `true` if the rule applies at the given level
|
|
171
|
+
- **Behavior:** `'aa'` includes all rules. `'a'` includes only rules tagged with `wcag2a`.
|
|
172
|
+
|
|
173
|
+
### OracleAuditor
|
|
174
|
+
|
|
175
|
+
#### `constructor(orchestrator, context)`
|
|
176
|
+
|
|
177
|
+
- `orchestrator: OrchestratorLike` — any object with `pressKey()`, `getState()`, and `traverseSubTree()` methods
|
|
178
|
+
- `context: AuditContext` — `{ project, specName, wcagLevel?, disabledRules? }`
|
|
179
|
+
|
|
180
|
+
#### `pressKey(key, modifiers?): Promise<A11yState>`
|
|
181
|
+
|
|
182
|
+
Dispatch a key press and automatically audit the resulting state for all state-based rules.
|
|
183
|
+
|
|
184
|
+
#### `getState(): Promise<A11yState>`
|
|
185
|
+
|
|
186
|
+
Read the current state and audit it for all state-based rules.
|
|
187
|
+
|
|
188
|
+
#### `checkTrap(selector, maxTabs?): Promise<TraversalResult>`
|
|
189
|
+
|
|
190
|
+
Run keyboard trap detection on a container and audit the result.
|
|
191
|
+
|
|
192
|
+
#### `getIssues(): ReadonlyArray<OracleIssue>`
|
|
193
|
+
|
|
194
|
+
Return a copy of all accumulated issues.
|
|
195
|
+
|
|
196
|
+
#### `clear(): void`
|
|
197
|
+
|
|
198
|
+
Reset the accumulated issues list.
|
|
199
|
+
|
|
200
|
+
#### `issueCount: number`
|
|
201
|
+
|
|
202
|
+
The number of accumulated issues (getter).
|
|
203
|
+
|
|
204
|
+
### OrchestratorLike Interface
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
interface OrchestratorLike {
|
|
208
|
+
pressKey(key: string, modifiers?: Record<string, boolean>): Promise<A11yState>;
|
|
209
|
+
getState(): Promise<A11yState>;
|
|
210
|
+
traverseSubTree(selector: string, maxTabs?: number): Promise<TraversalResult>;
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Satisfied by `A11yOracle` (playwright-plugin) and `A11yOrchestrator` (core-engine).
|
|
215
|
+
|
|
216
|
+
### Rule Utilities
|
|
217
|
+
|
|
218
|
+
#### `RULES: Record<string, OracleRule>`
|
|
219
|
+
|
|
220
|
+
All defined rule objects keyed by rule ID.
|
|
221
|
+
|
|
222
|
+
#### `RULE_IDS: string[]`
|
|
223
|
+
|
|
224
|
+
Array of all rule IDs.
|
|
225
|
+
|
|
226
|
+
#### `getRule(ruleId): OracleRule`
|
|
227
|
+
|
|
228
|
+
Get a rule by ID, or throw if unknown.
|
|
229
|
+
|
|
230
|
+
### Selector Utilities
|
|
231
|
+
|
|
232
|
+
#### `selectorFromFocusedElement(el): string`
|
|
233
|
+
|
|
234
|
+
Generate a CSS selector from an `A11yFocusedElement`. Priority: `#id` > `tag.class1.class2` > `tag`.
|
|
235
|
+
|
|
236
|
+
#### `selectorFromTabOrderEntry(entry): string`
|
|
237
|
+
|
|
238
|
+
Generate a CSS selector from a `TabOrderEntry`. Priority: `#id` > `tag[role="..."]` > `tag`.
|
|
239
|
+
|
|
240
|
+
#### `htmlSnippetFromFocusedElement(el): string`
|
|
241
|
+
|
|
242
|
+
Generate a minimal HTML snippet from an `A11yFocusedElement`.
|
|
243
|
+
|
|
244
|
+
#### `htmlSnippetFromTabOrderEntry(entry): string`
|
|
245
|
+
|
|
246
|
+
Generate a minimal HTML snippet from a `TabOrderEntry`.
|
|
247
|
+
|
|
248
|
+
## Types
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import type {
|
|
252
|
+
OracleIssue, // Main issue object
|
|
253
|
+
OracleNode, // Axe-compatible node result
|
|
254
|
+
OracleCheck, // Individual check within a node
|
|
255
|
+
OracleImpact, // 'minor' | 'moderate' | 'serious' | 'critical'
|
|
256
|
+
OracleResultType, // 'violation' | 'incomplete' | 'oracle'
|
|
257
|
+
OracleRule, // Rule metadata
|
|
258
|
+
AuditContext, // { project, specName, wcagLevel?, disabledRules? }
|
|
259
|
+
WcagLevel, // 'wcag2a' | 'wcag2aa' | 'wcag21a' | 'wcag21aa' | 'wcag22a' | 'wcag22aa'
|
|
260
|
+
} from '@a11y-oracle/audit-formatter';
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Exports
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// Types
|
|
267
|
+
export type { OracleIssue, OracleNode, OracleCheck, OracleImpact, OracleResultType, OracleRule, AuditContext, WcagLevel };
|
|
268
|
+
|
|
269
|
+
// Rule definitions
|
|
270
|
+
export { RULES, RULE_IDS, getRule, matchesWcagLevel };
|
|
271
|
+
|
|
272
|
+
// Pure formatter functions
|
|
273
|
+
export { formatFocusIssues, formatTrapIssue, formatNameIssues, formatRoleIssues, formatTabIndexIssues, formatAllIssues };
|
|
274
|
+
|
|
275
|
+
// Selector utilities
|
|
276
|
+
export { selectorFromFocusedElement, selectorFromTabOrderEntry, htmlSnippetFromFocusedElement, htmlSnippetFromTabOrderEntry };
|
|
277
|
+
|
|
278
|
+
// Convenience class
|
|
279
|
+
export { OracleAuditor };
|
|
280
|
+
export type { OrchestratorLike };
|
|
281
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @a11y-oracle/audit-formatter
|
|
3
|
+
*
|
|
4
|
+
* Converts A11y-Oracle findings into axe-core-compatible issues.
|
|
5
|
+
*
|
|
6
|
+
* Output is structurally compatible with Beacon's AxeIssue interface,
|
|
7
|
+
* differentiated by `resultType: 'oracle'` and `oracle/`-prefixed ruleIds.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
export type { OracleIssue, OracleNode, OracleCheck, OracleImpact, OracleResultType, OracleRule, AuditContext, WcagLevel, } from './lib/types.js';
|
|
12
|
+
export { RULES, RULE_IDS, getRule, matchesWcagLevel } from './lib/rules.js';
|
|
13
|
+
export { formatFocusIssues, formatTrapIssue, formatNameIssues, formatRoleIssues, formatTabIndexIssues, formatAllIssues, } from './lib/formatters.js';
|
|
14
|
+
export { selectorFromFocusedElement, selectorFromTabOrderEntry, htmlSnippetFromFocusedElement, htmlSnippetFromTabOrderEntry, } from './lib/selector.js';
|
|
15
|
+
export { OracleAuditor } from './lib/oracle-auditor.js';
|
|
16
|
+
export type { OrchestratorLike } from './lib/oracle-auditor.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAG5E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @a11y-oracle/audit-formatter
|
|
3
|
+
*
|
|
4
|
+
* Converts A11y-Oracle findings into axe-core-compatible issues.
|
|
5
|
+
*
|
|
6
|
+
* Output is structurally compatible with Beacon's AxeIssue interface,
|
|
7
|
+
* differentiated by `resultType: 'oracle'` and `oracle/`-prefixed ruleIds.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
// Rule definitions
|
|
12
|
+
export { RULES, RULE_IDS, getRule, matchesWcagLevel } from './lib/rules.js';
|
|
13
|
+
// Pure formatter functions
|
|
14
|
+
export { formatFocusIssues, formatTrapIssue, formatNameIssues, formatRoleIssues, formatTabIndexIssues, formatAllIssues, } from './lib/formatters.js';
|
|
15
|
+
// Selector utilities
|
|
16
|
+
export { selectorFromFocusedElement, selectorFromTabOrderEntry, htmlSnippetFromFocusedElement, htmlSnippetFromTabOrderEntry, } from './lib/selector.js';
|
|
17
|
+
// Convenience class
|
|
18
|
+
export { OracleAuditor } from './lib/oracle-auditor.js';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module formatters
|
|
3
|
+
*
|
|
4
|
+
* Pure functions that convert A11y-Oracle data into OracleIssue objects.
|
|
5
|
+
*
|
|
6
|
+
* Each function takes A11y-Oracle findings + an AuditContext and returns
|
|
7
|
+
* an array of OracleIssue objects (empty if no issues found). The functions
|
|
8
|
+
* have no side effects and do not require a CDP session or orchestrator.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { formatFocusIssues } from '@a11y-oracle/audit-formatter';
|
|
13
|
+
*
|
|
14
|
+
* const state = await a11y.pressKey('Tab');
|
|
15
|
+
* const issues = formatFocusIssues(state, { project: 'my-app', specName: 'nav.spec.ts' });
|
|
16
|
+
* expect(issues).toHaveLength(0); // No focus issues
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import type { A11yState } from '@a11y-oracle/core-engine';
|
|
20
|
+
import type { TraversalResult } from '@a11y-oracle/focus-analyzer';
|
|
21
|
+
import type { OracleIssue, AuditContext } from './types.js';
|
|
22
|
+
/**
|
|
23
|
+
* Analyze an A11yState for focus-related issues.
|
|
24
|
+
*
|
|
25
|
+
* Checks two rules (only one fires per state — `focus-not-visible` takes priority):
|
|
26
|
+
* - `oracle/focus-not-visible` — `focusIndicator.isVisible === false`
|
|
27
|
+
* - `oracle/focus-low-contrast` — `isVisible` but `meetsWCAG_AA === false`
|
|
28
|
+
*
|
|
29
|
+
* Returns an empty array if no element is focused or focus indicator passes.
|
|
30
|
+
*
|
|
31
|
+
* @param state - Unified accessibility state from pressKey() or getState()
|
|
32
|
+
* @param context - Audit context (project, specName)
|
|
33
|
+
* @returns Array of 0 or 1 OracleIssue
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatFocusIssues(state: A11yState, context: AuditContext): OracleIssue[];
|
|
36
|
+
/**
|
|
37
|
+
* Analyze a TraversalResult for keyboard trap issues.
|
|
38
|
+
*
|
|
39
|
+
* Checks:
|
|
40
|
+
* - `oracle/keyboard-trap` — `isTrapped === true`
|
|
41
|
+
*
|
|
42
|
+
* @param result - Traversal result from traverseSubTree()
|
|
43
|
+
* @param containerSelector - The CSS selector of the container tested for trapping
|
|
44
|
+
* @param context - Audit context
|
|
45
|
+
* @returns Array of 0 or 1 OracleIssue
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatTrapIssue(result: TraversalResult, containerSelector: string, context: AuditContext): OracleIssue[];
|
|
48
|
+
/**
|
|
49
|
+
* Analyze an A11yState for missing accessible name issues.
|
|
50
|
+
*
|
|
51
|
+
* Checks:
|
|
52
|
+
* - `oracle/focus-missing-name` — focused element has no computed name
|
|
53
|
+
*
|
|
54
|
+
* Only fires when an element is focused AND has a meaningful role
|
|
55
|
+
* (elements with generic/none/presentation roles fire
|
|
56
|
+
* `oracle/focus-generic-role` instead).
|
|
57
|
+
*
|
|
58
|
+
* @param state - Unified accessibility state from pressKey() or getState()
|
|
59
|
+
* @param context - Audit context (project, specName)
|
|
60
|
+
* @returns Array of 0 or 1 OracleIssue
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatNameIssues(state: A11yState, context: AuditContext): OracleIssue[];
|
|
63
|
+
/**
|
|
64
|
+
* Analyze an A11yState for generic/presentational role issues.
|
|
65
|
+
*
|
|
66
|
+
* Checks:
|
|
67
|
+
* - `oracle/focus-generic-role` — focused element has generic, none, or
|
|
68
|
+
* presentation role
|
|
69
|
+
*
|
|
70
|
+
* Only fires when an element is focused AND the AXNode role is one of the
|
|
71
|
+
* semantically empty roles. This indicates an element that receives keyboard
|
|
72
|
+
* focus but provides no role information to assistive technologies.
|
|
73
|
+
*
|
|
74
|
+
* @param state - Unified accessibility state from pressKey() or getState()
|
|
75
|
+
* @param context - Audit context (project, specName)
|
|
76
|
+
* @returns Array of 0 or 1 OracleIssue
|
|
77
|
+
*/
|
|
78
|
+
export declare function formatRoleIssues(state: A11yState, context: AuditContext): OracleIssue[];
|
|
79
|
+
/**
|
|
80
|
+
* Analyze an A11yState for positive tabindex issues.
|
|
81
|
+
*
|
|
82
|
+
* Checks:
|
|
83
|
+
* - `oracle/positive-tabindex` — focused element has `tabIndex > 0`
|
|
84
|
+
*
|
|
85
|
+
* Positive tabindex values create an unpredictable focus order that
|
|
86
|
+
* diverges from the visual reading order.
|
|
87
|
+
*
|
|
88
|
+
* @param state - Unified accessibility state from pressKey() or getState()
|
|
89
|
+
* @param context - Audit context (project, specName)
|
|
90
|
+
* @returns Array of 0 or 1 OracleIssue
|
|
91
|
+
*/
|
|
92
|
+
export declare function formatTabIndexIssues(state: A11yState, context: AuditContext): OracleIssue[];
|
|
93
|
+
/**
|
|
94
|
+
* Convenience: analyze an A11yState for ALL state-based rules.
|
|
95
|
+
*
|
|
96
|
+
* Runs focus indicator checks, name/role checks, and tabindex checks.
|
|
97
|
+
* Trap detection requires a separate TraversalResult — use
|
|
98
|
+
* `formatTrapIssue()` for that.
|
|
99
|
+
*
|
|
100
|
+
* @param state - Unified accessibility state
|
|
101
|
+
* @param context - Audit context
|
|
102
|
+
* @returns Array of OracleIssue objects
|
|
103
|
+
*/
|
|
104
|
+
export declare function formatAllIssues(state: A11yState, context: AuditContext): OracleIssue[];
|
|
105
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,SAAS,EAEV,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EACb,MAAM,YAAY,CAAC;AASpB;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,GACpB,WAAW,EAAE,CAgCf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,YAAY,GACpB,WAAW,EAAE,CAgEf;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,GACpB,WAAW,EAAE,CAiBf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,GACpB,WAAW,EAAE,CAkBf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,GACpB,WAAW,EAAE,CAiBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,GACpB,WAAW,EAAE,CAiBf"}
|