snap-ally 0.0.2 → 0.1.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -43
- package/dist/A11yHtmlRenderer.d.ts +3 -3
- package/dist/A11yHtmlRenderer.js +31 -18
- package/dist/A11yReportAssets.d.ts +1 -1
- package/dist/A11yReportAssets.js +20 -12
- package/dist/A11yScanner.d.ts +2 -0
- package/dist/A11yScanner.js +63 -14
- package/dist/A11yTimeUtils.d.ts +4 -0
- package/dist/A11yTimeUtils.js +15 -0
- package/dist/SnapAllyReporter.d.ts +1 -0
- package/dist/SnapAllyReporter.js +47 -23
- package/dist/models/index.d.ts +11 -1
- package/dist/templates/accessibility-report.html +205 -1324
- package/dist/templates/execution-summary.html +155 -644
- package/dist/templates/global-report-styles.css +1536 -0
- package/dist/templates/report-app.js +857 -0
- package/dist/templates/test-execution-report.html +151 -536
- package/package.json +6 -7
package/dist/SnapAllyReporter.js
CHANGED
|
@@ -44,6 +44,9 @@ const fs = __importStar(require("fs"));
|
|
|
44
44
|
* Generates an execution summary and detailed reports per test.
|
|
45
45
|
*/
|
|
46
46
|
class SnapAllyReporter {
|
|
47
|
+
printsToStdio() {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
47
50
|
constructor(options = {}) {
|
|
48
51
|
this.testIndex = 0;
|
|
49
52
|
this.assetsManager = new A11yReportAssets_1.A11yReportAssets();
|
|
@@ -62,7 +65,8 @@ class SnapAllyReporter {
|
|
|
62
65
|
groupedResults: {},
|
|
63
66
|
wcagErrors: {},
|
|
64
67
|
totalA11yErrorCount: 0,
|
|
65
|
-
browserSummaries: {}
|
|
68
|
+
browserSummaries: {},
|
|
69
|
+
date: ''
|
|
66
70
|
};
|
|
67
71
|
// Track async tasks to ensure they finish before onEnd
|
|
68
72
|
this.tasks = [];
|
|
@@ -76,7 +80,7 @@ class SnapAllyReporter {
|
|
|
76
80
|
this.tasks.push(this.processTestResult(test, result));
|
|
77
81
|
}
|
|
78
82
|
async processTestResult(test, result) {
|
|
79
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
83
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
80
84
|
this.testIndex++;
|
|
81
85
|
const sanitizedTitle = test.title.replace(/[^a-z0-9]+/gi, '-').toLowerCase();
|
|
82
86
|
const testFolderName = `${this.testIndex}-${sanitizedTitle}`;
|
|
@@ -88,14 +92,14 @@ class SnapAllyReporter {
|
|
|
88
92
|
}
|
|
89
93
|
const tags = test.tags.map(t => t.replace('@', ''));
|
|
90
94
|
const statusIcon = models_1.TestStatusIcon[result.status] || 'help';
|
|
91
|
-
const
|
|
95
|
+
const projectUse = ((_a = test.parent.project()) === null || _a === void 0 ? void 0 : _a.use) || {};
|
|
96
|
+
const browser = ((_b = test.parent.project()) === null || _b === void 0 ? void 0 : _b.name) || projectUse.browserName || projectUse.defaultBrowserType || 'chromium';
|
|
92
97
|
const descAnnotation = test.annotations.find(a => a.type === 'Description');
|
|
93
98
|
const description = (descAnnotation === null || descAnnotation === void 0 ? void 0 : descAnnotation.description) || 'No Description';
|
|
94
|
-
// Prepare steps from annotations
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
.
|
|
98
|
-
.map(a => a.description || 'Step');
|
|
99
|
+
// Prepare steps from actual test.step calls instead of just annotations
|
|
100
|
+
const steps = result.steps
|
|
101
|
+
.filter(s => s.category === 'test.step')
|
|
102
|
+
.map(s => s.title);
|
|
99
103
|
const preConditions = test.annotations
|
|
100
104
|
.filter(a => a.type === 'Pre Condition')
|
|
101
105
|
.map(a => a.description || '');
|
|
@@ -126,6 +130,7 @@ class SnapAllyReporter {
|
|
|
126
130
|
let a11yReportPath = undefined;
|
|
127
131
|
let a11yErrorCount = 0;
|
|
128
132
|
let aggregatedA11yErrors = [];
|
|
133
|
+
let testStatsPageUrl = undefined;
|
|
129
134
|
// Loop through all accessibility scans in this test
|
|
130
135
|
for (const [index, source] of a11yDataSources.entries()) {
|
|
131
136
|
let reportData;
|
|
@@ -173,10 +178,10 @@ class SnapAllyReporter {
|
|
|
173
178
|
// Set the main report path to the LAST one (or maybe first? using last for now)
|
|
174
179
|
a11yReportPath = a11yReportName;
|
|
175
180
|
// Re-apply configuration
|
|
176
|
-
reportData.criticalColor = ((
|
|
177
|
-
reportData.seriousColor = ((
|
|
178
|
-
reportData.moderateColor = ((
|
|
179
|
-
reportData.minorColor = ((
|
|
181
|
+
reportData.criticalColor = ((_c = this.options.colors) === null || _c === void 0 ? void 0 : _c.critical) || '#c92a2a';
|
|
182
|
+
reportData.seriousColor = ((_d = this.options.colors) === null || _d === void 0 ? void 0 : _d.serious) || '#e67700';
|
|
183
|
+
reportData.moderateColor = ((_e = this.options.colors) === null || _e === void 0 ? void 0 : _e.moderate) || '#ca8a04';
|
|
184
|
+
reportData.minorColor = ((_f = this.options.colors) === null || _f === void 0 ? void 0 : _f.minor) || '#0891b2';
|
|
180
185
|
if (this.options.ado) {
|
|
181
186
|
reportData.adoOrganization = this.options.ado.organization || reportData.adoOrganization;
|
|
182
187
|
reportData.adoProject = this.options.ado.project || reportData.adoProject;
|
|
@@ -184,8 +189,24 @@ class SnapAllyReporter {
|
|
|
184
189
|
// Sync video name
|
|
185
190
|
if (video)
|
|
186
191
|
reportData.video = video;
|
|
192
|
+
// Backfill steps from actual test.step calls if annotations were empty
|
|
193
|
+
const filteredSteps = steps.filter(s => !s.includes('Capture A11y screenshot'));
|
|
194
|
+
if (filteredSteps.length > 0) {
|
|
195
|
+
reportData.a11yErrors.forEach(err => {
|
|
196
|
+
err.target.forEach(t => {
|
|
197
|
+
if (!t.steps || t.steps.length === 0) {
|
|
198
|
+
t.steps = filteredSteps;
|
|
199
|
+
t.stepsJson = JSON.stringify(filteredSteps);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
187
204
|
const auditFile = path.join(testResultsFolder, a11yReportName);
|
|
188
205
|
await this.renderer.render('accessibility-report.html', { data: reportData, folderTest: testResultsFolder }, testResultsFolder, auditFile);
|
|
206
|
+
// Capture the first page URL for the testStats if not already set
|
|
207
|
+
if (reportData.pageUrl && !testStatsPageUrl) {
|
|
208
|
+
testStatsPageUrl = reportData.pageUrl;
|
|
209
|
+
}
|
|
189
210
|
// --- 3. Update Browser-Specific Summary (Partial Aggregation) ---
|
|
190
211
|
if (!this.executionSummary.browserSummaries[browser]) {
|
|
191
212
|
this.executionSummary.browserSummaries[browser] = {
|
|
@@ -203,12 +224,12 @@ class SnapAllyReporter {
|
|
|
203
224
|
};
|
|
204
225
|
}
|
|
205
226
|
const bSummary = this.executionSummary.browserSummaries[browser];
|
|
206
|
-
if (reportData.
|
|
227
|
+
if (reportData.a11yErrors && reportData.a11yErrors.length > 0) {
|
|
207
228
|
// Aggregate counts
|
|
208
|
-
const scanErrorCount = reportData.
|
|
229
|
+
const scanErrorCount = reportData.a11yErrors.reduce((sum, err) => sum + (err.total || 0), 0);
|
|
209
230
|
a11yErrorCount += scanErrorCount;
|
|
210
|
-
aggregatedA11yErrors.push(...reportData.
|
|
211
|
-
reportData.
|
|
231
|
+
aggregatedA11yErrors.push(...reportData.a11yErrors);
|
|
232
|
+
reportData.a11yErrors.forEach((err) => {
|
|
212
233
|
const rule = err.id;
|
|
213
234
|
// Local Browser aggregation
|
|
214
235
|
if (!bSummary.wcagErrors[rule]) {
|
|
@@ -275,13 +296,15 @@ class SnapAllyReporter {
|
|
|
275
296
|
steps,
|
|
276
297
|
postConditions,
|
|
277
298
|
statusIcon,
|
|
299
|
+
pageUrl: testStatsPageUrl,
|
|
278
300
|
videoPath: video,
|
|
279
301
|
screenshotPaths: screenshots,
|
|
280
302
|
attachments: allAttachments,
|
|
281
303
|
errors: errorLogs,
|
|
282
304
|
a11yReportPath,
|
|
283
305
|
a11yErrorCount,
|
|
284
|
-
a11yErrors: aggregatedA11yErrors
|
|
306
|
+
a11yErrors: aggregatedA11yErrors,
|
|
307
|
+
colors: this.options.colors
|
|
285
308
|
};
|
|
286
309
|
this.executionSummary.groupedResults[fileGroup].push(testStats);
|
|
287
310
|
// Update summary counts
|
|
@@ -302,14 +325,14 @@ class SnapAllyReporter {
|
|
|
302
325
|
this.executionSummary.total++;
|
|
303
326
|
// Create color config for template
|
|
304
327
|
const colors = {
|
|
305
|
-
critical: ((
|
|
306
|
-
serious: ((
|
|
307
|
-
moderate: ((
|
|
308
|
-
minor: ((
|
|
328
|
+
critical: ((_g = this.options.colors) === null || _g === void 0 ? void 0 : _g.critical) || '#c92a2a',
|
|
329
|
+
serious: ((_h = this.options.colors) === null || _h === void 0 ? void 0 : _h.serious) || '#e67700',
|
|
330
|
+
moderate: ((_j = this.options.colors) === null || _j === void 0 ? void 0 : _j.moderate) || '#ca8a04',
|
|
331
|
+
minor: ((_k = this.options.colors) === null || _k === void 0 ? void 0 : _k.minor) || '#0891b2'
|
|
309
332
|
};
|
|
310
333
|
// Render Step Report
|
|
311
334
|
const indexFile = path.join(testResultsFolder, `execution-${sanitizedTitle}.html`);
|
|
312
|
-
await this.renderer.render('test-execution-report.html', {
|
|
335
|
+
await this.renderer.render('test-execution-report.html', { ...testStats, colors }, testResultsFolder, indexFile);
|
|
313
336
|
}
|
|
314
337
|
async onEnd(result) {
|
|
315
338
|
var _a, _b, _c, _d;
|
|
@@ -319,13 +342,14 @@ class SnapAllyReporter {
|
|
|
319
342
|
this.executionSummary.duration = A11yTimeUtils_1.A11yTimeUtils.formatDuration(result.duration);
|
|
320
343
|
this.executionSummary.status = result.status;
|
|
321
344
|
this.executionSummary.statusIcon = models_1.TestStatusIcon[result.status] || 'help';
|
|
345
|
+
this.executionSummary.date = A11yTimeUtils_1.A11yTimeUtils.formatDate(new Date());
|
|
322
346
|
const colors = {
|
|
323
347
|
critical: ((_a = this.options.colors) === null || _a === void 0 ? void 0 : _a.critical) || '#c92a2a',
|
|
324
348
|
serious: ((_b = this.options.colors) === null || _b === void 0 ? void 0 : _b.serious) || '#e67700',
|
|
325
349
|
moderate: ((_c = this.options.colors) === null || _c === void 0 ? void 0 : _c.moderate) || '#ca8a04',
|
|
326
350
|
minor: ((_d = this.options.colors) === null || _d === void 0 ? void 0 : _d.minor) || '#0891b2'
|
|
327
351
|
};
|
|
328
|
-
await this.renderer.render('execution-summary.html', {
|
|
352
|
+
await this.renderer.render('execution-summary.html', { ...this.executionSummary, colors }, this.outputFolder, summaryFile);
|
|
329
353
|
console.log(`\n[SnapAlly] Reports generated in: ${path.resolve(this.outputFolder)}`);
|
|
330
354
|
}
|
|
331
355
|
}
|
package/dist/models/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export interface ReportData {
|
|
2
2
|
pageKey: string;
|
|
3
|
+
pageUrl?: string;
|
|
3
4
|
accessibilityScore: number;
|
|
4
5
|
video: string;
|
|
5
|
-
|
|
6
|
+
a11yErrors: A11yError[];
|
|
6
7
|
criticalColor: string;
|
|
7
8
|
seriousColor: string;
|
|
8
9
|
moderateColor: string;
|
|
@@ -10,6 +11,7 @@ export interface ReportData {
|
|
|
10
11
|
adoOrganization?: string;
|
|
11
12
|
adoProject?: string;
|
|
12
13
|
adoPat?: string;
|
|
14
|
+
timestamp?: string;
|
|
13
15
|
}
|
|
14
16
|
export interface A11yError {
|
|
15
17
|
id: string;
|
|
@@ -50,6 +52,7 @@ export interface TestResults {
|
|
|
50
52
|
duration: string;
|
|
51
53
|
description: string;
|
|
52
54
|
status: string;
|
|
55
|
+
pageUrl?: string;
|
|
53
56
|
browser: string;
|
|
54
57
|
tags: string[];
|
|
55
58
|
preConditions: string[];
|
|
@@ -67,8 +70,15 @@ export interface TestResults {
|
|
|
67
70
|
executionReportPath?: string;
|
|
68
71
|
a11yErrors?: A11yError[];
|
|
69
72
|
a11yErrorCount?: number;
|
|
73
|
+
colors?: {
|
|
74
|
+
critical?: string;
|
|
75
|
+
serious?: string;
|
|
76
|
+
moderate?: string;
|
|
77
|
+
minor?: string;
|
|
78
|
+
};
|
|
70
79
|
}
|
|
71
80
|
export interface TestSummary {
|
|
81
|
+
date?: string;
|
|
72
82
|
duration: string;
|
|
73
83
|
status: string;
|
|
74
84
|
statusIcon: string;
|