test-a11y-js 0.7.1 → 0.8.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 CHANGED
@@ -1,6 +1,18 @@
1
1
  # test-a11y-js
2
2
 
3
- A JavaScript library for testing component accessibility across multiple testing frameworks. Includes both a programmatic API and an ESLint plugin for real-time accessibility linting.
3
+ > **Catch accessibility issues in your editor, not in production.** Zero-config ESLint plugin + programmatic API for React, Vue, and JSX.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/test-a11y-js.svg)](https://www.npmjs.com/package/test-a11y-js)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
+
9
+ **Why test-a11y-js?**
10
+ - ✅ **Zero config** - Works out of the box with React, Vue, and JSX
11
+ - ✅ **Real-time feedback** - Catch issues in your editor, not in production
12
+ - ✅ **16 accessibility rules** - Covers images, forms, buttons, landmarks, ARIA, semantic HTML, and more
13
+ - ✅ **Dual API** - Use as ESLint plugin OR programmatic API
14
+ - ✅ **Large project ready** - Minimal preset for incremental adoption
15
+ - ✅ **Framework agnostic** - Works with React, Vue, Preact, Solid, and more
4
16
 
5
17
  ## Installation
6
18
 
@@ -16,37 +28,62 @@ npm install --save-dev test-a11y-js
16
28
 
17
29
  **Note:** jsdom is only required if you use HTML strings in your code. JSX and Vue templates work without jsdom. See [jsdom Guide](./docs/JSDOM.md) for details.
18
30
 
19
- ## Usage
20
-
21
- ### Programmatic API
31
+ ## Quick Start (30 seconds)
22
32
 
23
- Use the `A11yChecker` class to test DOM elements programmatically:
33
+ **Option 1: ESLint Plugin (Recommended)**
34
+ ```javascript
35
+ // .eslintrc.js
36
+ module.exports = {
37
+ plugins: ['test-a11y-js'],
38
+ extends: ['plugin:test-a11y-js/recommended']
39
+ }
40
+ ```
24
41
 
42
+ **Option 2: Programmatic API**
25
43
  ```typescript
26
44
  import { A11yChecker } from 'test-a11y-js'
27
45
 
28
- // Test a DOM element for accessibility violations
29
- const results = await A11yChecker.check(element)
30
-
31
- // Individual checks
32
- const imageViolations = A11yChecker.checkImageAlt(element)
33
- const linkViolations = A11yChecker.checkLinkText(element)
34
- const buttonViolations = A11yChecker.checkButtonLabel(element)
35
- const formViolations = A11yChecker.checkFormLabels(element)
36
- const headingViolations = A11yChecker.checkHeadingOrder(element)
37
- const iframeViolations = A11yChecker.checkIframeTitle(element)
38
- const fieldsetViolations = A11yChecker.checkFieldsetLegend(element)
39
- const tableViolations = A11yChecker.checkTableStructure(element)
40
- const detailsViolations = A11yChecker.checkDetailsSummary(element)
41
- const videoViolations = A11yChecker.checkVideoCaptions(element)
42
- const audioViolations = A11yChecker.checkAudioCaptions(element)
43
- const landmarkViolations = A11yChecker.checkLandmarks(element)
44
- const dialogViolations = A11yChecker.checkDialogModal(element)
46
+ const violations = A11yChecker.checkImageAlt(element)
45
47
  ```
46
48
 
47
- ### ESLint Plugin
49
+ That's it! Start catching accessibility issues immediately.
50
+
51
+ ## ESLint Plugin vs Programmatic API
52
+
53
+ **When to use the ESLint Plugin:**
54
+ - ✅ **Real-time feedback** - Catch issues as you type in your editor
55
+ - ✅ **CI/CD integration** - Prevent commits with accessibility violations
56
+ - ✅ **Team-wide enforcement** - Ensure all developers follow accessibility standards
57
+ - ✅ **Zero test code** - No need to write test cases, just configure ESLint
58
+ - ✅ **Best for:** Development workflow, code reviews, preventing regressions
59
+
60
+ **When to use the Programmatic API:**
61
+ - ✅ **Custom test scenarios** - Write specific accessibility tests in your test suite
62
+ - ✅ **Dynamic content** - Test accessibility of dynamically generated DOM
63
+ - ✅ **Integration testing** - Test accessibility in E2E or integration tests
64
+ - ✅ **Custom reporting** - Build custom violation reporting or analytics
65
+ - ✅ **Best for:** Unit tests, integration tests, custom testing workflows
66
+
67
+ **You can use both!** Many teams use ESLint plugin for development and programmatic API for comprehensive test coverage.
68
+
69
+ ## What Problems Does This Solve?
70
+
71
+ ❌ **Before:** Accessibility issues discovered in production or by users
72
+ ✅ **After:** Issues caught in your editor before commit
73
+
74
+ ❌ **Before:** Manual accessibility audits take hours
75
+ ✅ **After:** Automated checks run in milliseconds
76
+
77
+ ❌ **Before:** Complex setup with multiple tools
78
+ ✅ **After:** One package, zero config, works everywhere
79
+
80
+ ## Usage
48
81
 
49
- Use the ESLint plugin for real-time accessibility linting in your editor and CI/CD:
82
+ > **Not sure which to use?** See [ESLint Plugin vs Programmatic API](#eslint-plugin-vs-programmatic-api) above for guidance.
83
+
84
+ ### ESLint Plugin (Recommended for Most Cases)
85
+
86
+ The ESLint plugin provides real-time accessibility linting in your editor and CI/CD. It's the easiest way to catch issues during development.
50
87
 
51
88
  #### Basic Setup
52
89
 
@@ -105,6 +142,32 @@ module.exports = {
105
142
 
106
143
  See [Configuration Guide](./docs/CONFIGURATION.md) for more details and [Large Project Setup Guide](./docs/LARGE_PROJECTS.md) for incremental adoption strategies.
107
144
 
145
+ ### Programmatic API
146
+
147
+ Use the `A11yChecker` class to test DOM elements programmatically in your test suites:
148
+
149
+ ```typescript
150
+ import { A11yChecker } from 'test-a11y-js'
151
+
152
+ // Test a DOM element for accessibility violations
153
+ const results = await A11yChecker.check(element)
154
+
155
+ // Individual checks
156
+ const imageViolations = A11yChecker.checkImageAlt(element)
157
+ const linkViolations = A11yChecker.checkLinkText(element)
158
+ const buttonViolations = A11yChecker.checkButtonLabel(element)
159
+ const formViolations = A11yChecker.checkFormLabels(element)
160
+ const headingViolations = A11yChecker.checkHeadingOrder(element)
161
+ const iframeViolations = A11yChecker.checkIframeTitle(element)
162
+ const fieldsetViolations = A11yChecker.checkFieldsetLegend(element)
163
+ const tableViolations = A11yChecker.checkTableStructure(element)
164
+ const detailsViolations = A11yChecker.checkDetailsSummary(element)
165
+ const videoViolations = A11yChecker.checkVideoCaptions(element)
166
+ const audioViolations = A11yChecker.checkAudioCaptions(element)
167
+ const landmarkViolations = A11yChecker.checkLandmarks(element)
168
+ const dialogViolations = A11yChecker.checkDialogModal(element)
169
+ ```
170
+
108
171
  ## API
109
172
 
110
173
  ### A11yChecker
@@ -151,6 +214,27 @@ Validates proper use of landmark elements.
151
214
  #### `checkDialogModal(element: Element): A11yViolation[]`
152
215
  Validates dialog elements have proper accessibility attributes.
153
216
 
217
+ #### `checkAriaRoles(element: Element): A11yViolation[]`
218
+ Validates ARIA roles for validity, appropriateness, and context.
219
+
220
+ #### `checkAriaProperties(element: Element): A11yViolation[]`
221
+ Validates ARIA properties for validity, appropriateness, and values.
222
+
223
+ #### `checkAriaRelationships(element: Element): A11yViolation[]`
224
+ Validates ARIA ID references with enhanced checks.
225
+
226
+ #### `checkAccessibleName(element: Element): A11yViolation[]`
227
+ Validates accessible name computation.
228
+
229
+ #### `checkCompositePatterns(element: Element): A11yViolation[]`
230
+ Validates composite ARIA patterns (tab/listbox/menu/tree).
231
+
232
+ #### `checkSemanticHTML(element: Element): A11yViolation[]`
233
+ Validates semantic HTML usage and structure.
234
+
235
+ #### `checkFormValidationMessages(element: Element): A11yViolation[]`
236
+ Validates form validation messages and error handling.
237
+
154
238
  ### Types
155
239
 
156
240
  ```typescript
@@ -182,6 +266,9 @@ interface A11yResults {
182
266
  - **Audio captions validation** - Validates audio elements have tracks or transcripts
183
267
  - **Landmark roles validation** - Checks proper use of semantic landmarks
184
268
  - **Dialog/Modal validation** - Validates dialog accessibility patterns
269
+ - **Comprehensive ARIA validation** - Validates ARIA roles, properties, relationships, accessible names, and composite patterns
270
+ - **Semantic HTML validation** - Validates proper use of semantic HTML and detects misuse
271
+ - **Form validation messages** - Validates form validation and error handling
185
272
 
186
273
  ### ESLint Plugin
187
274
  - Real-time accessibility linting in your editor
@@ -194,7 +281,7 @@ interface A11yResults {
194
281
 
195
282
  ## ESLint Rules
196
283
 
197
- The plugin provides 13 accessibility rules:
284
+ The plugin provides 16 accessibility rules:
198
285
 
199
286
  - `test-a11y-js/image-alt` - Enforce images have alt attributes
200
287
  - `test-a11y-js/button-label` - Enforce buttons have labels
@@ -209,6 +296,9 @@ The plugin provides 13 accessibility rules:
209
296
  - `test-a11y-js/audio-captions` - Enforce audio elements have tracks or transcripts
210
297
  - `test-a11y-js/landmark-roles` - Enforce proper use of landmark elements (nav, main, header, footer, aside, section, article)
211
298
  - `test-a11y-js/dialog-modal` - Enforce dialog elements have proper accessibility attributes
299
+ - `test-a11y-js/aria-validation` - Enforce valid ARIA roles, properties, relationships, and accessible names
300
+ - `test-a11y-js/semantic-html` - Enforce proper use of semantic HTML elements
301
+ - `test-a11y-js/form-validation` - Enforce proper form validation messages and error handling
212
302
 
213
303
  See [`src/checks.json`](./src/checks.json) for a complete list of supported elements, ARIA attributes, and rules (including what's not yet supported).
214
304
 
@@ -272,6 +362,17 @@ function MyComponent() {
272
362
  </template>
273
363
  ```
274
364
 
365
+ ## How It Compares
366
+
367
+ | Feature | test-a11y-js | eslint-plugin-jsx-a11y | @axe-core/react |
368
+ |---------|--------------|------------------------|-----------------|
369
+ | Zero config | ✅ | ❌ | ❌ |
370
+ | Vue support | ✅ | ❌ | ❌ |
371
+ | Programmatic API | ✅ | ❌ | ✅ |
372
+ | Editor integration | ✅ | ✅ | ❌ |
373
+ | Large project ready | ✅ | ⚠️ | ⚠️ |
374
+ | Framework agnostic | ✅ | React only | React only |
375
+
275
376
  ## Framework Support
276
377
 
277
378
  - ✅ **React/JSX** - Full support via JSX AST
@@ -289,6 +390,18 @@ npx eslint . --cache
289
390
 
290
391
  See [Performance Guide](./docs/PERFORMANCE.md) for optimization tips and [Large Project Setup Guide](./docs/LARGE_PROJECTS.md) for incremental adoption strategies.
291
392
 
393
+ ## Real Impact
394
+
395
+ **Before using test-a11y-js:**
396
+ - Accessibility violations discovered in production audits
397
+ - Weeks spent fixing issues after deployment
398
+ - High costs for accessibility audits
399
+
400
+ **After using test-a11y-js:**
401
+ - Issues caught during development in your editor
402
+ - Zero violations reach production
403
+ - Automated checks save time and money
404
+
292
405
  ## Publishing
293
406
 
294
407
  This package uses GitHub Actions for automated publishing to npm. Publishing details are documented in [`.github/workflows/README.md`](.github/workflows/README.md) for maintainers.
package/dist/index.d.mts CHANGED
@@ -25,6 +25,43 @@ declare class A11yChecker {
25
25
  static checkLandmarks(element: Element): A11yViolation[];
26
26
  static checkDialogModal(element: Element): A11yViolation[];
27
27
  static check(element: Element): Promise<A11yResults>;
28
+ /**
29
+ * Check ARIA roles for validity, appropriateness, and context
30
+ */
31
+ static checkAriaRoles(element: Element): A11yViolation[];
32
+ private static hasStrongNativeSemantics;
33
+ /**
34
+ * Check ARIA properties for validity, appropriateness, and values
35
+ */
36
+ static checkAriaProperties(element: Element): A11yViolation[];
37
+ /**
38
+ * Validate ARIA property value based on type
39
+ */
40
+ private static validateAriaPropertyValue;
41
+ /**
42
+ * Check ARIA relationships (ID references) with enhanced validation
43
+ */
44
+ static checkAriaRelationships(element: Element): A11yViolation[];
45
+ /**
46
+ * Check if element is focusable
47
+ */
48
+ private static isFocusable;
49
+ /**
50
+ * Check accessible name computation
51
+ */
52
+ static checkAccessibleName(element: Element): A11yViolation[];
53
+ /**
54
+ * Check composite patterns (tab/listbox/menu/tree)
55
+ */
56
+ static checkCompositePatterns(element: Element): A11yViolation[];
57
+ /**
58
+ * Check semantic HTML usage and structure
59
+ */
60
+ static checkSemanticHTML(element: Element): A11yViolation[];
61
+ /**
62
+ * Check form validation messages
63
+ */
64
+ static checkFormValidationMessages(element: Element): A11yViolation[];
28
65
  }
29
66
 
30
67
  export { A11yChecker, A11yResults, A11yViolation };
package/dist/index.d.ts CHANGED
@@ -25,6 +25,43 @@ declare class A11yChecker {
25
25
  static checkLandmarks(element: Element): A11yViolation[];
26
26
  static checkDialogModal(element: Element): A11yViolation[];
27
27
  static check(element: Element): Promise<A11yResults>;
28
+ /**
29
+ * Check ARIA roles for validity, appropriateness, and context
30
+ */
31
+ static checkAriaRoles(element: Element): A11yViolation[];
32
+ private static hasStrongNativeSemantics;
33
+ /**
34
+ * Check ARIA properties for validity, appropriateness, and values
35
+ */
36
+ static checkAriaProperties(element: Element): A11yViolation[];
37
+ /**
38
+ * Validate ARIA property value based on type
39
+ */
40
+ private static validateAriaPropertyValue;
41
+ /**
42
+ * Check ARIA relationships (ID references) with enhanced validation
43
+ */
44
+ static checkAriaRelationships(element: Element): A11yViolation[];
45
+ /**
46
+ * Check if element is focusable
47
+ */
48
+ private static isFocusable;
49
+ /**
50
+ * Check accessible name computation
51
+ */
52
+ static checkAccessibleName(element: Element): A11yViolation[];
53
+ /**
54
+ * Check composite patterns (tab/listbox/menu/tree)
55
+ */
56
+ static checkCompositePatterns(element: Element): A11yViolation[];
57
+ /**
58
+ * Check semantic HTML usage and structure
59
+ */
60
+ static checkSemanticHTML(element: Element): A11yViolation[];
61
+ /**
62
+ * Check form validation messages
63
+ */
64
+ static checkFormValidationMessages(element: Element): A11yViolation[];
28
65
  }
29
66
 
30
67
  export { A11yChecker, A11yResults, A11yViolation };