@dallask/a11y-mcp-srv 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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +9 -0
  3. package/README.md +1328 -0
  4. package/bin/server.js +8 -0
  5. package/dist/core/accessibility-runner.d.ts +123 -0
  6. package/dist/core/accessibility-runner.d.ts.map +1 -0
  7. package/dist/core/accessibility-runner.js +465 -0
  8. package/dist/core/accessibility-runner.js.map +1 -0
  9. package/dist/core/basic-auth.d.ts +35 -0
  10. package/dist/core/basic-auth.d.ts.map +1 -0
  11. package/dist/core/basic-auth.js +52 -0
  12. package/dist/core/basic-auth.js.map +1 -0
  13. package/dist/core/config.d.ts +44 -0
  14. package/dist/core/config.d.ts.map +1 -0
  15. package/dist/core/config.js +163 -0
  16. package/dist/core/config.js.map +1 -0
  17. package/dist/core/error-handler.d.ts +66 -0
  18. package/dist/core/error-handler.d.ts.map +1 -0
  19. package/dist/core/error-handler.js +305 -0
  20. package/dist/core/error-handler.js.map +1 -0
  21. package/dist/core/normalize-audit-result.d.ts +18 -0
  22. package/dist/core/normalize-audit-result.d.ts.map +1 -0
  23. package/dist/core/normalize-audit-result.js +118 -0
  24. package/dist/core/normalize-audit-result.js.map +1 -0
  25. package/dist/core/playwright-bootstrap.d.ts +21 -0
  26. package/dist/core/playwright-bootstrap.d.ts.map +1 -0
  27. package/dist/core/playwright-bootstrap.js +144 -0
  28. package/dist/core/playwright-bootstrap.js.map +1 -0
  29. package/dist/core/progress-streamer.d.ts +44 -0
  30. package/dist/core/progress-streamer.d.ts.map +1 -0
  31. package/dist/core/progress-streamer.js +160 -0
  32. package/dist/core/progress-streamer.js.map +1 -0
  33. package/dist/core/result-processor.d.ts +86 -0
  34. package/dist/core/result-processor.d.ts.map +1 -0
  35. package/dist/core/result-processor.js +475 -0
  36. package/dist/core/result-processor.js.map +1 -0
  37. package/dist/core/session-manager.d.ts +73 -0
  38. package/dist/core/session-manager.d.ts.map +1 -0
  39. package/dist/core/session-manager.js +243 -0
  40. package/dist/core/session-manager.js.map +1 -0
  41. package/dist/server.d.ts +10 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +1439 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/tools/aggregate.d.ts +26 -0
  46. package/dist/tools/aggregate.d.ts.map +1 -0
  47. package/dist/tools/aggregate.js +340 -0
  48. package/dist/tools/aggregate.js.map +1 -0
  49. package/dist/tools/analysis.d.ts +68 -0
  50. package/dist/tools/analysis.d.ts.map +1 -0
  51. package/dist/tools/analysis.js +1199 -0
  52. package/dist/tools/analysis.js.map +1 -0
  53. package/dist/tools/audit.d.ts +38 -0
  54. package/dist/tools/audit.d.ts.map +1 -0
  55. package/dist/tools/audit.js +472 -0
  56. package/dist/tools/audit.js.map +1 -0
  57. package/dist/tools/comparison.d.ts +27 -0
  58. package/dist/tools/comparison.d.ts.map +1 -0
  59. package/dist/tools/comparison.js +499 -0
  60. package/dist/tools/comparison.js.map +1 -0
  61. package/dist/tools/export.d.ts +43 -0
  62. package/dist/tools/export.d.ts.map +1 -0
  63. package/dist/tools/export.js +746 -0
  64. package/dist/tools/export.js.map +1 -0
  65. package/dist/tools/filter.d.ts +26 -0
  66. package/dist/tools/filter.d.ts.map +1 -0
  67. package/dist/tools/filter.js +244 -0
  68. package/dist/tools/filter.js.map +1 -0
  69. package/dist/tools/session.d.ts +26 -0
  70. package/dist/tools/session.d.ts.map +1 -0
  71. package/dist/tools/session.js +228 -0
  72. package/dist/tools/session.js.map +1 -0
  73. package/dist/tools/visualize.d.ts +26 -0
  74. package/dist/tools/visualize.d.ts.map +1 -0
  75. package/dist/tools/visualize.js +942 -0
  76. package/dist/tools/visualize.js.map +1 -0
  77. package/dist/types/index.d.ts +792 -0
  78. package/dist/types/index.d.ts.map +1 -0
  79. package/dist/types/index.js +24 -0
  80. package/dist/types/index.js.map +1 -0
  81. package/package.json +69 -0
package/bin/server.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Wrapper script for npx execution
4
+ // This file is executed when running: npx @dallask/a11y-mcp-srv
5
+ import('../dist/server.js').catch((error) => {
6
+ console.error('Error starting server:', error);
7
+ process.exit(1);
8
+ });
@@ -0,0 +1,123 @@
1
+ /**
2
+ * AccessibilityRunner - Runs accessibility tests using axe-core or IBM Equal Access (ACE)
3
+ * Replaces previous WAVE-based implementation with axe-core and accessibility-checker.
4
+ */
5
+ import { type Page } from 'playwright';
6
+ import type { AccessibilityResults, AccessibilityTag, AccessibilityEngine, WaitStrategy } from '../types/index.js';
7
+ /** Re-export for callers that use runner config */
8
+ export type { AccessibilityEngine } from '../types/index.js';
9
+ /**
10
+ * Configuration for running an accessibility test
11
+ */
12
+ export interface AccessibilityRunnerConfig {
13
+ /** URL to test */
14
+ url: string;
15
+ /** Wait strategy for page loading */
16
+ waitForLoad?: WaitStrategy;
17
+ /** Timeout in milliseconds (default: 30000) */
18
+ timeout?: number;
19
+ /** Accessibility tags to pass to the engine as runOnly scope */
20
+ tags?: AccessibilityTag[];
21
+ /** Engine to use: axe-core (default) or IBM Equal Access */
22
+ engine?: AccessibilityEngine;
23
+ /** Whether to post-filter results by tags (default: false).
24
+ * Set to true only when the user explicitly requested specific tags.
25
+ * When false, tags are passed to the engine for scoping but all returned issues are shown. */
26
+ applyTagFilter?: boolean;
27
+ }
28
+ /**
29
+ * Result from running an accessibility test
30
+ */
31
+ export interface AccessibilityRunnerResult {
32
+ /** Raw accessibility results */
33
+ accessibilityResults: AccessibilityResults;
34
+ /** Filtered results if tags were specified */
35
+ filteredResults?: AccessibilityResults;
36
+ /** Applied filters information */
37
+ appliedFilters?: {
38
+ tags?: AccessibilityTag[];
39
+ originalIssueCount?: number;
40
+ };
41
+ /** HTTP status code of the main document response (e.g. 200, 401). Undefined when no navigation. */
42
+ responseStatus?: number;
43
+ }
44
+ /**
45
+ * AccessibilityRunner class - Handles accessibility test execution with axe-core or ACE
46
+ */
47
+ export declare class AccessibilityRunner {
48
+ private axePath;
49
+ constructor();
50
+ /**
51
+ * Navigate to URL and wait for page to be ready.
52
+ * @returns HTTP status code of the main document response (e.g. 200, 401), or undefined if unavailable.
53
+ */
54
+ private navigateAndWait;
55
+ /**
56
+ * Build axe run options (runOnly tags)
57
+ */
58
+ private buildAxeOptions;
59
+ /**
60
+ * Run axe-core analysis in the browser and return raw axe result
61
+ */
62
+ private runAxeAnalysis;
63
+ /**
64
+ * Convert axe-core results to our AccessibilityResults format
65
+ */
66
+ private axeToAccessibilityResults;
67
+ /**
68
+ * Map axe-style WCAG tags to IBM Equal Access policy IDs.
69
+ * ACE is scoped at scan time via setConfig({ policies }) — not post-filtered.
70
+ * wcag22* → WCAG_2_2
71
+ * wcag21* → WCAG_2_1
72
+ * wcag2* → WCAG_2_0
73
+ * best-practice / (default) → IBM_Accessibility
74
+ */
75
+ private acePolicesFromTags;
76
+ /**
77
+ * Run IBM Equal Access (accessibility-checker) analysis on HTML content.
78
+ * ACE never fetches URLs; the caller loads the page in Playwright and passes the final HTML
79
+ * (including everything changed by JavaScript). This avoids ACE's internal Puppeteer launch.
80
+ * WCAG level/policy is configured via setConfig before the scan — tags are engine settings.
81
+ */
82
+ private runACEAnalysis;
83
+ /**
84
+ * Compare impact severity (higher = worse). Used to take the worst impact per rule.
85
+ * Uses IMPACT_ORDER for both axe and ACE native levels.
86
+ */
87
+ private impactRank;
88
+ /**
89
+ * Convert ACE report to our AccessibilityResults format.
90
+ * Uses ACE native levels (violation, potentialviolation, recommendation, etc.).
91
+ */
92
+ private aceToAccessibilityResults;
93
+ /**
94
+ * Run accessibility analysis (axe in browser, or ACE via getCompliance)
95
+ */
96
+ private runAccessibilityAnalysis;
97
+ /**
98
+ * Count total issues in violations
99
+ */
100
+ private countTotalIssues;
101
+ /**
102
+ * Get a mapping of common accessibility rule IDs to their accessibility tags.
103
+ * Includes both axe-core and ACE-style rule IDs; WCAG 2.2 tags ensure strict
104
+ * tag filters (e.g. wcag22aa only) still include these rules.
105
+ */
106
+ private getRuleTagMapping;
107
+ /**
108
+ * Check if a rule matches any of the specified tags.
109
+ * Only uses ruleData.tags when the array is non-empty; otherwise falls back to
110
+ * the static mapping and finally defaults to true (include the rule).
111
+ * This prevents rules with tags:[] from being silently dropped.
112
+ */
113
+ private ruleMatchesTags;
114
+ /**
115
+ * Filter accessibility results by tags
116
+ */
117
+ private filterByTags;
118
+ /**
119
+ * Run accessibility test on a URL
120
+ */
121
+ run(page: Page, config: AccessibilityRunnerConfig): Promise<AccessibilityRunnerResult>;
122
+ }
123
+ //# sourceMappingURL=accessibility-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibility-runner.d.ts","sourceRoot":"","sources":["../../src/core/accessibility-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAGtC,OAAO,KAAK,EACV,oBAAoB,EAIpB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACb,MAAM,mBAAmB,CAAA;AAW1B,mDAAmD;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE5D;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,qCAAqC;IACrC,WAAW,CAAC,EAAE,YAAY,CAAA;IAC1B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACzB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B;;mGAE+F;IAC/F,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,gCAAgC;IAChC,oBAAoB,EAAE,oBAAoB,CAAA;IAC1C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,oBAAoB,CAAA;IACtC,kCAAkC;IAClC,cAAc,CAAC,EAAE;QACf,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAA;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAC5B,CAAA;IACD,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AA+FD;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAQ;;IASvB;;;OAGG;YACW,eAAe;IA+D7B;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;YACW,cAAc;IA0B5B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAmEjC;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;;;;OAKG;YACW,cAAc;IAqB5B;;;OAGG;IACH,OAAO,CAAC,UAAU;IAKlB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAoEjC;;OAEG;YACW,wBAAwB;IA4BtC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAmCzB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAiBvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAiCpB;;OAEG;IACG,GAAG,CACP,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,yBAAyB,CAAC;CA+DtC"}
@@ -0,0 +1,465 @@
1
+ /**
2
+ * AccessibilityRunner - Runs accessibility tests using axe-core or IBM Equal Access (ACE)
3
+ * Replaces previous WAVE-based implementation with axe-core and accessibility-checker.
4
+ */
5
+ import * as path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import { IMPACT_ORDER } from '../types/index.js';
8
+ /**
9
+ * Debug logger that writes to stderr to avoid interfering with MCP protocol
10
+ */
11
+ function debugLog(...args) {
12
+ console.error(...args);
13
+ }
14
+ /** Default axe-core tags for WCAG 2.1 AA */
15
+ const DEFAULT_AXE_TAGS = [
16
+ 'wcag2a',
17
+ 'wcag2aa',
18
+ 'wcag21a',
19
+ 'wcag21aa',
20
+ 'best-practice',
21
+ ];
22
+ /**
23
+ * Parse tagName, className, and id from HTML snippet or path.dom string.
24
+ * Used to populate domInfo so Element and Class selector columns are accurate.
25
+ */
26
+ function parseDomFromSnippet(snippet, pathDom) {
27
+ let tagName = '';
28
+ let className = null;
29
+ let id = null;
30
+ if (snippet) {
31
+ const tagMatch = snippet.match(/<\s*(\w+)[\s>]/);
32
+ if (tagMatch)
33
+ tagName = tagMatch[1].toLowerCase();
34
+ const classMatch = snippet.match(/class\s*=\s*["']([^"']*)["']/);
35
+ if (classMatch)
36
+ className = classMatch[1].trim() || null;
37
+ const idMatch = snippet.match(/\bid\s*=\s*["']([^"']*)["']/);
38
+ if (idMatch)
39
+ id = idMatch[1].trim() || null;
40
+ }
41
+ if (!tagName && pathDom) {
42
+ const segments = pathDom.split(/[/.]/);
43
+ const last = segments[segments.length - 1];
44
+ if (last) {
45
+ const tagPart = last.replace(/\[\d+\]$/, '').trim();
46
+ if (tagPart)
47
+ tagName = tagPart.toLowerCase();
48
+ }
49
+ }
50
+ if (!tagName)
51
+ tagName = 'element';
52
+ return { tagName, className, id };
53
+ }
54
+ /**
55
+ * AccessibilityRunner class - Handles accessibility test execution with axe-core or ACE
56
+ */
57
+ export class AccessibilityRunner {
58
+ constructor() {
59
+ const currentFile = fileURLToPath(import.meta.url);
60
+ const currentDir = path.dirname(currentFile);
61
+ const serverDir = path.resolve(currentDir, '../../');
62
+ this.axePath = path.join(serverDir, 'node_modules', 'axe-core', 'axe.min.js');
63
+ }
64
+ /**
65
+ * Navigate to URL and wait for page to be ready.
66
+ * @returns HTTP status code of the main document response (e.g. 200, 401), or undefined if unavailable.
67
+ */
68
+ async navigateAndWait(page, url, waitStrategy = 'networkidle', timeout = 30000) {
69
+ debugLog(`Navigating to ${url}...`);
70
+ const startTime = Date.now();
71
+ const response = await page.goto(url, {
72
+ waitUntil: 'domcontentloaded',
73
+ timeout,
74
+ });
75
+ const status = response?.status();
76
+ if (status != null)
77
+ debugLog(`Page response status: ${status}`);
78
+ debugLog('Page navigation started');
79
+ const remainingTime = timeout - (Date.now() - startTime);
80
+ if (remainingTime > 0) {
81
+ try {
82
+ switch (waitStrategy) {
83
+ case 'networkidle':
84
+ await page.waitForLoadState('networkidle', {
85
+ timeout: Math.min(remainingTime, 6000),
86
+ });
87
+ debugLog('Page reached networkidle state');
88
+ break;
89
+ case 'load':
90
+ await page.waitForLoadState('load', {
91
+ timeout: Math.min(remainingTime, 6000),
92
+ });
93
+ debugLog('Page reached load state');
94
+ break;
95
+ case 'domcontentloaded':
96
+ debugLog('DOM content loaded');
97
+ break;
98
+ }
99
+ const finalWaitTime = timeout - (Date.now() - startTime);
100
+ if (finalWaitTime > 1000) {
101
+ try {
102
+ await page.waitForFunction(() => (typeof document !== 'undefined' &&
103
+ document.readyState === 'complete' &&
104
+ document.body !== null), { timeout: Math.min(finalWaitTime, 2000) });
105
+ debugLog('DOM is ready');
106
+ }
107
+ catch {
108
+ debugLog('DOM readiness check timed out, proceeding anyway...');
109
+ }
110
+ }
111
+ }
112
+ catch {
113
+ debugLog('Page still loading, but proceeding with analysis...');
114
+ }
115
+ }
116
+ debugLog(`Page loading completed in ${Date.now() - startTime}ms - proceeding with accessibility analysis`);
117
+ return status;
118
+ }
119
+ /**
120
+ * Build axe run options (runOnly tags)
121
+ */
122
+ buildAxeOptions(tags) {
123
+ const runOnly = tags && tags.length > 0 ? [...tags] : [...DEFAULT_AXE_TAGS];
124
+ return { runOnly };
125
+ }
126
+ /**
127
+ * Run axe-core analysis in the browser and return raw axe result
128
+ */
129
+ async runAxeAnalysis(page, tags) {
130
+ const axeOptions = this.buildAxeOptions(tags);
131
+ await page.addScriptTag({ path: this.axePath });
132
+ const rawResult = await page.evaluate((options) => {
133
+ return new Promise((resolve, reject) => {
134
+ if (typeof window.axe?.run !== 'function') {
135
+ reject(new Error('axe.run is not available'));
136
+ return;
137
+ }
138
+ ;
139
+ window
140
+ .axe.run(options)
141
+ .then(resolve)
142
+ .catch(reject);
143
+ });
144
+ }, axeOptions);
145
+ return rawResult;
146
+ }
147
+ /**
148
+ * Convert axe-core results to our AccessibilityResults format
149
+ */
150
+ axeToAccessibilityResults(axeResult, url, testEnvironment) {
151
+ const violations = {};
152
+ const timestamp = new Date().toISOString();
153
+ axeResult.violations.forEach((v) => {
154
+ const categoryKey = v.id.toLowerCase().includes('color-contrast') ||
155
+ v.id.toLowerCase().includes('contrast')
156
+ ? 'contrast'
157
+ : 'error';
158
+ if (!violations[categoryKey]) {
159
+ violations[categoryKey] = { count: 0, items: {} };
160
+ }
161
+ const xpaths = (v.nodes || []).map((n) => (n.target && n.target[0]) || '');
162
+ const domInfo = (v.nodes || []).map((n) => {
163
+ const selector = n.target && n.target[0];
164
+ const { tagName, className, id } = parseDomFromSnippet(n.html ?? null, selector);
165
+ return {
166
+ innerHTML: n.html ? n.html.substring(0, 200) : null,
167
+ selector,
168
+ tagName,
169
+ className,
170
+ id,
171
+ };
172
+ });
173
+ // Use axe-core native impact levels (critical, serious, moderate, minor)
174
+ const impact = v.impact?.toLowerCase() ?? 'moderate';
175
+ const ruleData = {
176
+ count: v.nodes?.length ?? 0,
177
+ xpaths,
178
+ description: v.description ?? v.help ?? v.id,
179
+ domInfo,
180
+ tags: v.tags ?? [],
181
+ impact,
182
+ };
183
+ violations[categoryKey].items[v.id] = ruleData;
184
+ violations[categoryKey].count += ruleData.count;
185
+ });
186
+ return {
187
+ url,
188
+ timestamp,
189
+ testEngine: { name: 'axe-core', version: '4.x' },
190
+ testRunner: { name: 'Standalone Accessibility Analyzer' },
191
+ testEnvironment,
192
+ violations,
193
+ };
194
+ }
195
+ /**
196
+ * Map axe-style WCAG tags to IBM Equal Access policy IDs.
197
+ * ACE is scoped at scan time via setConfig({ policies }) — not post-filtered.
198
+ * wcag22* → WCAG_2_2
199
+ * wcag21* → WCAG_2_1
200
+ * wcag2* → WCAG_2_0
201
+ * best-practice / (default) → IBM_Accessibility
202
+ */
203
+ acePolicesFromTags(tags) {
204
+ if (!tags || tags.length === 0)
205
+ return ['IBM_Accessibility'];
206
+ if (tags.some((t) => t.startsWith('wcag22')))
207
+ return ['WCAG_2_2'];
208
+ if (tags.some((t) => t.startsWith('wcag21')))
209
+ return ['WCAG_2_1'];
210
+ if (tags.some((t) => t.startsWith('wcag2')))
211
+ return ['WCAG_2_0'];
212
+ return ['IBM_Accessibility'];
213
+ }
214
+ /**
215
+ * Run IBM Equal Access (accessibility-checker) analysis on HTML content.
216
+ * ACE never fetches URLs; the caller loads the page in Playwright and passes the final HTML
217
+ * (including everything changed by JavaScript). This avoids ACE's internal Puppeteer launch.
218
+ * WCAG level/policy is configured via setConfig before the scan — tags are engine settings.
219
+ */
220
+ async runACEAnalysis(htmlContent, url, tags) {
221
+ const aChecker = await import('accessibility-checker');
222
+ const label = `audit-${Date.now()}`;
223
+ const policies = this.acePolicesFromTags(tags);
224
+ debugLog(`ACE policies: ${policies.join(', ')}`);
225
+ try {
226
+ await aChecker.setConfig({ policies, ruleArchive: 'latest' });
227
+ const result = await aChecker.getCompliance(htmlContent, label);
228
+ const report = result.report;
229
+ return this.aceToAccessibilityResults(report, url);
230
+ }
231
+ finally {
232
+ await aChecker.close?.();
233
+ }
234
+ }
235
+ /**
236
+ * Compare impact severity (higher = worse). Used to take the worst impact per rule.
237
+ * Uses IMPACT_ORDER for both axe and ACE native levels.
238
+ */
239
+ impactRank(a) {
240
+ if (!a)
241
+ return 0;
242
+ return IMPACT_ORDER[a.toLowerCase()] ?? 2;
243
+ }
244
+ /**
245
+ * Convert ACE report to our AccessibilityResults format.
246
+ * Uses ACE native levels (violation, potentialviolation, recommendation, etc.).
247
+ */
248
+ aceToAccessibilityResults(report, url) {
249
+ const violations = { error: { count: 0, items: {} } };
250
+ const timestamp = new Date().toISOString();
251
+ const violationItems = report.results.filter((r) => r.level === 'violation' ||
252
+ r.level === 'potentialviolation' ||
253
+ r.level === 'recommendation' ||
254
+ r.level === 'potentialrecommendation' ||
255
+ r.level === 'manual');
256
+ violationItems.forEach((item) => {
257
+ const ruleId = item.ruleId;
258
+ // Use ACE native level (violation, potentialviolation, recommendation, etc.)
259
+ const itemImpact = item.level.toLowerCase();
260
+ if (!violations.error.items[ruleId]) {
261
+ violations.error.items[ruleId] = {
262
+ count: 0,
263
+ xpaths: [],
264
+ description: item.message,
265
+ domInfo: [],
266
+ tags: [],
267
+ impact: itemImpact,
268
+ };
269
+ }
270
+ const rule = violations.error.items[ruleId];
271
+ rule.count += 1;
272
+ rule.xpaths.push(item.path.dom || '');
273
+ const { tagName, className, id } = parseDomFromSnippet(item.snippet ?? null, item.path.dom);
274
+ rule.domInfo.push({
275
+ innerHTML: item.snippet ? item.snippet.substring(0, 200) : null,
276
+ selector: item.path.dom,
277
+ tagName,
278
+ className,
279
+ id,
280
+ });
281
+ if (itemImpact && this.impactRank(itemImpact) > this.impactRank(rule.impact)) {
282
+ rule.impact = itemImpact;
283
+ }
284
+ });
285
+ Object.values(violations.error.items).forEach((rule) => {
286
+ violations.error.count += rule.count;
287
+ });
288
+ return {
289
+ url,
290
+ timestamp,
291
+ testEngine: { name: 'IBM Equal Access', version: '4.x' },
292
+ testRunner: { name: 'accessibility-checker' },
293
+ testEnvironment: {
294
+ userAgent: 'accessibility-checker',
295
+ windowWidth: 1280,
296
+ windowHeight: 720,
297
+ },
298
+ violations,
299
+ };
300
+ }
301
+ /**
302
+ * Run accessibility analysis (axe in browser, or ACE via getCompliance)
303
+ */
304
+ async runAccessibilityAnalysis(page, url, engine, tags) {
305
+ if (engine === 'ace') {
306
+ const html = await page.content();
307
+ return this.runACEAnalysis(html, url, tags);
308
+ }
309
+ const axeResult = await this.runAxeAnalysis(page, tags);
310
+ const viewport = page.viewportSize();
311
+ const testEnvironment = {
312
+ userAgent: await page.evaluate(() => navigator.userAgent),
313
+ windowWidth: viewport?.width ?? 1280,
314
+ windowHeight: viewport?.height ?? 720,
315
+ orientationType: await page
316
+ .evaluate(() => screen.orientation?.type)
317
+ .catch(() => undefined),
318
+ orientationAngle: await page
319
+ .evaluate(() => screen.orientation?.angle)
320
+ .catch(() => undefined),
321
+ };
322
+ return this.axeToAccessibilityResults(axeResult, url, testEnvironment);
323
+ }
324
+ /**
325
+ * Count total issues in violations
326
+ */
327
+ countTotalIssues(violations) {
328
+ let total = 0;
329
+ Object.values(violations).forEach((category) => {
330
+ if (category && category.count) {
331
+ total += category.count;
332
+ }
333
+ });
334
+ return total;
335
+ }
336
+ /**
337
+ * Get a mapping of common accessibility rule IDs to their accessibility tags.
338
+ * Includes both axe-core and ACE-style rule IDs; WCAG 2.2 tags ensure strict
339
+ * tag filters (e.g. wcag22aa only) still include these rules.
340
+ */
341
+ getRuleTagMapping() {
342
+ const wcagA = [
343
+ 'wcag2a',
344
+ 'wcag21a',
345
+ 'wcag22a',
346
+ ];
347
+ const wcagAA = [
348
+ 'wcag2aa',
349
+ 'wcag21aa',
350
+ 'wcag22aa',
351
+ ];
352
+ return {
353
+ 'color-contrast': ['wcag21aa', 'wcag2aa', 'wcag22aa'],
354
+ 'image-alt': wcagA,
355
+ label: wcagA,
356
+ 'heading-order': wcagA,
357
+ 'html-has-lang': wcagA,
358
+ 'link-name': wcagA,
359
+ 'aria-valid-attr-value': wcagA,
360
+ tabindex: wcagA,
361
+ 'button-name': wcagA,
362
+ 'document-title': wcagA,
363
+ 'heading_empty': wcagA,
364
+ 'button_empty': wcagA,
365
+ 'aria_reference_broken': wcagA,
366
+ contrast: ['wcag21aa', 'wcag2aa', 'wcag22aa'],
367
+ // ACE-style rule IDs (common patterns)
368
+ 'RPT_Header_HasContent': wcagA,
369
+ 'RPT_Button_AccessibleName': wcagA,
370
+ 'RPT_Label_FormControls': wcagA,
371
+ 'RPT_Elem_UniqueId': wcagA,
372
+ 'IBMA_Color_Contrast_WCAG2AA': wcagAA,
373
+ };
374
+ }
375
+ /**
376
+ * Check if a rule matches any of the specified tags.
377
+ * Only uses ruleData.tags when the array is non-empty; otherwise falls back to
378
+ * the static mapping and finally defaults to true (include the rule).
379
+ * This prevents rules with tags:[] from being silently dropped.
380
+ */
381
+ ruleMatchesTags(ruleId, ruleData, tags) {
382
+ if (!tags || tags.length === 0)
383
+ return true;
384
+ if (ruleData.tags && Array.isArray(ruleData.tags) && ruleData.tags.length > 0) {
385
+ return ruleData.tags.some((tag) => tags.includes(tag));
386
+ }
387
+ const mapping = this.getRuleTagMapping();
388
+ const ruleTags = mapping[ruleId];
389
+ if (ruleTags?.length) {
390
+ return ruleTags.some((tag) => tags.includes(tag));
391
+ }
392
+ return true;
393
+ }
394
+ /**
395
+ * Filter accessibility results by tags
396
+ */
397
+ filterByTags(results, tags) {
398
+ if (!tags || tags.length === 0)
399
+ return results;
400
+ const filteredViolations = {};
401
+ Object.entries(results.violations).forEach(([categoryKey, category]) => {
402
+ if (!category?.items)
403
+ return;
404
+ const filteredItems = {};
405
+ Object.entries(category.items).forEach(([ruleId, ruleData]) => {
406
+ if (this.ruleMatchesTags(ruleId, ruleData, tags)) {
407
+ filteredItems[ruleId] = ruleData;
408
+ }
409
+ });
410
+ if (Object.keys(filteredItems).length > 0) {
411
+ const categoryCount = Object.values(filteredItems).reduce((total, item) => total + (item.count || 0), 0);
412
+ filteredViolations[categoryKey] = {
413
+ count: categoryCount,
414
+ items: filteredItems,
415
+ };
416
+ }
417
+ });
418
+ return { ...results, violations: filteredViolations };
419
+ }
420
+ /**
421
+ * Run accessibility test on a URL
422
+ */
423
+ async run(page, config) {
424
+ const { url, waitForLoad = 'networkidle', timeout = 30000, tags, engine = 'axe', applyTagFilter = false, } = config;
425
+ try {
426
+ if (engine === 'ace') {
427
+ // Always load the page in Playwright and pass the final HTML to ACE (no separate ACE browser).
428
+ // This gives us JS-rendered content and supports Basic Auth; ACE only analyzes the HTML string.
429
+ const responseStatus = await this.navigateAndWait(page, url, waitForLoad, timeout);
430
+ const html = await page.content();
431
+ debugLog(`Running IBM Equal Access (ACE) analysis on page content (${url})...`);
432
+ const accessibilityResults = await this.runACEAnalysis(html, url, tags);
433
+ return {
434
+ accessibilityResults,
435
+ filteredResults: undefined,
436
+ appliedFilters: tags && tags.length > 0 ? { tags } : undefined,
437
+ responseStatus,
438
+ };
439
+ }
440
+ const responseStatus = await this.navigateAndWait(page, url, waitForLoad, timeout);
441
+ debugLog(`Running axe-core analysis on ${url}...`);
442
+ const accessibilityResults = await this.runAccessibilityAnalysis(page, url, 'axe', tags);
443
+ const originalIssueCount = this.countTotalIssues(accessibilityResults.violations);
444
+ let filteredResults;
445
+ let appliedFilters;
446
+ if (applyTagFilter && tags && tags.length > 0) {
447
+ filteredResults = this.filterByTags(accessibilityResults, tags);
448
+ appliedFilters = { tags, originalIssueCount };
449
+ debugLog(`Filtered results: ${originalIssueCount} -> ${this.countTotalIssues(filteredResults.violations)} issues (tags: ${tags.join(', ')})`);
450
+ }
451
+ return {
452
+ accessibilityResults,
453
+ filteredResults,
454
+ appliedFilters,
455
+ responseStatus,
456
+ };
457
+ }
458
+ catch (error) {
459
+ console.error('Error running accessibility test:', error);
460
+ const errorMessage = error instanceof Error ? error.message : String(error);
461
+ throw new Error(`Accessibility test failed for ${url}: ${errorMessage}`);
462
+ }
463
+ }
464
+ }
465
+ //# sourceMappingURL=accessibility-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibility-runner.js","sourceRoot":"","sources":["../../src/core/accessibility-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Shared HTTP Basic Auth utilities for tools that use URLs.
3
+ * Use when auditing or fetching URLs that require Basic Authentication.
4
+ */
5
+ export interface ParsedUrlCredentials {
6
+ urlWithoutAuth: string;
7
+ username?: string;
8
+ password?: string;
9
+ }
10
+ export interface BasicAuthParams {
11
+ basicAuthUsername?: string;
12
+ basicAuthPassword?: string;
13
+ }
14
+ /**
15
+ * Parse Basic Auth credentials from URL if present (e.g. https://user:password@host/path).
16
+ * Returns URL with credentials stripped and optional username/password.
17
+ */
18
+ export declare function parseUrlCredentials(url: string): ParsedUrlCredentials;
19
+ /**
20
+ * Build the Authorization header value for HTTP Basic Auth.
21
+ * Returns "Basic <base64(user:password)>" or null if either credential is missing.
22
+ */
23
+ export declare function getBasicAuthHeader(username: string | undefined, password: string | undefined): string | null;
24
+ /**
25
+ * Resolve URL and Basic Auth from a URL (possibly with user:password@host) and optional
26
+ * explicit username/password. Explicit params override credentials embedded in the URL.
27
+ * Returns normalized URL without auth and credentials suitable for passing to auditUrl etc.
28
+ */
29
+ export declare function resolveBasicAuth(url: string, explicitUsername?: string, explicitPassword?: string): {
30
+ urlWithoutAuth: string;
31
+ basicAuthUsername: string | undefined;
32
+ basicAuthPassword: string | undefined;
33
+ basicAuthHeader: string | null;
34
+ };
35
+ //# sourceMappingURL=basic-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic-auth.d.ts","sourceRoot":"","sources":["../../src/core/basic-auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAcrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,gBAAgB,CAAC,EAAE,MAAM,EACzB,gBAAgB,CAAC,EAAE,MAAM,GACxB;IACD,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B,CAWA"}