snap-ally 1.0.2 → 1.0.3
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/dist/SnapAllyReporter.js +18 -9
- package/dist/templates/report-app.js +11 -3
- package/package.json +1 -1
package/dist/SnapAllyReporter.js
CHANGED
|
@@ -140,22 +140,31 @@ class SnapAllyReporter {
|
|
|
140
140
|
const videoPath = this.assetsManager.copyVideos(result, testFolder);
|
|
141
141
|
const screenshotPaths = this.assetsManager.copyScreenshots(result, testFolder);
|
|
142
142
|
const attachments = this.assetsManager.copyAllOtherAttachments(result, testFolder);
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
// A single test may call scanA11y/checkAccessibility multiple times (e.g.
|
|
144
|
+
// before and after login), producing one 'A11y' attachment per scan. Read
|
|
145
|
+
// every 'A11y' attachment and merge their violations so findings from all
|
|
146
|
+
// scans are reported — not just the first.
|
|
147
|
+
const a11yAttachments = result.attachments.filter((a) => a.name === 'A11y' && a.body);
|
|
148
|
+
if (a11yAttachments.length === 0 && this.options.verbose) {
|
|
145
149
|
console.warn(`[SnapAlly] A11y attachment missing for test: ${test.title}. Available: ${result.attachments.map(a => a.name).join(', ')}`);
|
|
146
150
|
}
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
const parsedData = [];
|
|
152
|
+
for (const att of a11yAttachments) {
|
|
149
153
|
try {
|
|
150
|
-
|
|
154
|
+
const raw = JSON.parse(att.body.toString());
|
|
155
|
+
// Handle cases where the payload is the direct ReportData or wrapped in a data property
|
|
156
|
+
const data = (raw && typeof raw === 'object' && 'data' in raw ? raw.data : raw);
|
|
157
|
+
if (data)
|
|
158
|
+
parsedData.push(data);
|
|
151
159
|
}
|
|
152
160
|
catch (err) {
|
|
153
|
-
console.error(`[SnapAlly] Failed to parse A11y attachment: ${err}. Body was: ${
|
|
161
|
+
console.error(`[SnapAlly] Failed to parse A11y attachment: ${err}. Body was: ${att.body.toString().substring(0, 100)}`);
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
const
|
|
164
|
+
// Use the first scan for page-level metadata (pageUrl, ADO settings, ...),
|
|
165
|
+
// but aggregate violations across every scan in the test.
|
|
166
|
+
const actualData = parsedData[0] || null;
|
|
167
|
+
const violations = parsedData.flatMap((d) => d.a11yErrors || d.violations || []);
|
|
159
168
|
const a11yErrorCount = violations.reduce((acc, curr) => { var _a, _b; return acc + (curr.total || ((_a = curr.target) === null || _a === void 0 ? void 0 : _a.length) || ((_b = curr.nodes) === null || _b === void 0 ? void 0 : _b.length) || 0); }, 0);
|
|
160
169
|
const filteredSteps = (() => {
|
|
161
170
|
const blocklist = ['Evaluate', 'Create page', 'Close page', 'Before Hooks', 'After Hooks', 'Worker Teardown', 'Worker Cleanup', 'Attach', 'Wait for timeout', 'Capture A11y screenshot', 'Scroll into view', 'Bounding box'];
|
|
@@ -109,14 +109,22 @@ function renderTestExecutionReport(data) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// Helper method for array elements
|
|
112
|
-
const renderList = (array, listId, cardId) => {
|
|
112
|
+
const renderList = (array, listId, cardId, asHtml = false) => {
|
|
113
113
|
if (array && array.length > 0) {
|
|
114
114
|
document.getElementById(cardId).classList.remove('hidden');
|
|
115
115
|
const list = document.getElementById(listId);
|
|
116
116
|
const tpl = document.getElementById('string-item-template');
|
|
117
117
|
array.forEach((item) => {
|
|
118
118
|
const clone = tpl.content.cloneNode(true);
|
|
119
|
-
clone.querySelector('li')
|
|
119
|
+
const li = clone.querySelector('li');
|
|
120
|
+
// Exceptions arrive as pre-sanitized HTML from ansiToHtml (entities
|
|
121
|
+
// already escaped, only known <span> color tags injected), so render
|
|
122
|
+
// them as HTML to show the colors. Everything else is plain text.
|
|
123
|
+
if (asHtml) {
|
|
124
|
+
li.innerHTML = item;
|
|
125
|
+
} else {
|
|
126
|
+
li.textContent = item;
|
|
127
|
+
}
|
|
120
128
|
list.appendChild(clone);
|
|
121
129
|
});
|
|
122
130
|
}
|
|
@@ -130,7 +138,7 @@ function renderTestExecutionReport(data) {
|
|
|
130
138
|
const filteredErrs = (data.errors || []).filter(
|
|
131
139
|
(err) => !err.includes('Accessibility audit failed')
|
|
132
140
|
);
|
|
133
|
-
renderList(filteredErrs, 'list-exceptions', 'card-exceptions');
|
|
141
|
+
renderList(filteredErrs, 'list-exceptions', 'card-exceptions', true);
|
|
134
142
|
|
|
135
143
|
// Normalize to an array of videos
|
|
136
144
|
const videos = Array.isArray(data.videoPath)
|
package/package.json
CHANGED