@diegovelasquezweb/a11y-engine 0.6.1 → 0.6.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.
@@ -9,18 +9,24 @@ export default {
9
9
  id: "axe",
10
10
  label: "axe-core",
11
11
  description: "Primary WCAG rule engine for rendered DOM violations.",
12
+ coverage: "Broadest WCAG rule coverage with over 90 checks across all four principles. Catches missing labels, contrast failures, landmark structure, and ARIA misuse.",
13
+ speed: "Fast",
12
14
  defaultEnabled: true,
13
15
  },
14
16
  {
15
17
  id: "cdp",
16
18
  label: "CDP",
17
19
  description: "Chrome accessibility tree checks for name/role/focus gaps.",
20
+ coverage: "Inspects the browser accessibility tree directly via Chrome DevTools Protocol. Catches name and role issues that axe misses at the DOM level.",
21
+ speed: "Medium",
18
22
  defaultEnabled: true,
19
23
  },
20
24
  {
21
25
  id: "pa11y",
22
26
  label: "pa11y",
23
27
  description: "HTML CodeSniffer checks to complement axe coverage.",
28
+ coverage: "Runs HTML CodeSniffer against the rendered page. Complements axe with additional HTML-level checks and alternative rule interpretations.",
29
+ speed: "Medium",
24
30
  defaultEnabled: true,
25
31
  },
26
32
  ],
@@ -36,7 +42,7 @@ export default {
36
42
  id: "crawlDepth",
37
43
  label: "Crawl depth",
38
44
  description: "Controls how many link levels are explored from the start page.",
39
- defaultValue: 2,
45
+ defaultValue: 1,
40
46
  type: "number",
41
47
  },
42
48
  {
@@ -45,29 +51,48 @@ export default {
45
51
  description: "Navigation readiness event before scanning each page.",
46
52
  defaultValue: "domcontentloaded",
47
53
  type: "enum",
48
- allowedValues: ["domcontentloaded", "load", "networkidle"],
54
+ allowedValues: [
55
+ {
56
+ value: "domcontentloaded",
57
+ label: "DOM Ready",
58
+ description: "Fires when the initial HTML is parsed. Fastest — use for server-rendered pages.",
59
+ },
60
+ {
61
+ value: "load",
62
+ label: "Page Load",
63
+ description: "Waits for all resources (images, scripts) to finish loading. Good for pages with critical above-the-fold assets.",
64
+ },
65
+ {
66
+ value: "networkidle",
67
+ label: "Network Idle",
68
+ description: "Waits until no network requests for 500ms. Best for SPAs and pages with deferred content loading.",
69
+ },
70
+ ],
49
71
  },
50
72
  {
51
73
  id: "timeoutMs",
52
74
  label: "Timeout",
53
- description: "Maximum navigation wait time per route in milliseconds.",
75
+ description: "Maximum time to wait for each page to load before aborting.",
54
76
  defaultValue: 30000,
55
77
  type: "number",
56
78
  },
57
79
  {
58
80
  id: "viewport",
59
81
  label: "Viewport",
60
- description: "Browser viewport used during scan emulation.",
82
+ description: "Browser window size used during the audit.",
61
83
  defaultValue: "1280x800",
62
84
  type: "text",
63
85
  },
64
86
  {
65
87
  id: "colorScheme",
66
88
  label: "Color scheme",
67
- description: "Emulated light or dark color-scheme preference.",
89
+ description: "Emulates light or dark mode during the scan.",
68
90
  defaultValue: "light",
69
91
  type: "enum",
70
- allowedValues: ["light", "dark"],
92
+ allowedValues: [
93
+ { value: "light", label: "Light" },
94
+ { value: "dark", label: "Dark" },
95
+ ],
71
96
  },
72
97
  {
73
98
  id: "axeTags",
@@ -78,6 +103,95 @@ export default {
78
103
  },
79
104
  ],
80
105
  },
106
+ conformanceLevels: [
107
+ {
108
+ id: "A",
109
+ label: "Level A",
110
+ badge: "Minimum",
111
+ description: "The baseline: essential requirements that remove the most severe barriers.",
112
+ shortDescription: "Minimum baseline",
113
+ hint: "Failing Level A means some users cannot access the content at all.",
114
+ tags: ["wcag2a", "wcag21a", "wcag22a"],
115
+ },
116
+ {
117
+ id: "AA",
118
+ label: "Level AA",
119
+ badge: "Standard",
120
+ description: "The recommended target for most websites — required by most accessibility laws.",
121
+ shortDescription: "Recommended for most websites",
122
+ hint: "Referenced by ADA, Section 508, EN 301 549, and EAA.",
123
+ tags: ["wcag2a", "wcag21a", "wcag22a", "wcag2aa", "wcag21aa", "wcag22aa"],
124
+ },
125
+ {
126
+ id: "AAA",
127
+ label: "Level AAA",
128
+ badge: "Enhanced",
129
+ description: "The highest conformance level — not required but beneficial for specialized audiences.",
130
+ shortDescription: "Strictest — not required by most regulations",
131
+ hint: "Full AAA conformance is not recommended as a general policy for entire sites.",
132
+ tags: ["wcag2a", "wcag21a", "wcag22a", "wcag2aa", "wcag21aa", "wcag22aa", "wcag2aaa"],
133
+ },
134
+ ],
135
+ wcagPrinciples: [
136
+ {
137
+ id: "perceivable",
138
+ name: "Perceivable",
139
+ description: "Information and UI components must be presentable to users in ways they can perceive.",
140
+ criterionPrefix: " 1.",
141
+ number: 1,
142
+ },
143
+ {
144
+ id: "operable",
145
+ name: "Operable",
146
+ description: "UI components and navigation must be operable.",
147
+ criterionPrefix: " 2.",
148
+ number: 2,
149
+ },
150
+ {
151
+ id: "understandable",
152
+ name: "Understandable",
153
+ description: "Information and the operation of the UI must be understandable.",
154
+ criterionPrefix: " 3.",
155
+ number: 3,
156
+ },
157
+ {
158
+ id: "robust",
159
+ name: "Robust",
160
+ description: "Content must be robust enough to be interpreted by a wide variety of user agents.",
161
+ criterionPrefix: " 4.",
162
+ number: 4,
163
+ },
164
+ ],
165
+ severityLevels: [
166
+ {
167
+ id: "Critical",
168
+ label: "Critical",
169
+ shortDescription: "Functional blockers",
170
+ description: "Blocks key user tasks with no practical workaround.",
171
+ order: 1,
172
+ },
173
+ {
174
+ id: "Serious",
175
+ label: "Serious",
176
+ shortDescription: "Serious impediments",
177
+ description: "Major barrier with difficult workaround or significant friction.",
178
+ order: 2,
179
+ },
180
+ {
181
+ id: "Moderate",
182
+ label: "Moderate",
183
+ shortDescription: "Significant friction",
184
+ description: "Usability degradation that still allows task completion.",
185
+ order: 3,
186
+ },
187
+ {
188
+ id: "Minor",
189
+ label: "Minor",
190
+ shortDescription: "Minor violations",
191
+ description: "Lower-impact issue that still reduces quality and consistency.",
192
+ order: 4,
193
+ },
194
+ ],
81
195
  personas: {
82
196
  screenReader: {
83
197
  label: "Screen Reader Users",
@@ -96,16 +210,17 @@ export default {
96
210
  description: "People who benefit from predictable behavior and clear instructions.",
97
211
  },
98
212
  },
99
- tooltips: {
100
- scoreGauge: {
213
+ concepts: {
214
+ score: {
101
215
  title: "Compliance Score",
102
216
  body: "Weighted score from severity totals. It is a prioritization signal, not legal certification.",
217
+ context: "Based on automated accessibility technical checks.",
103
218
  },
104
219
  wcagStatus: {
105
220
  title: "WCAG Status",
106
221
  body: "Pass = no issues. Conditional Pass = only Moderate/Minor. Fail = any Critical/Serious remaining.",
107
222
  },
108
- severityCards: {
223
+ severityBreakdown: {
109
224
  title: "Severity Breakdown",
110
225
  body: "Issue counts grouped by user impact and task completion risk.",
111
226
  },
@@ -116,6 +231,7 @@ export default {
116
231
  quickWins: {
117
232
  title: "Quick Wins",
118
233
  body: "Top Critical/Serious findings that already include concrete fix code.",
234
+ context: "High-priority issues with ready-to-use code fixes for immediate remediation.",
119
235
  },
120
236
  findingsFilter: {
121
237
  title: "Findings Filter",
@@ -135,24 +251,21 @@ export default {
135
251
  {
136
252
  id: "wcag-2-0",
137
253
  title: "WCAG 2.0",
138
- tag: "2008",
139
- tagVariant: "neutral",
254
+ badge: "2008",
140
255
  summary: "The original W3C recommendation that established the foundation for web accessibility.",
141
256
  body: "Introduced the four principles (Perceivable, Operable, Understandable, Robust) and three conformance levels (A, AA, AAA). Covers core requirements like text alternatives, keyboard access, color contrast, and form labels. Still widely referenced in legal frameworks worldwide.",
142
257
  },
143
258
  {
144
259
  id: "wcag-2-1",
145
260
  title: "WCAG 2.1",
146
- tag: "2018",
147
- tagVariant: "info",
261
+ badge: "2018",
148
262
  summary: "Extended 2.0 with 17 new success criteria for mobile, low vision, and cognitive disabilities.",
149
263
  body: "Added criteria for touch targets (2.5.5), text spacing (1.4.12), content reflow (1.4.10), orientation (1.3.4), and input purpose (1.3.5). Required by the European Accessibility Act (EAA) and referenced in updated ADA guidance. All 2.0 criteria remain \u2014 2.1 is a superset.",
150
264
  },
151
265
  {
152
266
  id: "wcag-2-2",
153
267
  title: "WCAG 2.2",
154
- tag: "2023",
155
- tagVariant: "violet",
268
+ badge: "2023",
156
269
  summary: "The latest version, adding 9 new criteria focused on cognitive accessibility and consistent help.",
157
270
  body: "Key additions include consistent help (3.2.6), accessible authentication (3.3.8), dragging movements (2.5.7), and focus appearance (2.4.11/2.4.12). Removed criterion 4.1.1 (Parsing) as it\u2019s now handled by modern browsers. Supersedes both 2.0 and 2.1 \u2014 all prior criteria are included.",
158
271
  },
@@ -165,24 +278,21 @@ export default {
165
278
  {
166
279
  id: "level-a",
167
280
  title: "Level A",
168
- tag: "Minimum",
169
- tagVariant: "warning",
281
+ badge: "Minimum",
170
282
  summary: "The baseline: essential requirements that remove the most severe barriers.",
171
283
  body: "Covers fundamentals like non-text content alternatives (1.1.1), keyboard operability (2.1.1), page titles (2.4.2), and language of the page (3.1.1). Failing Level A means some users cannot access the content at all. Every site should meet Level A at minimum.",
172
284
  },
173
285
  {
174
286
  id: "level-aa",
175
287
  title: "Level AA",
176
- tag: "Standard",
177
- tagVariant: "success",
288
+ badge: "Standard",
178
289
  summary: "The recommended target for most websites \u2014 required by most accessibility laws.",
179
290
  body: "Includes all Level A criteria plus requirements for color contrast (1.4.3 \u2014 4.5:1 ratio), resize text (1.4.4), focus visible (2.4.7), error suggestion (3.3.3), and consistent navigation (3.2.3). Referenced by ADA, Section 508, EN 301 549, and EAA. This is the standard the scanner defaults to.",
180
291
  },
181
292
  {
182
293
  id: "level-aaa",
183
294
  title: "Level AAA",
184
- tag: "Enhanced",
185
- tagVariant: "purple",
295
+ badge: "Enhanced",
186
296
  summary: "The highest conformance level \u2014 not required but beneficial for specialized audiences.",
187
297
  body: "Adds stricter contrast (1.4.6 \u2014 7:1 ratio), sign language for audio (1.2.6), extended audio description (1.2.7), and reading level (3.1.5). Full AAA conformance is not recommended as a general policy because some criteria cannot be satisfied for all content types. Useful for targeted sections like education or government services.",
188
298
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegovelasquezweb/a11y-engine",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "WCAG 2.2 AA accessibility audit engine — scanner, analyzer, and report builders",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/index.d.mts CHANGED
@@ -217,82 +217,74 @@ export interface ScannerEngineHelp {
217
217
  id: "axe" | "cdp" | "pa11y" | string;
218
218
  label: string;
219
219
  description: string;
220
+ coverage: string;
221
+ speed: "Fast" | "Medium" | "Slow" | string;
220
222
  defaultEnabled: boolean;
221
223
  }
222
224
 
225
+ export interface EnumOptionValue {
226
+ value: string;
227
+ label: string;
228
+ description?: string;
229
+ }
230
+
223
231
  export interface ScannerOptionHelp {
224
232
  id: string;
225
233
  label: string;
226
234
  description: string;
227
235
  defaultValue: unknown;
228
236
  type: string;
229
- allowedValues?: unknown[];
237
+ allowedValues?: unknown[] | EnumOptionValue[];
230
238
  }
231
239
 
232
- export interface ScannerHelp {
233
- locale: string;
234
- version: string;
235
- title: string;
236
- engines: ScannerEngineHelp[];
237
- options: ScannerOptionHelp[];
240
+ export interface ConformanceLevel {
241
+ id: "A" | "AA" | "AAA";
242
+ label: string;
243
+ badge: string;
244
+ description: string;
245
+ shortDescription: string;
246
+ hint: string;
247
+ tags: string[];
238
248
  }
239
249
 
240
- export interface PersonaReferenceItem {
250
+ export interface WcagPrinciple {
241
251
  id: string;
242
- icon: string;
252
+ name: string;
253
+ description: string;
254
+ criterionPrefix: string;
255
+ number: number;
256
+ }
257
+
258
+ export interface SeverityLevel {
259
+ id: "Critical" | "Serious" | "Moderate" | "Minor";
243
260
  label: string;
261
+ shortDescription: string;
244
262
  description: string;
245
- keywords: string[];
246
- mappedRules: string[];
263
+ order: number;
247
264
  }
248
265
 
249
- export interface PersonaReference {
266
+ export interface ConformanceLevelsResult {
250
267
  locale: string;
251
268
  version: string;
252
- personas: PersonaReferenceItem[];
253
- }
254
-
255
- export interface UiTooltip {
256
- title: string;
257
- body: string;
258
- }
259
-
260
- export interface GlossaryEntry {
261
- term: string;
262
- definition: string;
263
- }
264
-
265
- export interface DocArticle {
266
- id: string;
267
- title: string;
268
- icon?: string;
269
- tag?: string;
270
- tagVariant?: string;
271
- summary: string;
272
- body: string;
273
- }
274
-
275
- export interface DocGroup {
276
- id: string;
277
- label: string;
278
- articles: DocArticle[];
269
+ conformanceLevels: ConformanceLevel[];
279
270
  }
280
271
 
281
- export interface DocSection {
282
- id: string;
283
- heading: string;
284
- articles?: DocArticle[];
285
- groups?: DocGroup[];
272
+ export interface WcagPrinciplesResult {
273
+ locale: string;
274
+ version: string;
275
+ wcagPrinciples: WcagPrinciple[];
286
276
  }
287
277
 
288
- export interface KnowledgeDocs {
289
- sections: DocSection[];
278
+ export interface SeverityLevelsResult {
279
+ locale: string;
280
+ version: string;
281
+ severityLevels: SeverityLevel[];
290
282
  }
291
283
 
292
284
  export interface UiHelp {
293
285
  locale: string;
294
286
  version: string;
295
- tooltips: Record<string, UiTooltip>;
287
+ concepts: Record<string, ConceptEntry>;
296
288
  glossary: GlossaryEntry[];
297
289
  }
298
290
 
@@ -305,9 +297,12 @@ export interface EngineKnowledge {
305
297
  options: ScannerOptionHelp[];
306
298
  };
307
299
  personas: PersonaReferenceItem[];
308
- tooltips: Record<string, UiTooltip>;
300
+ concepts: Record<string, ConceptEntry>;
309
301
  glossary: GlossaryEntry[];
310
302
  docs: KnowledgeDocs;
303
+ conformanceLevels: ConformanceLevel[];
304
+ wcagPrinciples: WcagPrinciple[];
305
+ severityLevels: SeverityLevel[];
311
306
  }
312
307
 
313
308
  export interface KnowledgeOptions {
@@ -405,4 +400,10 @@ export function getPersonaReference(options?: KnowledgeOptions): PersonaReferenc
405
400
 
406
401
  export function getUiHelp(options?: KnowledgeOptions): UiHelp;
407
402
 
403
+ export function getConformanceLevels(options?: KnowledgeOptions): ConformanceLevelsResult;
404
+
405
+ export function getWcagPrinciples(options?: KnowledgeOptions): WcagPrinciplesResult;
406
+
407
+ export function getSeverityLevels(options?: KnowledgeOptions): SeverityLevelsResult;
408
+
408
409
  export function getKnowledge(options?: KnowledgeOptions): EngineKnowledge;
package/src/index.mjs CHANGED
@@ -515,7 +515,7 @@ export function getUiHelp(options = {}) {
515
515
  return {
516
516
  locale,
517
517
  version: payload.version || "1.0.0",
518
- tooltips: clone(localePayload.tooltips || {}),
518
+ concepts: clone(localePayload.concepts || {}),
519
519
  glossary: clone(localePayload.glossary || []),
520
520
  };
521
521
  }
@@ -527,11 +527,64 @@ export function getUiHelp(options = {}) {
527
527
  * @param {{ locale?: string }} [options={}]
528
528
  * @returns {{ locale: string, version: string, scanner: object, personas: object[], tooltips: Record<string, object>, glossary: object[] }}
529
529
  */
530
+ /**
531
+ * Returns conformance level definitions with WCAG axe-core tag mappings.
532
+ *
533
+ * @param {{ locale?: string }} [options={}]
534
+ * @returns {{ locale: string, version: string, conformanceLevels: object[] }}
535
+ */
536
+ export function getConformanceLevels(options = {}) {
537
+ const locale = resolveKnowledgeLocale(options.locale || "en");
538
+ const payload = getKnowledgeData();
539
+ const levels = payload.locales[locale]?.conformanceLevels || [];
540
+ return {
541
+ locale,
542
+ version: payload.version || "1.0.0",
543
+ conformanceLevels: clone(levels),
544
+ };
545
+ }
546
+
547
+ /**
548
+ * Returns the four WCAG principles with their criterion prefix patterns.
549
+ *
550
+ * @param {{ locale?: string }} [options={}]
551
+ * @returns {{ locale: string, version: string, wcagPrinciples: object[] }}
552
+ */
553
+ export function getWcagPrinciples(options = {}) {
554
+ const locale = resolveKnowledgeLocale(options.locale || "en");
555
+ const payload = getKnowledgeData();
556
+ const principles = payload.locales[locale]?.wcagPrinciples || [];
557
+ return {
558
+ locale,
559
+ version: payload.version || "1.0.0",
560
+ wcagPrinciples: clone(principles),
561
+ };
562
+ }
563
+
564
+ /**
565
+ * Returns severity level definitions with labels, descriptions, and ordering.
566
+ *
567
+ * @param {{ locale?: string }} [options={}]
568
+ * @returns {{ locale: string, version: string, severityLevels: object[] }}
569
+ */
570
+ export function getSeverityLevels(options = {}) {
571
+ const locale = resolveKnowledgeLocale(options.locale || "en");
572
+ const payload = getKnowledgeData();
573
+ const levels = payload.locales[locale]?.severityLevels || [];
574
+ return {
575
+ locale,
576
+ version: payload.version || "1.0.0",
577
+ severityLevels: clone(levels),
578
+ };
579
+ }
580
+
530
581
  export function getKnowledge(options = {}) {
531
582
  const scanner = getScannerHelp(options);
532
583
  const personas = getPersonaReference(options);
533
584
  const ui = getUiHelp(options);
534
-
585
+ const conformance = getConformanceLevels(options);
586
+ const principles = getWcagPrinciples(options);
587
+ const severity = getSeverityLevels(options);
535
588
  const payload = getKnowledgeData();
536
589
  const docs = clone(payload.locales[scanner.locale]?.docs ?? { sections: [] });
537
590
 
@@ -544,9 +597,12 @@ export function getKnowledge(options = {}) {
544
597
  options: scanner.options,
545
598
  },
546
599
  personas: personas.personas,
547
- tooltips: ui.tooltips,
600
+ concepts: ui.concepts,
548
601
  glossary: ui.glossary,
549
602
  docs,
603
+ conformanceLevels: conformance.conformanceLevels,
604
+ wcagPrinciples: principles.wcagPrinciples,
605
+ severityLevels: severity.severityLevels,
550
606
  };
551
607
  }
552
608