@dallask/a11y-mcp-srv 1.1.7
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/LICENSE +21 -0
- package/NOTICE +9 -0
- package/README.md +1311 -0
- package/bin/server.js +8 -0
- package/dist/core/accessibility-runner.d.ts +115 -0
- package/dist/core/accessibility-runner.d.ts.map +1 -0
- package/dist/core/accessibility-runner.js +419 -0
- package/dist/core/accessibility-runner.js.map +1 -0
- package/dist/core/config.d.ts +42 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +159 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/error-handler.d.ts +61 -0
- package/dist/core/error-handler.d.ts.map +1 -0
- package/dist/core/error-handler.js +264 -0
- package/dist/core/error-handler.js.map +1 -0
- package/dist/core/progress-streamer.d.ts +44 -0
- package/dist/core/progress-streamer.d.ts.map +1 -0
- package/dist/core/progress-streamer.js +160 -0
- package/dist/core/progress-streamer.js.map +1 -0
- package/dist/core/result-processor.d.ts +69 -0
- package/dist/core/result-processor.d.ts.map +1 -0
- package/dist/core/result-processor.js +461 -0
- package/dist/core/result-processor.js.map +1 -0
- package/dist/core/session-manager.d.ts +73 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +243 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1298 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/aggregate.d.ts +26 -0
- package/dist/tools/aggregate.d.ts.map +1 -0
- package/dist/tools/aggregate.js +308 -0
- package/dist/tools/aggregate.js.map +1 -0
- package/dist/tools/analysis.d.ts +68 -0
- package/dist/tools/analysis.d.ts.map +1 -0
- package/dist/tools/analysis.js +1232 -0
- package/dist/tools/analysis.js.map +1 -0
- package/dist/tools/audit.d.ts +38 -0
- package/dist/tools/audit.d.ts.map +1 -0
- package/dist/tools/audit.js +422 -0
- package/dist/tools/audit.js.map +1 -0
- package/dist/tools/comparison.d.ts +27 -0
- package/dist/tools/comparison.d.ts.map +1 -0
- package/dist/tools/comparison.js +488 -0
- package/dist/tools/comparison.js.map +1 -0
- package/dist/tools/export.d.ts +43 -0
- package/dist/tools/export.d.ts.map +1 -0
- package/dist/tools/export.js +729 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/filter.d.ts +26 -0
- package/dist/tools/filter.d.ts.map +1 -0
- package/dist/tools/filter.js +227 -0
- package/dist/tools/filter.js.map +1 -0
- package/dist/tools/session.d.ts +26 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +227 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/visualize.d.ts +26 -0
- package/dist/tools/visualize.d.ts.map +1 -0
- package/dist/tools/visualize.js +946 -0
- package/dist/tools/visualize.js.map +1 -0
- package/dist/types/index.d.ts +755 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +57 -0
package/bin/server.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
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
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* AccessibilityRunner class - Handles accessibility test execution with axe-core or ACE
|
|
44
|
+
*/
|
|
45
|
+
export declare class AccessibilityRunner {
|
|
46
|
+
private axePath;
|
|
47
|
+
constructor();
|
|
48
|
+
/**
|
|
49
|
+
* Navigate to URL and wait for page to be ready
|
|
50
|
+
*/
|
|
51
|
+
private navigateAndWait;
|
|
52
|
+
/**
|
|
53
|
+
* Build axe run options (runOnly tags)
|
|
54
|
+
*/
|
|
55
|
+
private buildAxeOptions;
|
|
56
|
+
/**
|
|
57
|
+
* Run axe-core analysis in the browser and return raw axe result
|
|
58
|
+
*/
|
|
59
|
+
private runAxeAnalysis;
|
|
60
|
+
/**
|
|
61
|
+
* Convert axe-core results to our AccessibilityResults format
|
|
62
|
+
*/
|
|
63
|
+
private axeToAccessibilityResults;
|
|
64
|
+
/**
|
|
65
|
+
* Run IBM Equal Access (accessibility-checker) analysis for a URL
|
|
66
|
+
*/
|
|
67
|
+
private runACEAnalysis;
|
|
68
|
+
/**
|
|
69
|
+
* Map ACE report level to IBM Equal Access severity levels.
|
|
70
|
+
* Matches the IBM browser tool exactly:
|
|
71
|
+
* violation → 'violation' (🚫 red)
|
|
72
|
+
* potentialviolation → 'needs-review' (⚠️ yellow)
|
|
73
|
+
* potentialrecommendation→ 'needs-review' (⚠️ yellow)
|
|
74
|
+
* recommendation → 'recommendation' (ℹ️ blue)
|
|
75
|
+
* manual → 'needs-review' (⚠️ yellow – manual check required)
|
|
76
|
+
* pass / ignored → 'minor'
|
|
77
|
+
*/
|
|
78
|
+
private aceLevelToImpact;
|
|
79
|
+
/**
|
|
80
|
+
* Compare impact severity (higher = worse). Used to take the worst impact per rule.
|
|
81
|
+
*/
|
|
82
|
+
private impactRank;
|
|
83
|
+
/**
|
|
84
|
+
* Convert ACE report to our AccessibilityResults format.
|
|
85
|
+
* Preserves ACE severity (critical/serious/moderate) so output matches the IBM browser tool.
|
|
86
|
+
*/
|
|
87
|
+
private aceToAccessibilityResults;
|
|
88
|
+
/**
|
|
89
|
+
* Run accessibility analysis (axe in browser, or ACE via getCompliance)
|
|
90
|
+
*/
|
|
91
|
+
private runAccessibilityAnalysis;
|
|
92
|
+
/**
|
|
93
|
+
* Count total issues in violations
|
|
94
|
+
*/
|
|
95
|
+
private countTotalIssues;
|
|
96
|
+
/**
|
|
97
|
+
* Get a mapping of common accessibility rule IDs to their accessibility tags.
|
|
98
|
+
* Includes both axe-core and ACE-style rule IDs; WCAG 2.2 tags ensure strict
|
|
99
|
+
* tag filters (e.g. wcag22aa only) still include these rules.
|
|
100
|
+
*/
|
|
101
|
+
private getRuleTagMapping;
|
|
102
|
+
/**
|
|
103
|
+
* Check if a rule matches any of the specified tags
|
|
104
|
+
*/
|
|
105
|
+
private ruleMatchesTags;
|
|
106
|
+
/**
|
|
107
|
+
* Filter accessibility results by tags
|
|
108
|
+
*/
|
|
109
|
+
private filterByTags;
|
|
110
|
+
/**
|
|
111
|
+
* Run accessibility test on a URL
|
|
112
|
+
*/
|
|
113
|
+
run(page: Page, config: AccessibilityRunnerConfig): Promise<AccessibilityRunnerResult>;
|
|
114
|
+
}
|
|
115
|
+
//# 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;AAU1B,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;CACF;AA6DD;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAQ;;IASvB;;OAEG;YACW,eAAe;IA4D7B;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;YACW,cAAc;IA0B5B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAmEjC;;OAEG;YACW,cAAc;IAgB5B;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IA2DjC;;OAEG;YACW,wBAAwB;IA2BtC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAmCzB;;OAEG;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;CAqEtC"}
|
|
@@ -0,0 +1,419 @@
|
|
|
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
|
+
/**
|
|
8
|
+
* Debug logger that writes to stderr to avoid interfering with MCP protocol
|
|
9
|
+
*/
|
|
10
|
+
function debugLog(...args) {
|
|
11
|
+
console.error(...args);
|
|
12
|
+
}
|
|
13
|
+
/** Default axe-core tags for WCAG 2.1 AA */
|
|
14
|
+
const DEFAULT_AXE_TAGS = [
|
|
15
|
+
'wcag2a',
|
|
16
|
+
'wcag2aa',
|
|
17
|
+
'wcag21a',
|
|
18
|
+
'wcag21aa',
|
|
19
|
+
'best-practice',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* AccessibilityRunner class - Handles accessibility test execution with axe-core or ACE
|
|
23
|
+
*/
|
|
24
|
+
export class AccessibilityRunner {
|
|
25
|
+
constructor() {
|
|
26
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
27
|
+
const currentDir = path.dirname(currentFile);
|
|
28
|
+
const serverDir = path.resolve(currentDir, '../../');
|
|
29
|
+
this.axePath = path.join(serverDir, 'node_modules', 'axe-core', 'axe.min.js');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Navigate to URL and wait for page to be ready
|
|
33
|
+
*/
|
|
34
|
+
async navigateAndWait(page, url, waitStrategy = 'networkidle', timeout = 30000) {
|
|
35
|
+
debugLog(`Navigating to ${url}...`);
|
|
36
|
+
const startTime = Date.now();
|
|
37
|
+
await page.goto(url, {
|
|
38
|
+
waitUntil: 'domcontentloaded',
|
|
39
|
+
timeout,
|
|
40
|
+
});
|
|
41
|
+
debugLog('Page navigation started');
|
|
42
|
+
const remainingTime = timeout - (Date.now() - startTime);
|
|
43
|
+
if (remainingTime > 0) {
|
|
44
|
+
try {
|
|
45
|
+
switch (waitStrategy) {
|
|
46
|
+
case 'networkidle':
|
|
47
|
+
await page.waitForLoadState('networkidle', {
|
|
48
|
+
timeout: Math.min(remainingTime, 6000),
|
|
49
|
+
});
|
|
50
|
+
debugLog('Page reached networkidle state');
|
|
51
|
+
break;
|
|
52
|
+
case 'load':
|
|
53
|
+
await page.waitForLoadState('load', {
|
|
54
|
+
timeout: Math.min(remainingTime, 6000),
|
|
55
|
+
});
|
|
56
|
+
debugLog('Page reached load state');
|
|
57
|
+
break;
|
|
58
|
+
case 'domcontentloaded':
|
|
59
|
+
debugLog('DOM content loaded');
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
const finalWaitTime = timeout - (Date.now() - startTime);
|
|
63
|
+
if (finalWaitTime > 1000) {
|
|
64
|
+
try {
|
|
65
|
+
await page.waitForFunction(() => (typeof document !== 'undefined' &&
|
|
66
|
+
document.readyState === 'complete' &&
|
|
67
|
+
document.body !== null), { timeout: Math.min(finalWaitTime, 2000) });
|
|
68
|
+
debugLog('DOM is ready');
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
debugLog('DOM readiness check timed out, proceeding anyway...');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
debugLog('Page still loading, but proceeding with analysis...');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
debugLog(`Page loading completed in ${Date.now() - startTime}ms - proceeding with accessibility analysis`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build axe run options (runOnly tags)
|
|
83
|
+
*/
|
|
84
|
+
buildAxeOptions(tags) {
|
|
85
|
+
const runOnly = tags && tags.length > 0 ? [...tags] : [...DEFAULT_AXE_TAGS];
|
|
86
|
+
return { runOnly };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Run axe-core analysis in the browser and return raw axe result
|
|
90
|
+
*/
|
|
91
|
+
async runAxeAnalysis(page, tags) {
|
|
92
|
+
const axeOptions = this.buildAxeOptions(tags);
|
|
93
|
+
await page.addScriptTag({ path: this.axePath });
|
|
94
|
+
const rawResult = await page.evaluate((options) => {
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
if (typeof window.axe?.run !== 'function') {
|
|
97
|
+
reject(new Error('axe.run is not available'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
;
|
|
101
|
+
window
|
|
102
|
+
.axe.run(options)
|
|
103
|
+
.then(resolve)
|
|
104
|
+
.catch(reject);
|
|
105
|
+
});
|
|
106
|
+
}, axeOptions);
|
|
107
|
+
return rawResult;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Convert axe-core results to our AccessibilityResults format
|
|
111
|
+
*/
|
|
112
|
+
axeToAccessibilityResults(axeResult, url, testEnvironment) {
|
|
113
|
+
const violations = {};
|
|
114
|
+
const timestamp = new Date().toISOString();
|
|
115
|
+
axeResult.violations.forEach((v) => {
|
|
116
|
+
const categoryKey = v.id.toLowerCase().includes('color-contrast') ||
|
|
117
|
+
v.id.toLowerCase().includes('contrast')
|
|
118
|
+
? 'contrast'
|
|
119
|
+
: 'error';
|
|
120
|
+
if (!violations[categoryKey]) {
|
|
121
|
+
violations[categoryKey] = { count: 0, items: {} };
|
|
122
|
+
}
|
|
123
|
+
const xpaths = (v.nodes || []).map((n) => (n.target && n.target[0]) || '');
|
|
124
|
+
const domInfo = (v.nodes || []).map((n) => ({
|
|
125
|
+
innerHTML: n.html ? n.html.substring(0, 200) : null,
|
|
126
|
+
selector: n.target && n.target[0],
|
|
127
|
+
}));
|
|
128
|
+
// Map axe-core impact levels to IBM Equal Access severity levels.
|
|
129
|
+
// Axe violations are definite failures → 'violation'.
|
|
130
|
+
// (Axe "incomplete" items would be 'needs-review' but we only process violations here.)
|
|
131
|
+
const axeImpact = v.impact?.toLowerCase();
|
|
132
|
+
const impact = axeImpact === 'critical' || axeImpact === 'serious'
|
|
133
|
+
? 'violation'
|
|
134
|
+
: axeImpact === 'moderate'
|
|
135
|
+
? 'needs-review'
|
|
136
|
+
: 'recommendation';
|
|
137
|
+
const ruleData = {
|
|
138
|
+
count: v.nodes?.length ?? 0,
|
|
139
|
+
xpaths,
|
|
140
|
+
description: v.description ?? v.help ?? v.id,
|
|
141
|
+
domInfo,
|
|
142
|
+
tags: v.tags ?? [],
|
|
143
|
+
impact,
|
|
144
|
+
};
|
|
145
|
+
violations[categoryKey].items[v.id] = ruleData;
|
|
146
|
+
violations[categoryKey].count += ruleData.count;
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
url,
|
|
150
|
+
timestamp,
|
|
151
|
+
testEngine: { name: 'axe-core', version: '4.x' },
|
|
152
|
+
testRunner: { name: 'Standalone Accessibility Analyzer' },
|
|
153
|
+
testEnvironment,
|
|
154
|
+
violations,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Run IBM Equal Access (accessibility-checker) analysis for a URL
|
|
159
|
+
*/
|
|
160
|
+
async runACEAnalysis(url, _tags) {
|
|
161
|
+
const aChecker = await import('accessibility-checker');
|
|
162
|
+
const label = `audit-${Date.now()}`;
|
|
163
|
+
try {
|
|
164
|
+
const result = await aChecker.getCompliance(url, label);
|
|
165
|
+
const report = result.report;
|
|
166
|
+
return this.aceToAccessibilityResults(report, url);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await aChecker.close?.();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Map ACE report level to IBM Equal Access severity levels.
|
|
174
|
+
* Matches the IBM browser tool exactly:
|
|
175
|
+
* violation → 'violation' (🚫 red)
|
|
176
|
+
* potentialviolation → 'needs-review' (⚠️ yellow)
|
|
177
|
+
* potentialrecommendation→ 'needs-review' (⚠️ yellow)
|
|
178
|
+
* recommendation → 'recommendation' (ℹ️ blue)
|
|
179
|
+
* manual → 'needs-review' (⚠️ yellow – manual check required)
|
|
180
|
+
* pass / ignored → 'minor'
|
|
181
|
+
*/
|
|
182
|
+
aceLevelToImpact(level) {
|
|
183
|
+
const l = level.toLowerCase();
|
|
184
|
+
if (l === 'violation')
|
|
185
|
+
return 'violation';
|
|
186
|
+
if (l === 'potentialviolation' || l === 'potentialrecommendation' || l === 'manual')
|
|
187
|
+
return 'needs-review';
|
|
188
|
+
if (l === 'recommendation')
|
|
189
|
+
return 'recommendation';
|
|
190
|
+
return 'minor';
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Compare impact severity (higher = worse). Used to take the worst impact per rule.
|
|
194
|
+
*/
|
|
195
|
+
impactRank(a) {
|
|
196
|
+
if (!a)
|
|
197
|
+
return 0;
|
|
198
|
+
const r = {
|
|
199
|
+
violation: 4,
|
|
200
|
+
'needs-review': 3,
|
|
201
|
+
recommendation: 2,
|
|
202
|
+
minor: 1,
|
|
203
|
+
};
|
|
204
|
+
return r[a] ?? 0;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Convert ACE report to our AccessibilityResults format.
|
|
208
|
+
* Preserves ACE severity (critical/serious/moderate) so output matches the IBM browser tool.
|
|
209
|
+
*/
|
|
210
|
+
aceToAccessibilityResults(report, url) {
|
|
211
|
+
const violations = { error: { count: 0, items: {} } };
|
|
212
|
+
const timestamp = new Date().toISOString();
|
|
213
|
+
const violationItems = report.results.filter((r) => r.level === 'violation' ||
|
|
214
|
+
r.level === 'potentialviolation' ||
|
|
215
|
+
r.level === 'recommendation' ||
|
|
216
|
+
r.level === 'potentialrecommendation');
|
|
217
|
+
violationItems.forEach((item) => {
|
|
218
|
+
const ruleId = item.ruleId;
|
|
219
|
+
const itemImpact = this.aceLevelToImpact(item.level);
|
|
220
|
+
if (!violations.error.items[ruleId]) {
|
|
221
|
+
violations.error.items[ruleId] = {
|
|
222
|
+
count: 0,
|
|
223
|
+
xpaths: [],
|
|
224
|
+
description: item.message,
|
|
225
|
+
domInfo: [],
|
|
226
|
+
tags: [],
|
|
227
|
+
impact: itemImpact,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
const rule = violations.error.items[ruleId];
|
|
231
|
+
rule.count += 1;
|
|
232
|
+
rule.xpaths.push(item.path.dom || '');
|
|
233
|
+
rule.domInfo.push({
|
|
234
|
+
innerHTML: item.snippet ? item.snippet.substring(0, 200) : null,
|
|
235
|
+
selector: item.path.dom,
|
|
236
|
+
});
|
|
237
|
+
if (itemImpact && this.impactRank(itemImpact) > this.impactRank(rule.impact)) {
|
|
238
|
+
rule.impact = itemImpact;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
Object.values(violations.error.items).forEach((rule) => {
|
|
242
|
+
violations.error.count += rule.count;
|
|
243
|
+
});
|
|
244
|
+
return {
|
|
245
|
+
url,
|
|
246
|
+
timestamp,
|
|
247
|
+
testEngine: { name: 'IBM Equal Access', version: '4.x' },
|
|
248
|
+
testRunner: { name: 'accessibility-checker' },
|
|
249
|
+
testEnvironment: {
|
|
250
|
+
userAgent: 'accessibility-checker',
|
|
251
|
+
windowWidth: 1280,
|
|
252
|
+
windowHeight: 720,
|
|
253
|
+
},
|
|
254
|
+
violations,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Run accessibility analysis (axe in browser, or ACE via getCompliance)
|
|
259
|
+
*/
|
|
260
|
+
async runAccessibilityAnalysis(page, url, engine, tags) {
|
|
261
|
+
if (engine === 'ace') {
|
|
262
|
+
return this.runACEAnalysis(url, tags);
|
|
263
|
+
}
|
|
264
|
+
const axeResult = await this.runAxeAnalysis(page, tags);
|
|
265
|
+
const viewport = page.viewportSize();
|
|
266
|
+
const testEnvironment = {
|
|
267
|
+
userAgent: await page.evaluate(() => navigator.userAgent),
|
|
268
|
+
windowWidth: viewport?.width ?? 1280,
|
|
269
|
+
windowHeight: viewport?.height ?? 720,
|
|
270
|
+
orientationType: await page
|
|
271
|
+
.evaluate(() => screen.orientation?.type)
|
|
272
|
+
.catch(() => undefined),
|
|
273
|
+
orientationAngle: await page
|
|
274
|
+
.evaluate(() => screen.orientation?.angle)
|
|
275
|
+
.catch(() => undefined),
|
|
276
|
+
};
|
|
277
|
+
return this.axeToAccessibilityResults(axeResult, url, testEnvironment);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Count total issues in violations
|
|
281
|
+
*/
|
|
282
|
+
countTotalIssues(violations) {
|
|
283
|
+
let total = 0;
|
|
284
|
+
Object.values(violations).forEach((category) => {
|
|
285
|
+
if (category && category.count) {
|
|
286
|
+
total += category.count;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
return total;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get a mapping of common accessibility rule IDs to their accessibility tags.
|
|
293
|
+
* Includes both axe-core and ACE-style rule IDs; WCAG 2.2 tags ensure strict
|
|
294
|
+
* tag filters (e.g. wcag22aa only) still include these rules.
|
|
295
|
+
*/
|
|
296
|
+
getRuleTagMapping() {
|
|
297
|
+
const wcagA = [
|
|
298
|
+
'wcag2a',
|
|
299
|
+
'wcag21a',
|
|
300
|
+
'wcag22a',
|
|
301
|
+
];
|
|
302
|
+
const wcagAA = [
|
|
303
|
+
'wcag2aa',
|
|
304
|
+
'wcag21aa',
|
|
305
|
+
'wcag22aa',
|
|
306
|
+
];
|
|
307
|
+
return {
|
|
308
|
+
'color-contrast': ['wcag21aa', 'wcag2aa', 'wcag22aa'],
|
|
309
|
+
'image-alt': wcagA,
|
|
310
|
+
label: wcagA,
|
|
311
|
+
'heading-order': wcagA,
|
|
312
|
+
'html-has-lang': wcagA,
|
|
313
|
+
'link-name': wcagA,
|
|
314
|
+
'aria-valid-attr-value': wcagA,
|
|
315
|
+
tabindex: wcagA,
|
|
316
|
+
'button-name': wcagA,
|
|
317
|
+
'document-title': wcagA,
|
|
318
|
+
'heading_empty': wcagA,
|
|
319
|
+
'button_empty': wcagA,
|
|
320
|
+
'aria_reference_broken': wcagA,
|
|
321
|
+
contrast: ['wcag21aa', 'wcag2aa', 'wcag22aa'],
|
|
322
|
+
// ACE-style rule IDs (common patterns)
|
|
323
|
+
'RPT_Header_HasContent': wcagA,
|
|
324
|
+
'RPT_Button_AccessibleName': wcagA,
|
|
325
|
+
'RPT_Label_FormControls': wcagA,
|
|
326
|
+
'RPT_Elem_UniqueId': wcagA,
|
|
327
|
+
'IBMA_Color_Contrast_WCAG2AA': wcagAA,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Check if a rule matches any of the specified tags
|
|
332
|
+
*/
|
|
333
|
+
ruleMatchesTags(ruleId, ruleData, tags) {
|
|
334
|
+
if (!tags || tags.length === 0)
|
|
335
|
+
return true;
|
|
336
|
+
if (ruleData.tags && Array.isArray(ruleData.tags)) {
|
|
337
|
+
return ruleData.tags.some((tag) => tags.includes(tag));
|
|
338
|
+
}
|
|
339
|
+
const mapping = this.getRuleTagMapping();
|
|
340
|
+
const ruleTags = mapping[ruleId];
|
|
341
|
+
if (ruleTags?.length) {
|
|
342
|
+
return ruleTags.some((tag) => tags.includes(tag));
|
|
343
|
+
}
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Filter accessibility results by tags
|
|
348
|
+
*/
|
|
349
|
+
filterByTags(results, tags) {
|
|
350
|
+
if (!tags || tags.length === 0)
|
|
351
|
+
return results;
|
|
352
|
+
const filteredViolations = {};
|
|
353
|
+
Object.entries(results.violations).forEach(([categoryKey, category]) => {
|
|
354
|
+
if (!category?.items)
|
|
355
|
+
return;
|
|
356
|
+
const filteredItems = {};
|
|
357
|
+
Object.entries(category.items).forEach(([ruleId, ruleData]) => {
|
|
358
|
+
if (this.ruleMatchesTags(ruleId, ruleData, tags)) {
|
|
359
|
+
filteredItems[ruleId] = ruleData;
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
if (Object.keys(filteredItems).length > 0) {
|
|
363
|
+
const categoryCount = Object.values(filteredItems).reduce((total, item) => total + (item.count || 0), 0);
|
|
364
|
+
filteredViolations[categoryKey] = {
|
|
365
|
+
count: categoryCount,
|
|
366
|
+
items: filteredItems,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
return { ...results, violations: filteredViolations };
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Run accessibility test on a URL
|
|
374
|
+
*/
|
|
375
|
+
async run(page, config) {
|
|
376
|
+
const { url, waitForLoad = 'networkidle', timeout = 30000, tags, engine = 'axe', applyTagFilter = false, } = config;
|
|
377
|
+
try {
|
|
378
|
+
if (engine === 'ace') {
|
|
379
|
+
debugLog(`Running IBM Equal Access (ACE) analysis on ${url}...`);
|
|
380
|
+
const accessibilityResults = await this.runACEAnalysis(url, tags);
|
|
381
|
+
const originalIssueCount = this.countTotalIssues(accessibilityResults.violations);
|
|
382
|
+
let filteredResults;
|
|
383
|
+
let appliedFilters;
|
|
384
|
+
if (applyTagFilter && tags && tags.length > 0) {
|
|
385
|
+
filteredResults = this.filterByTags(accessibilityResults, tags);
|
|
386
|
+
appliedFilters = { tags, originalIssueCount };
|
|
387
|
+
debugLog(`Filtered results: ${originalIssueCount} -> ${this.countTotalIssues(filteredResults.violations)} issues`);
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
accessibilityResults,
|
|
391
|
+
filteredResults,
|
|
392
|
+
appliedFilters,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
await this.navigateAndWait(page, url, waitForLoad, timeout);
|
|
396
|
+
debugLog(`Running axe-core analysis on ${url}...`);
|
|
397
|
+
const accessibilityResults = await this.runAccessibilityAnalysis(page, url, 'axe', tags);
|
|
398
|
+
const originalIssueCount = this.countTotalIssues(accessibilityResults.violations);
|
|
399
|
+
let filteredResults;
|
|
400
|
+
let appliedFilters;
|
|
401
|
+
if (applyTagFilter && tags && tags.length > 0) {
|
|
402
|
+
filteredResults = this.filterByTags(accessibilityResults, tags);
|
|
403
|
+
appliedFilters = { tags, originalIssueCount };
|
|
404
|
+
debugLog(`Filtered results: ${originalIssueCount} -> ${this.countTotalIssues(filteredResults.violations)} issues (tags: ${tags.join(', ')})`);
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
accessibilityResults,
|
|
408
|
+
filteredResults,
|
|
409
|
+
appliedFilters,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
console.error('Error running accessibility test:', error);
|
|
414
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
415
|
+
throw new Error(`Accessibility test failed for ${url}: ${errorMessage}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
//# sourceMappingURL=accessibility-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility-runner.js","sourceRoot":"","sources":["../../src/core/accessibility-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAYnC;;GAEG;AACH,SAAS,QAAQ,CAAC,GAAG,IAAe;IAClC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;AACxB,CAAC;AAwCD,4CAA4C;AAC5C,MAAM,gBAAgB,GAAG;IACvB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,UAAU;IACV,eAAe;CAChB,CAAA;AAoDD;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAG9B;QACE,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAClD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QACpD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,CAAC,CAAA;IAC/E,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAC3B,IAAU,EACV,GAAW,EACX,eAA6B,aAAa,EAC1C,UAAkB,KAAK;QAEvB,QAAQ,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAA;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE5B,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACnB,SAAS,EAAE,kBAAkB;YAC7B,OAAO;SACR,CAAC,CAAA;QACF,QAAQ,CAAC,yBAAyB,CAAC,CAAA;QAEnC,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAA;QACxD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,QAAQ,YAAY,EAAE,CAAC;oBACrB,KAAK,aAAa;wBAChB,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE;4BACzC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC;yBACvC,CAAC,CAAA;wBACF,QAAQ,CAAC,gCAAgC,CAAC,CAAA;wBAC1C,MAAK;oBACP,KAAK,MAAM;wBACT,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE;4BAClC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC;yBACvC,CAAC,CAAA;wBACF,QAAQ,CAAC,yBAAyB,CAAC,CAAA;wBACnC,MAAK;oBACP,KAAK,kBAAkB;wBACrB,QAAQ,CAAC,oBAAoB,CAAC,CAAA;wBAC9B,MAAK;gBACT,CAAC;gBACD,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAA;gBACxD,IAAI,aAAa,GAAG,IAAI,EAAE,CAAC;oBACzB,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,eAAe,CACxB,GAAG,EAAE,CACH,CAAC,OAAO,QAAQ,KAAK,WAAW;4BAC9B,QAAQ,CAAC,UAAU,KAAK,UAAU;4BAClC,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAY,EACtC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAC3C,CAAA;wBACD,QAAQ,CAAC,cAAc,CAAC,CAAA;oBAC1B,CAAC;oBAAC,MAAM,CAAC;wBACP,QAAQ,CAAC,qDAAqD,CAAC,CAAA;oBACjE,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,qDAAqD,CAAC,CAAA;YACjE,CAAC;QACH,CAAC;QAED,QAAQ,CACN,6BAA6B,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,6CAA6C,CACjG,CAAA;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAAyB;QAC/C,MAAM,OAAO,GACX,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAA;QAC7D,OAAO,EAAE,OAAO,EAAE,CAAA;IACpB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAC1B,IAAU,EACV,IAAyB;QAEzB,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAC7C,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAE/C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CACnC,CAAC,OAA8B,EAAE,EAAE;YACjC,OAAO,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtD,IAAI,OAAQ,MAAiF,CAAC,GAAG,EAAE,GAAG,KAAK,UAAU,EAAE,CAAC;oBACtH,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAA;oBAC7C,OAAM;gBACR,CAAC;gBACD,CAAC;gBAAC,MAAgF;qBAC/E,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;qBAChB,IAAI,CAAC,OAAO,CAAC;qBACb,KAAK,CAAC,MAAM,CAAC,CAAA;YAClB,CAAC,CAAC,CAAA;QACJ,CAAC,EACD,UAAU,CACX,CAAA;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;OAEG;IACK,yBAAyB,CAC/B,SAA0B,EAC1B,GAAW,EACX,eAMC;QAED,MAAM,UAAU,GAAwB,EAAE,CAAA;QAC1C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAE1C,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAe,EAAE,EAAE;YAC/C,MAAM,WAAW,GACf,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAC7C,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACrC,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,OAAO,CAAA;YAEb,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7B,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;YACnD,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CACvC,CAAA;YACD,MAAM,OAAO,GAAc,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrD,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;gBACnD,QAAQ,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;aAClC,CAAC,CAAC,CAAA;YAEH,kEAAkE;YAClE,sDAAsD;YACtD,wFAAwF;YACxF,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,CAAA;YACzC,MAAM,MAAM,GACV,SAAS,KAAK,UAAU,IAAI,SAAS,KAAK,SAAS;gBACjD,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,SAAS,KAAK,UAAU;oBACxB,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,gBAAgB,CAAA;YAExB,MAAM,QAAQ,GAA0B;gBACtC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;gBAC3B,MAAM;gBACN,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE;gBAC5C,OAAO;gBACP,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;gBAClB,MAAM;aACP,CAAA;YAED,UAAU,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAA;YAC9C,UAAU,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAA;QACjD,CAAC,CAAC,CAAA;QAEF,OAAO;YACL,GAAG;YACH,SAAS;YACT,UAAU,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE;YAChD,UAAU,EAAE,EAAE,IAAI,EAAE,mCAAmC,EAAE;YACzD,eAAe;YACf,UAAU;SACX,CAAA;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAC1B,GAAW,EACX,KAA0B;QAE1B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;QACtD,MAAM,KAAK,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;QAEnC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAA8B,CAAA;YACpD,OAAO,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACpD,CAAC;gBAAS,CAAC;YACT,MAAM,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAA;QAC1B,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACK,gBAAgB,CAAC,KAAa;QACpC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QAC7B,IAAI,CAAC,KAAK,WAAW;YAAE,OAAO,WAAW,CAAA;QACzC,IAAI,CAAC,KAAK,oBAAoB,IAAI,CAAC,KAAK,yBAAyB,IAAI,CAAC,KAAK,QAAQ;YAAE,OAAO,cAAc,CAAA;QAC1G,IAAI,CAAC,KAAK,gBAAgB;YAAE,OAAO,gBAAgB,CAAA;QACnD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,CAAkC;QACnD,IAAI,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;QAChB,MAAM,CAAC,GAAiE;YACtE,SAAS,EAAE,CAAC;YACZ,cAAc,EAAE,CAAC;YACjB,cAAc,EAAE,CAAC;YACjB,KAAK,EAAE,CAAC;SACT,CAAA;QACD,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED;;;OAGG;IACK,yBAAyB,CAC/B,MAAiB,EACjB,GAAW;QAEX,MAAM,UAAU,GAAwB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAA;QAC1E,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAE1C,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAC1C,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,KAAK,KAAK,WAAW;YACvB,CAAC,CAAC,KAAK,KAAK,oBAAoB;YAChC,CAAC,CAAC,KAAK,KAAK,gBAAgB;YAC5B,CAAC,CAAC,KAAK,KAAK,yBAAyB,CACxC,CAAA;QAED,cAAc,CAAC,OAAO,CAAC,CAAC,IAAmB,EAAE,EAAE;YAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACpD,IAAI,CAAC,UAAU,CAAC,KAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrC,UAAU,CAAC,KAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;oBAChC,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,EAAE;oBACV,WAAW,EAAE,IAAI,CAAC,OAAO;oBACzB,OAAO,EAAE,EAAE;oBACX,IAAI,EAAE,EAAE;oBACR,MAAM,EAAE,UAAU;iBACnB,CAAA;YACH,CAAC;YAED,MAAM,IAAI,GAAG,UAAU,CAAC,KAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAC5C,IAAI,CAAC,KAAK,IAAI,CAAC,CAAA;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAA;YACrC,IAAI,CAAC,OAAQ,CAAC,IAAI,CAAC;gBACjB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;gBAC/D,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;aACxB,CAAC,CAAA;YACF,IAAI,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7E,IAAI,CAAC,MAAM,GAAG,UAAU,CAAA;YAC1B,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACtD,UAAU,CAAC,KAAM,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAA;QACvC,CAAC,CAAC,CAAA;QAEF,OAAO;YACL,GAAG;YACH,SAAS;YACT,UAAU,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK,EAAE;YACxD,UAAU,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE;YAC7C,eAAe,EAAE;gBACf,SAAS,EAAE,uBAAuB;gBAClC,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,GAAG;aAClB;YACD,UAAU;SACX,CAAA;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB,CACpC,IAAU,EACV,GAAW,EACX,MAA2B,EAC3B,IAAyB;QAEzB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACvC,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;QACpC,MAAM,eAAe,GAAG;YACtB,SAAS,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC;YACzD,WAAW,EAAE,QAAQ,EAAE,KAAK,IAAI,IAAI;YACpC,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG;YACrC,eAAe,EAAE,MAAM,IAAI;iBACxB,QAAQ,CAAC,GAAG,EAAE,CAAE,MAA8C,CAAC,WAAW,EAAE,IAAI,CAAC;iBACjF,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;YACzB,gBAAgB,EAAE,MAAM,IAAI;iBACzB,QAAQ,CAAC,GAAG,EAAE,CAAE,MAA+C,CAAC,WAAW,EAAE,KAAK,CAAC;iBACnF,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;SAC1B,CAAA;QAED,OAAO,IAAI,CAAC,yBAAyB,CAAC,SAAS,EAAE,GAAG,EAAE,eAAe,CAAC,CAAA;IACxE,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,UAA+B;QACtD,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,QAA2C,EAAE,EAAE;YAChF,IAAI,QAAQ,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC/B,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAA;YACzB,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;;OAIG;IACK,iBAAiB;QACvB,MAAM,KAAK,GAAuB;YAChC,QAAQ;YACR,SAAS;YACT,SAAS;SACV,CAAA;QACD,MAAM,MAAM,GAAuB;YACjC,SAAS;YACT,UAAU;YACV,UAAU;SACX,CAAA;QACD,OAAO;YACL,gBAAgB,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;YACrD,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,KAAK;YACZ,eAAe,EAAE,KAAK;YACtB,eAAe,EAAE,KAAK;YACtB,WAAW,EAAE,KAAK;YAClB,uBAAuB,EAAE,KAAK;YAC9B,QAAQ,EAAE,KAAK;YACf,aAAa,EAAE,KAAK;YACpB,gBAAgB,EAAE,KAAK;YACvB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,uBAAuB,EAAE,KAAK;YAC9B,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;YAC7C,uCAAuC;YACvC,uBAAuB,EAAE,KAAK;YAC9B,2BAA2B,EAAE,KAAK;YAClC,wBAAwB,EAAE,KAAK;YAC/B,mBAAmB,EAAE,KAAK;YAC1B,6BAA6B,EAAE,MAAM;SACtC,CAAA;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CACrB,MAAc,EACd,QAA+B,EAC/B,IAAwB;QAExB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QAC3C,IAAI,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAuB,CAAC,CAAC,CAAA;QAC5E,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAA;QACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAChC,IAAI,QAAQ,EAAE,MAAM,EAAE,CAAC;YACrB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;QACnD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;OAEG;IACK,YAAY,CAClB,OAA6B,EAC7B,IAAwB;QAExB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAA;QAE9C,MAAM,kBAAkB,GAAwB,EAAE,CAAA;QAElD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;YACrE,IAAI,CAAC,QAAQ,EAAE,KAAK;gBAAE,OAAM;YAE5B,MAAM,aAAa,GAA0C,EAAE,CAAA;YAC/D,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE;gBAC5D,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;oBACjD,aAAa,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAA;gBAClC,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CACvD,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,EAC1C,CAAC,CACF,CAAA;gBACD,kBAAkB,CAAC,WAAW,CAAC,GAAG;oBAChC,KAAK,EAAE,aAAa;oBACpB,KAAK,EAAE,aAAa;iBACrB,CAAA;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAA;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CACP,IAAU,EACV,MAAiC;QAEjC,MAAM,EACJ,GAAG,EACH,WAAW,GAAG,aAAa,EAC3B,OAAO,GAAG,KAAK,EACf,IAAI,EACJ,MAAM,GAAG,KAAK,EACd,cAAc,GAAG,KAAK,GACvB,GAAG,MAAM,CAAA;QAEV,IAAI,CAAC;YACH,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,QAAQ,CAAC,8CAA8C,GAAG,KAAK,CAAC,CAAA;gBAChE,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;gBACjE,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAA;gBAEjF,IAAI,eAAiD,CAAA;gBACrD,IAAI,cAA2D,CAAA;gBAE/D,IAAI,cAAc,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9C,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAA;oBAC/D,cAAc,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAA;oBAC7C,QAAQ,CACN,qBAAqB,kBAAkB,OAAO,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,UAAU,CAAC,SAAS,CACzG,CAAA;gBACH,CAAC;gBAED,OAAO;oBACL,oBAAoB;oBACpB,eAAe;oBACf,cAAc;iBACf,CAAA;YACH,CAAC;YAED,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;YAC3D,QAAQ,CAAC,gCAAgC,GAAG,KAAK,CAAC,CAAA;YAElD,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAC9D,IAAI,EACJ,GAAG,EACH,KAAK,EACL,IAAI,CACL,CAAA;YAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAA;YAEjF,IAAI,eAAiD,CAAA;YACrD,IAAI,cAA2D,CAAA;YAE/D,IAAI,cAAc,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAA;gBAC/D,cAAc,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAA;gBAC7C,QAAQ,CACN,qBAAqB,kBAAkB,OAAO,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,UAAU,CAAC,kBAAkB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACpI,CAAA;YACH,CAAC;YAED,OAAO;gBACL,oBAAoB;gBACpB,eAAe;gBACf,cAAc;aACf,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAA;YACzD,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACxD,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,KAAK,YAAY,EAAE,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server configuration from environment variables.
|
|
3
|
+
* Compatible with joe-watkins/accessibility-testing-mcp style config.
|
|
4
|
+
*
|
|
5
|
+
* Configure via MCP config "env" section, e.g.:
|
|
6
|
+
* "env": {
|
|
7
|
+
* "A11Y_ENGINE": "axe",
|
|
8
|
+
* "WCAG_LEVEL": "2.2_AA",
|
|
9
|
+
* "BEST_PRACTICES": "true",
|
|
10
|
+
* "SCREEN_SIZES": "1280x1024,320x640",
|
|
11
|
+
* "HEADLESS_BROWSER": "true"
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
export type WcagLevel = '2.0_A' | '2.0_AA' | '2.0_AAA' | '2.1_A' | '2.1_AA' | '2.1_AAA' | '2.2_A' | '2.2_AA' | '2.2_AAA';
|
|
15
|
+
export type A11yEngine = 'axe' | 'ace';
|
|
16
|
+
export interface ScreenSize {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
label: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ServerConfig {
|
|
22
|
+
engine: A11yEngine;
|
|
23
|
+
wcagLevel: WcagLevel;
|
|
24
|
+
includeBestPractices: boolean;
|
|
25
|
+
screenSizes: ScreenSize[];
|
|
26
|
+
headless: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function loadConfig(): ServerConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Get the current server config (loads from env if not yet loaded).
|
|
31
|
+
*/
|
|
32
|
+
export declare function getConfig(): ServerConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Get axe-core tags for the configured WCAG level and best-practices setting.
|
|
35
|
+
* Used when the tool input does not specify tags.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getAxeTagsFromConfig(): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Get ACE policy name for the configured WCAG level (for accessibility-checker).
|
|
40
|
+
*/
|
|
41
|
+
export declare function getAcePolicyFromConfig(): string;
|
|
42
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,QAAQ,GACR,SAAS,GACT,OAAO,GACP,QAAQ,GACR,SAAS,GACT,OAAO,GACP,QAAQ,GACR,SAAS,CAAA;AAEb,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,CAAA;AAEtC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAyDD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAA;IAClB,SAAS,EAAE,SAAS,CAAA;IACpB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAgED,wBAAgB,UAAU,IAAI,YAAY,CAoBzC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAExC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAO/C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
|