accessibility-server-mcp 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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +762 -0
  3. package/config/wcag-rules.json +252 -0
  4. package/dist/index.d.ts +59 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +437 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/test-manual.d.ts +6 -0
  9. package/dist/test-manual.d.ts.map +1 -0
  10. package/dist/test-manual.js +66 -0
  11. package/dist/test-manual.js.map +1 -0
  12. package/dist/tools/accessibility-tester.d.ts +56 -0
  13. package/dist/tools/accessibility-tester.d.ts.map +1 -0
  14. package/dist/tools/accessibility-tester.js +317 -0
  15. package/dist/tools/accessibility-tester.js.map +1 -0
  16. package/dist/tools/color-contrast.d.ts +49 -0
  17. package/dist/tools/color-contrast.d.ts.map +1 -0
  18. package/dist/tools/color-contrast.js +237 -0
  19. package/dist/tools/color-contrast.js.map +1 -0
  20. package/dist/tools/wcag-validator.d.ts +43 -0
  21. package/dist/tools/wcag-validator.d.ts.map +1 -0
  22. package/dist/tools/wcag-validator.js +249 -0
  23. package/dist/tools/wcag-validator.js.map +1 -0
  24. package/dist/tools/website-accessibility-tester.d.ts +103 -0
  25. package/dist/tools/website-accessibility-tester.d.ts.map +1 -0
  26. package/dist/tools/website-accessibility-tester.js +228 -0
  27. package/dist/tools/website-accessibility-tester.js.map +1 -0
  28. package/dist/types/accessibility.d.ts +172 -0
  29. package/dist/types/accessibility.d.ts.map +1 -0
  30. package/dist/types/accessibility.js +5 -0
  31. package/dist/types/accessibility.js.map +1 -0
  32. package/dist/types/index.d.ts +6 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/dist/types/index.js +8 -0
  35. package/dist/types/index.js.map +1 -0
  36. package/dist/types/mcp.d.ts +70 -0
  37. package/dist/types/mcp.d.ts.map +1 -0
  38. package/dist/types/mcp.js +5 -0
  39. package/dist/types/mcp.js.map +1 -0
  40. package/dist/utils/browser-manager.d.ts +83 -0
  41. package/dist/utils/browser-manager.d.ts.map +1 -0
  42. package/dist/utils/browser-manager.js +292 -0
  43. package/dist/utils/browser-manager.js.map +1 -0
  44. package/dist/utils/index.d.ts +8 -0
  45. package/dist/utils/index.d.ts.map +1 -0
  46. package/dist/utils/index.js +8 -0
  47. package/dist/utils/index.js.map +1 -0
  48. package/dist/utils/logger.d.ts +36 -0
  49. package/dist/utils/logger.d.ts.map +1 -0
  50. package/dist/utils/logger.js +107 -0
  51. package/dist/utils/logger.js.map +1 -0
  52. package/dist/utils/report-generator.d.ts +31 -0
  53. package/dist/utils/report-generator.d.ts.map +1 -0
  54. package/dist/utils/report-generator.js +252 -0
  55. package/dist/utils/report-generator.js.map +1 -0
  56. package/dist/utils/website-crawler.d.ts +66 -0
  57. package/dist/utils/website-crawler.d.ts.map +1 -0
  58. package/dist/utils/website-crawler.js +306 -0
  59. package/dist/utils/website-crawler.js.map +1 -0
  60. package/package.json +80 -0
@@ -0,0 +1,43 @@
1
+ import { WCAGRule, AccessibilityCategory, WCAGLevel, WCAGVersion } from '../types/index.js';
2
+ import type { GetWCAGRulesInput, ToolResponse } from '../types/mcp.js';
3
+ /**
4
+ * WCAG rules validator and information provider
5
+ */
6
+ export declare class WCAGValidator {
7
+ private readonly logger;
8
+ private wcagConfig;
9
+ constructor();
10
+ /**
11
+ * Get WCAG rules based on filters
12
+ */
13
+ getRules(input: GetWCAGRulesInput): Promise<ToolResponse<WCAGRule[]>>;
14
+ /**
15
+ * Load WCAG configuration from file
16
+ */
17
+ private loadWCAGConfig;
18
+ /**
19
+ * Get all available WCAG rules
20
+ */
21
+ private getAllRules;
22
+ /**
23
+ * Apply filters to rules
24
+ */
25
+ private applyFilters;
26
+ /**
27
+ * Search rules by title and description
28
+ */
29
+ private searchRules;
30
+ /**
31
+ * Determine test type based on rule characteristics
32
+ */
33
+ private determineTestType;
34
+ /**
35
+ * Get rules for specific WCAG level and version
36
+ */
37
+ getRulesForLevel(wcagLevel: WCAGLevel, wcagVersion: WCAGVersion): Promise<string[]>;
38
+ /**
39
+ * Get rules for specific category
40
+ */
41
+ getRulesForCategory(category: AccessibilityCategory): Promise<string[]>;
42
+ }
43
+ //# sourceMappingURL=wcag-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wcag-validator.d.ts","sourceRoot":"","sources":["../../src/tools/wcag-validator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAuBvE;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,UAAU,CAA2B;;IAM7C;;OAEG;IACG,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;IA8D3E;;OAEG;YACW,cAAc;IAa5B;;OAEG;IACH,OAAO,CAAC,WAAW;IA2EnB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA8BzF;;OAEG;IACG,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAW9E"}
@@ -0,0 +1,249 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { Logger } from '../utils/index.js';
4
+ /**
5
+ * WCAG rules validator and information provider
6
+ */
7
+ export class WCAGValidator {
8
+ logger;
9
+ wcagConfig = null;
10
+ constructor() {
11
+ this.logger = new Logger().child({ component: 'WCAGValidator' });
12
+ }
13
+ /**
14
+ * Get WCAG rules based on filters
15
+ */
16
+ async getRules(input) {
17
+ const startTime = Date.now();
18
+ try {
19
+ this.logger.info('Getting WCAG rules', { filters: input });
20
+ // Load WCAG configuration if not already loaded
21
+ if (!this.wcagConfig) {
22
+ await this.loadWCAGConfig();
23
+ }
24
+ if (!this.wcagConfig) {
25
+ throw new Error('Failed to load WCAG configuration');
26
+ }
27
+ // Get all available rules
28
+ const allRules = this.getAllRules();
29
+ // Apply filters
30
+ let filteredRules = this.applyFilters(allRules, input);
31
+ // Apply search if provided
32
+ if (input.search) {
33
+ filteredRules = this.searchRules(filteredRules, input.search);
34
+ }
35
+ // Apply limit
36
+ if (input.limit && filteredRules.length > input.limit) {
37
+ filteredRules = filteredRules.slice(0, input.limit);
38
+ }
39
+ this.logger.info('WCAG rules retrieved', {
40
+ totalRules: allRules.length,
41
+ filteredRules: filteredRules.length
42
+ });
43
+ return {
44
+ success: true,
45
+ data: filteredRules,
46
+ processingTime: Date.now() - startTime,
47
+ timestamp: new Date().toISOString()
48
+ };
49
+ }
50
+ catch (error) {
51
+ this.logger.error('Error getting WCAG rules', error instanceof Error ? error : new Error(String(error)));
52
+ return {
53
+ success: false,
54
+ error: {
55
+ type: 'internal',
56
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
57
+ details: error instanceof Error ? {
58
+ name: error.name,
59
+ stack: error.stack
60
+ } : undefined
61
+ },
62
+ processingTime: Date.now() - startTime,
63
+ timestamp: new Date().toISOString()
64
+ };
65
+ }
66
+ }
67
+ /**
68
+ * Load WCAG configuration from file
69
+ */
70
+ async loadWCAGConfig() {
71
+ try {
72
+ const configPath = path.join(process.cwd(), 'config', 'wcag-rules.json');
73
+ const configData = await fs.readFile(configPath, 'utf8');
74
+ this.wcagConfig = JSON.parse(configData);
75
+ this.logger.debug('WCAG configuration loaded successfully');
76
+ }
77
+ catch (error) {
78
+ this.logger.error('Failed to load WCAG configuration', error instanceof Error ? error : new Error(String(error)));
79
+ throw new Error('Could not load WCAG rules configuration');
80
+ }
81
+ }
82
+ /**
83
+ * Get all available WCAG rules
84
+ */
85
+ getAllRules() {
86
+ if (!this.wcagConfig) {
87
+ return [];
88
+ }
89
+ const rules = [];
90
+ const { wcagRules, categories, ruleDescriptions } = this.wcagConfig;
91
+ // Collect all unique rule IDs
92
+ const allRuleIds = new Set();
93
+ Object.values(wcagRules).forEach(versionRules => {
94
+ Object.values(versionRules.level).forEach(levelRules => {
95
+ levelRules.forEach(ruleId => allRuleIds.add(ruleId));
96
+ });
97
+ });
98
+ // Create WCAGRule objects
99
+ allRuleIds.forEach(ruleId => {
100
+ const description = ruleDescriptions[ruleId];
101
+ if (!description) {
102
+ this.logger.warn(`No description found for rule: ${ruleId}`);
103
+ return;
104
+ }
105
+ // Determine which versions and levels this rule applies to
106
+ const versions = [];
107
+ let level = 'A';
108
+ Object.entries(wcagRules).forEach(([version, versionData]) => {
109
+ Object.entries(versionData.level).forEach(([lvl, rules]) => {
110
+ if (rules.includes(ruleId)) {
111
+ if (!versions.includes(version)) {
112
+ versions.push(version);
113
+ }
114
+ // Use the highest level found
115
+ if (lvl === 'AAA' || (lvl === 'AA' && level === 'A')) {
116
+ level = lvl;
117
+ }
118
+ }
119
+ });
120
+ });
121
+ // Determine categories
122
+ const ruleCategories = [];
123
+ Object.entries(categories).forEach(([category, categoryRules]) => {
124
+ if (categoryRules.includes(ruleId)) {
125
+ ruleCategories.push(category);
126
+ }
127
+ });
128
+ // Generate tags
129
+ const tags = [
130
+ ...ruleCategories,
131
+ ...versions.map(v => `wcag${v.replace('.', '')}`),
132
+ `level-${level.toLowerCase()}`
133
+ ];
134
+ rules.push({
135
+ id: ruleId,
136
+ title: description.title,
137
+ description: description.description,
138
+ level,
139
+ versions,
140
+ categories: ruleCategories,
141
+ tags,
142
+ wcagUrl: description.helpUrl,
143
+ testType: this.determineTestType(ruleId),
144
+ successCriteria: description.successCriteria
145
+ });
146
+ });
147
+ return rules.sort((a, b) => a.id.localeCompare(b.id));
148
+ }
149
+ /**
150
+ * Apply filters to rules
151
+ */
152
+ applyFilters(rules, filters) {
153
+ let filtered = [...rules];
154
+ // Filter by WCAG level
155
+ if (filters.wcagLevel) {
156
+ filtered = filtered.filter(rule => {
157
+ switch (filters.wcagLevel) {
158
+ case 'A':
159
+ return rule.level === 'A';
160
+ case 'AA':
161
+ return ['A', 'AA'].includes(rule.level);
162
+ case 'AAA':
163
+ return ['A', 'AA', 'AAA'].includes(rule.level);
164
+ default:
165
+ return true;
166
+ }
167
+ });
168
+ }
169
+ // Filter by category
170
+ if (filters.category) {
171
+ filtered = filtered.filter(rule => rule.categories.some(cat => cat.toLowerCase().includes(filters.category.toLowerCase())));
172
+ }
173
+ return filtered;
174
+ }
175
+ /**
176
+ * Search rules by title and description
177
+ */
178
+ searchRules(rules, searchTerm) {
179
+ const lowercaseSearch = searchTerm.toLowerCase();
180
+ return rules.filter(rule => rule.title.toLowerCase().includes(lowercaseSearch) ||
181
+ rule.description.toLowerCase().includes(lowercaseSearch) ||
182
+ rule.id.toLowerCase().includes(lowercaseSearch) ||
183
+ rule.categories.some(cat => cat.toLowerCase().includes(lowercaseSearch)) ||
184
+ rule.tags.some(tag => tag.toLowerCase().includes(lowercaseSearch)));
185
+ }
186
+ /**
187
+ * Determine test type based on rule characteristics
188
+ */
189
+ determineTestType(ruleId) {
190
+ // Rules that are typically automated
191
+ const automatedRules = [
192
+ 'color-contrast', 'image-alt', 'label', 'html-has-lang',
193
+ 'aria-allowed-attr', 'aria-required-attr', 'aria-valid-attr-value',
194
+ 'button-name', 'link-name', 'heading-order'
195
+ ];
196
+ // Rules that require manual testing
197
+ const manualRules = [
198
+ 'focus-order-semantics', 'page-has-heading-one', 'region',
199
+ 'target-size', 'orientation-lock'
200
+ ];
201
+ if (automatedRules.some(rule => ruleId.includes(rule))) {
202
+ return 'automated';
203
+ }
204
+ if (manualRules.some(rule => ruleId.includes(rule))) {
205
+ return 'manual';
206
+ }
207
+ return 'semi-automated';
208
+ }
209
+ /**
210
+ * Get rules for specific WCAG level and version
211
+ */
212
+ async getRulesForLevel(wcagLevel, wcagVersion) {
213
+ if (!this.wcagConfig) {
214
+ await this.loadWCAGConfig();
215
+ }
216
+ if (!this.wcagConfig) {
217
+ return [];
218
+ }
219
+ const versionRules = this.wcagConfig.wcagRules[wcagVersion];
220
+ if (!versionRules) {
221
+ return [];
222
+ }
223
+ const rules = [];
224
+ // Add rules for requested level and below
225
+ if (wcagLevel === 'A' || wcagLevel === 'AA' || wcagLevel === 'AAA') {
226
+ rules.push(...(versionRules.level.A || []));
227
+ }
228
+ if (wcagLevel === 'AA' || wcagLevel === 'AAA') {
229
+ rules.push(...(versionRules.level.AA || []));
230
+ }
231
+ if (wcagLevel === 'AAA') {
232
+ rules.push(...(versionRules.level.AAA || []));
233
+ }
234
+ return [...new Set(rules)]; // Remove duplicates
235
+ }
236
+ /**
237
+ * Get rules for specific category
238
+ */
239
+ async getRulesForCategory(category) {
240
+ if (!this.wcagConfig) {
241
+ await this.loadWCAGConfig();
242
+ }
243
+ if (!this.wcagConfig) {
244
+ return [];
245
+ }
246
+ return this.wcagConfig.categories[category] || [];
247
+ }
248
+ }
249
+ //# sourceMappingURL=wcag-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wcag-validator.js","sourceRoot":"","sources":["../../src/tools/wcag-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import { CrawlOptions, CrawlResult } from '../utils/website-crawler.js';
2
+ import { BrowserManager } from '../utils/browser-manager.js';
3
+ import { AccessibilityTestResult, WCAGLevel, ViolationSeverity } from '../types/accessibility.js';
4
+ export interface WebsiteTestOptions extends CrawlOptions {
5
+ /** WCAG level to test against */
6
+ wcagLevel?: WCAGLevel;
7
+ /** Whether to perform full analysis */
8
+ fullAnalysis?: boolean;
9
+ /** Maximum concurrent tests */
10
+ concurrency?: number;
11
+ /** Whether to continue testing if individual pages fail */
12
+ continueOnError?: boolean;
13
+ }
14
+ export interface PageTestResult {
15
+ /** URL that was tested */
16
+ url: string;
17
+ /** Whether the test was successful */
18
+ success: boolean;
19
+ /** Test result if successful */
20
+ result?: AccessibilityTestResult;
21
+ /** Error message if failed */
22
+ error?: string;
23
+ /** Test duration in milliseconds */
24
+ duration: number;
25
+ }
26
+ export interface WebsiteTestResult {
27
+ /** Website base URL */
28
+ baseUrl: string;
29
+ /** Timestamp when testing started */
30
+ timestamp: string;
31
+ /** Total duration of the entire test */
32
+ totalDuration: number;
33
+ /** Crawl results */
34
+ crawlResult: CrawlResult;
35
+ /** Results for each page tested */
36
+ pageResults: PageTestResult[];
37
+ /** Aggregated summary across all pages */
38
+ summary: WebsiteSummary;
39
+ /** Configuration used for testing */
40
+ testOptions: WebsiteTestOptions;
41
+ }
42
+ export interface WebsiteSummary {
43
+ /** Total pages tested successfully */
44
+ totalPages: number;
45
+ /** Total pages that failed to test */
46
+ failedPages: number;
47
+ /** Total violations across all pages */
48
+ totalViolations: number;
49
+ /** Violations by severity across all pages */
50
+ violationsBySeverity: Record<ViolationSeverity, number>;
51
+ /** Most common violations across the site */
52
+ commonViolations: Array<{
53
+ id: string;
54
+ description: string;
55
+ count: number;
56
+ affectedPages: number;
57
+ impact: ViolationSeverity;
58
+ }>;
59
+ /** Pages with the most violations */
60
+ problematicPages: Array<{
61
+ url: string;
62
+ violationCount: number;
63
+ score: number;
64
+ }>;
65
+ /** Overall site accessibility score */
66
+ overallScore: number;
67
+ /** WCAG compliance status */
68
+ compliance: Record<WCAGLevel, boolean>;
69
+ /** Performance metrics */
70
+ performance: {
71
+ averagePageTestTime: number;
72
+ crawlTime: number;
73
+ testTime: number;
74
+ };
75
+ }
76
+ export declare class WebsiteAccessibilityTester {
77
+ private readonly logger;
78
+ private readonly browserManager;
79
+ private readonly crawler;
80
+ private readonly accessibilityTester;
81
+ constructor(browserManager: BrowserManager);
82
+ /**
83
+ * Test accessibility for an entire website
84
+ */
85
+ testWebsite(baseUrl: string, options?: WebsiteTestOptions): Promise<WebsiteTestResult>;
86
+ /**
87
+ * Test multiple pages with controlled concurrency
88
+ */
89
+ private testPages;
90
+ /**
91
+ * Test a single page for accessibility
92
+ */
93
+ private testSinglePage;
94
+ /**
95
+ * Generate aggregated website summary from individual page results
96
+ */
97
+ private generateWebsiteSummary;
98
+ /**
99
+ * Split array into chunks of specified size
100
+ */
101
+ private chunkArray;
102
+ }
103
+ //# sourceMappingURL=website-accessibility-tester.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-accessibility-tester.d.ts","sourceRoot":"","sources":["../../src/tools/website-accessibility-tester.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ import { AccessibilityTester } from './accessibility-tester.js';
2
+ import { WebsiteCrawler } from '../utils/website-crawler.js';
3
+ import { Logger } from '../utils/logger.js';
4
+ export class WebsiteAccessibilityTester {
5
+ logger;
6
+ browserManager;
7
+ crawler;
8
+ accessibilityTester;
9
+ constructor(browserManager) {
10
+ this.logger = new Logger().child({ component: 'WebsiteAccessibilityTester' });
11
+ this.browserManager = browserManager;
12
+ this.crawler = new WebsiteCrawler(browserManager);
13
+ this.accessibilityTester = new AccessibilityTester(browserManager);
14
+ }
15
+ /**
16
+ * Test accessibility for an entire website
17
+ */
18
+ async testWebsite(baseUrl, options = {}) {
19
+ const startTime = Date.now();
20
+ const { wcagLevel = 'AA', fullAnalysis = false, concurrency = 3, continueOnError = true, ...crawlOptions } = options;
21
+ this.logger.info('Starting website accessibility test', {
22
+ baseUrl,
23
+ wcagLevel,
24
+ fullAnalysis,
25
+ concurrency
26
+ });
27
+ try {
28
+ // Step 1: Crawl the website to discover pages
29
+ this.logger.info('Crawling website to discover pages');
30
+ const crawlResult = await this.crawler.crawlWebsite(baseUrl, crawlOptions);
31
+ this.logger.info(`Discovered ${crawlResult.urls.length} pages to test`);
32
+ // Step 2: Test each discovered page
33
+ const testStartTime = Date.now();
34
+ const pageResults = await this.testPages(crawlResult.urls, wcagLevel, fullAnalysis, concurrency, continueOnError);
35
+ const testDuration = Date.now() - testStartTime;
36
+ // Step 3: Generate aggregated summary
37
+ const summary = this.generateWebsiteSummary(pageResults, crawlResult.crawlDuration, testDuration);
38
+ const totalDuration = Date.now() - startTime;
39
+ const result = {
40
+ baseUrl,
41
+ timestamp: new Date().toISOString(),
42
+ totalDuration,
43
+ crawlResult,
44
+ pageResults,
45
+ summary,
46
+ testOptions: options
47
+ };
48
+ this.logger.info('Website accessibility test completed', {
49
+ totalPages: summary.totalPages,
50
+ failedPages: summary.failedPages,
51
+ totalViolations: summary.totalViolations,
52
+ overallScore: summary.overallScore,
53
+ duration: totalDuration
54
+ });
55
+ return result;
56
+ }
57
+ catch (error) {
58
+ this.logger.error('Website accessibility test failed', error instanceof Error ? error : new Error(String(error)));
59
+ throw error;
60
+ }
61
+ }
62
+ /**
63
+ * Test multiple pages with controlled concurrency
64
+ */
65
+ async testPages(urls, wcagLevel, fullAnalysis, concurrency, continueOnError) {
66
+ const results = [];
67
+ const chunks = this.chunkArray(urls, concurrency);
68
+ for (let i = 0; i < chunks.length; i++) {
69
+ const chunk = chunks[i];
70
+ if (!chunk)
71
+ continue;
72
+ this.logger.info(`Testing batch ${i + 1}/${chunks.length} (${chunk.length} pages)`);
73
+ const chunkPromises = chunk.map(url => this.testSinglePage(url, wcagLevel, fullAnalysis, continueOnError));
74
+ const chunkResults = await Promise.all(chunkPromises);
75
+ results.push(...chunkResults);
76
+ // Add a small delay between batches to be respectful
77
+ if (i < chunks.length - 1) {
78
+ await new Promise(resolve => setTimeout(resolve, 1000));
79
+ }
80
+ }
81
+ return results;
82
+ }
83
+ /**
84
+ * Test a single page for accessibility
85
+ */
86
+ async testSinglePage(url, wcagLevel, fullAnalysis, continueOnError) {
87
+ const startTime = Date.now();
88
+ try {
89
+ this.logger.debug(`Testing page: ${url}`);
90
+ const result = await this.accessibilityTester.testTarget({
91
+ target: url,
92
+ type: 'url',
93
+ wcagLevel,
94
+ level: fullAnalysis ? 'full' : 'basic'
95
+ });
96
+ return {
97
+ url,
98
+ success: true,
99
+ result,
100
+ duration: Date.now() - startTime
101
+ };
102
+ }
103
+ catch (error) {
104
+ const errorMessage = error instanceof Error ? error.message : String(error);
105
+ this.logger.warn(`Failed to test page: ${url}`, { error: errorMessage });
106
+ if (!continueOnError) {
107
+ throw error;
108
+ }
109
+ return {
110
+ url,
111
+ success: false,
112
+ error: errorMessage,
113
+ duration: Date.now() - startTime
114
+ };
115
+ }
116
+ }
117
+ /**
118
+ * Generate aggregated website summary from individual page results
119
+ */
120
+ generateWebsiteSummary(pageResults, crawlTime, testTime) {
121
+ const successfulResults = pageResults.filter(r => r.success && r.result);
122
+ const failedResults = pageResults.filter(r => !r.success);
123
+ // Aggregate violations
124
+ const allViolations = [];
125
+ const violationsBySeverity = {
126
+ critical: 0,
127
+ serious: 0,
128
+ moderate: 0,
129
+ minor: 0
130
+ };
131
+ let totalScore = 0;
132
+ const pageScores = [];
133
+ for (const pageResult of successfulResults) {
134
+ if (pageResult.result) {
135
+ allViolations.push(...pageResult.result.violations);
136
+ // Aggregate severity counts
137
+ for (const violation of pageResult.result.violations) {
138
+ violationsBySeverity[violation.impact]++;
139
+ }
140
+ totalScore += pageResult.result.summary.score;
141
+ pageScores.push({
142
+ url: pageResult.url,
143
+ score: pageResult.result.summary.score,
144
+ violationCount: pageResult.result.violations.length
145
+ });
146
+ }
147
+ }
148
+ // Calculate common violations
149
+ const violationCounts = new Map();
150
+ for (const pageResult of successfulResults) {
151
+ if (pageResult.result) {
152
+ for (const violation of pageResult.result.violations) {
153
+ const existing = violationCounts.get(violation.id);
154
+ if (existing) {
155
+ existing.count++;
156
+ existing.affectedPages.add(pageResult.url);
157
+ }
158
+ else {
159
+ violationCounts.set(violation.id, {
160
+ id: violation.id,
161
+ description: violation.description,
162
+ count: 1,
163
+ affectedPages: new Set([pageResult.url]),
164
+ impact: violation.impact
165
+ });
166
+ }
167
+ }
168
+ }
169
+ }
170
+ const commonViolations = Array.from(violationCounts.values())
171
+ .map(v => ({
172
+ id: v.id,
173
+ description: v.description,
174
+ count: v.count,
175
+ affectedPages: v.affectedPages.size,
176
+ impact: v.impact
177
+ }))
178
+ .sort((a, b) => b.count - a.count)
179
+ .slice(0, 10);
180
+ // Find most problematic pages
181
+ const problematicPages = pageScores
182
+ .sort((a, b) => b.violationCount - a.violationCount || a.score - b.score)
183
+ .slice(0, 10);
184
+ // Calculate overall score
185
+ const overallScore = successfulResults.length > 0 ? totalScore / successfulResults.length : 0;
186
+ // Calculate compliance
187
+ const compliance = {
188
+ A: true,
189
+ AA: true,
190
+ AAA: true
191
+ };
192
+ for (const pageResult of successfulResults) {
193
+ if (pageResult.result) {
194
+ const pageCompliance = pageResult.result.summary.compliance;
195
+ compliance.A = compliance.A && pageCompliance.A;
196
+ compliance.AA = compliance.AA && pageCompliance.AA;
197
+ compliance.AAA = compliance.AAA && pageCompliance.AAA;
198
+ }
199
+ }
200
+ return {
201
+ totalPages: successfulResults.length,
202
+ failedPages: failedResults.length,
203
+ totalViolations: allViolations.length,
204
+ violationsBySeverity,
205
+ commonViolations,
206
+ problematicPages,
207
+ overallScore: Math.round(overallScore * 100) / 100,
208
+ compliance,
209
+ performance: {
210
+ averagePageTestTime: pageResults.length > 0 ?
211
+ pageResults.reduce((sum, r) => sum + r.duration, 0) / pageResults.length : 0,
212
+ crawlTime,
213
+ testTime
214
+ }
215
+ };
216
+ }
217
+ /**
218
+ * Split array into chunks of specified size
219
+ */
220
+ chunkArray(array, size) {
221
+ const chunks = [];
222
+ for (let i = 0; i < array.length; i += size) {
223
+ chunks.push(array.slice(i, i + size));
224
+ }
225
+ return chunks;
226
+ }
227
+ }
228
+ //# sourceMappingURL=website-accessibility-tester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-accessibility-tester.js","sourceRoot":"","sources":["../../src/tools/website-accessibility-tester.ts"],"names":[],"mappings":"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"}