snap-ally 0.2.5-beta → 0.3.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.
- package/dist/A11yReportAssets.d.ts +5 -12
- package/dist/A11yReportAssets.js +16 -82
- package/dist/A11yScanner.d.ts +2 -21
- package/dist/A11yScanner.js +16 -22
- package/dist/A11yTimeUtils.js +11 -23
- package/dist/A11yVisualReporter.d.ts +50 -0
- package/dist/A11yVisualReporter.js +188 -0
- package/dist/AccessibilityReporterOptions.d.ts +24 -0
- package/dist/AccessibilityReporterOptions.js +5 -0
- package/dist/ResolvedColors.d.ts +15 -0
- package/dist/ResolvedColors.js +20 -0
- package/dist/SnapAllyReporter.d.ts +12 -72
- package/dist/SnapAllyReporter.js +218 -329
- package/dist/core/A11yHtmlRenderer.d.ts +17 -0
- package/dist/core/A11yHtmlRenderer.js +118 -0
- package/dist/core/A11yReportAssets.d.ts +30 -0
- package/dist/core/A11yReportAssets.js +127 -0
- package/dist/core/A11yScanner.d.ts +8 -0
- package/dist/core/A11yScanner.js +178 -0
- package/dist/core/A11yVisualReporter.d.ts +50 -0
- package/dist/core/A11yVisualReporter.js +188 -0
- package/dist/core/HtmlRenderer.d.ts +14 -0
- package/dist/core/HtmlRenderer.js +106 -0
- package/dist/core/ReportAssets.d.ts +29 -0
- package/dist/core/ReportAssets.js +126 -0
- package/dist/core/Scanner.d.ts +7 -0
- package/dist/core/Scanner.js +162 -0
- package/dist/core/VisualReporter.d.ts +54 -0
- package/dist/core/VisualReporter.js +192 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +13 -12
- package/dist/models/A11yDataSource.d.ts +15 -0
- package/dist/models/A11yDataSource.js +2 -0
- package/dist/models/A11yError.d.ts +34 -0
- package/dist/models/A11yError.js +11 -0
- package/dist/models/A11yScannerOptions.d.ts +24 -0
- package/dist/models/A11yScannerOptions.js +2 -0
- package/dist/models/AccessibilityReporterOptions.d.ts +24 -0
- package/dist/models/AccessibilityReporterOptions.js +5 -0
- package/dist/models/DataSource.d.ts +15 -0
- package/dist/models/DataSource.js +2 -0
- package/dist/models/ImagePath.d.ts +5 -0
- package/dist/models/ImagePath.js +3 -0
- package/dist/models/ReportData.d.ts +24 -0
- package/dist/models/ReportData.js +2 -0
- package/dist/models/ReporterOptions.d.ts +24 -0
- package/dist/models/ReporterOptions.js +5 -0
- package/dist/models/ResolvedColors.d.ts +16 -0
- package/dist/models/ResolvedColors.js +24 -0
- package/dist/models/ScannerOptions.d.ts +30 -0
- package/dist/models/ScannerOptions.js +2 -0
- package/dist/models/Severity.d.ts +7 -0
- package/dist/models/Severity.js +11 -0
- package/dist/models/Target.d.ts +10 -0
- package/dist/models/Target.js +3 -0
- package/dist/models/TestResults.d.ts +41 -0
- package/dist/models/TestResults.js +2 -0
- package/dist/models/TestStatusIcon.d.ts +8 -0
- package/dist/models/TestStatusIcon.js +12 -0
- package/dist/models/TestSummary.d.ts +34 -0
- package/dist/models/TestSummary.js +2 -0
- package/dist/models/Violation.d.ts +13 -0
- package/dist/models/Violation.js +2 -0
- package/dist/models/index.d.ts +12 -113
- package/dist/models/index.js +26 -16
- package/dist/templates/accessibility-report.html +75 -101
- package/dist/templates/execution-summary.html +37 -103
- package/dist/templates/global-report-styles.css +400 -9
- package/dist/templates/report-app.js +171 -73
- package/dist/templates/test-execution-report.html +84 -113
- package/dist/utils/A11yTimeUtils.d.ts +13 -0
- package/dist/utils/A11yTimeUtils.js +40 -0
- package/dist/utils/TimeUtils.d.ts +13 -0
- package/dist/utils/TimeUtils.js +39 -0
- package/package.json +2 -2
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
document.addEventListener('DOMContentLoaded', () => {
|
|
7
7
|
// Pull injected data
|
|
8
8
|
const data = window.snapAllyData;
|
|
9
|
+
console.log('Snap Ally Debug: injectedData=', data);
|
|
9
10
|
if (!data) {
|
|
10
11
|
console.error('Snap Ally: No report data found in window.snapAllyData');
|
|
11
12
|
return;
|
|
@@ -52,11 +53,26 @@ function applyCustomColors(data) {
|
|
|
52
53
|
function renderTestExecutionReport(data) {
|
|
53
54
|
const root = document.getElementById('test-execution-root');
|
|
54
55
|
if (!root) return;
|
|
55
|
-
root.
|
|
56
|
+
root.classList.remove('hidden');
|
|
56
57
|
|
|
57
58
|
// Set document title
|
|
58
59
|
document.title = `Snap Ally - Test Execution: ${data.title}`;
|
|
59
60
|
|
|
61
|
+
if (data.a11yReportPath) {
|
|
62
|
+
console.log('[SnapAlly Diagnostic] Found report path:', data.a11yReportPath);
|
|
63
|
+
const a11yLink = document.getElementById('view-a11y-report-link');
|
|
64
|
+
if (a11yLink) {
|
|
65
|
+
const filename = data.a11yReportPath.split(/[/\\]/).pop();
|
|
66
|
+
a11yLink.href = filename;
|
|
67
|
+
a11yLink.classList.remove('hidden');
|
|
68
|
+
console.log('[SnapAlly Diagnostic] Link shown. Href:', a11yLink.href);
|
|
69
|
+
} else {
|
|
70
|
+
console.warn('[SnapAlly Diagnostic] Link element "view-a11y-report-link" NOT in DOM');
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
console.log('[SnapAlly Diagnostic] No a11yReportPath found in data');
|
|
74
|
+
}
|
|
75
|
+
|
|
60
76
|
// Header
|
|
61
77
|
document.getElementById('report-title').textContent = data.title;
|
|
62
78
|
|
|
@@ -65,8 +81,11 @@ function renderTestExecutionReport(data) {
|
|
|
65
81
|
document.getElementById('report-status-icon').textContent = data.statusIcon;
|
|
66
82
|
document.getElementById('report-status-text').textContent = data.status;
|
|
67
83
|
|
|
68
|
-
|
|
69
|
-
|
|
84
|
+
// Show verified badge only if no errors
|
|
85
|
+
// Show verified badge only if no errors and no path-reported violations
|
|
86
|
+
const hasA11yErrors = (data.a11yErrorCount > 0) || (data.a11yErrors && data.a11yErrors.length > 0);
|
|
87
|
+
if (data.a11yReportPath && !hasA11yErrors) {
|
|
88
|
+
document.getElementById('report-a11y-verified').classList.remove('hidden');
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
document.getElementById('report-duration').textContent = data.duration;
|
|
@@ -81,22 +100,18 @@ function renderTestExecutionReport(data) {
|
|
|
81
100
|
tagsContainer.appendChild(clone);
|
|
82
101
|
});
|
|
83
102
|
|
|
84
|
-
if (data.a11yReportPath) {
|
|
85
|
-
const a11yLink = document.getElementById('view-a11y-report-link');
|
|
86
|
-
a11yLink.href = `./${data.a11yReportPath}`;
|
|
87
|
-
a11yLink.style.display = 'flex';
|
|
88
|
-
}
|
|
89
103
|
|
|
90
104
|
// Description
|
|
91
105
|
if (data.description) {
|
|
92
|
-
document.getElementById('card-description')
|
|
106
|
+
const card = document.getElementById('card-description');
|
|
107
|
+
card.classList.remove('hidden');
|
|
93
108
|
document.getElementById('report-description').textContent = data.description;
|
|
94
109
|
}
|
|
95
110
|
|
|
96
111
|
// Helper method for array elements
|
|
97
112
|
const renderList = (array, listId, cardId) => {
|
|
98
113
|
if (array && array.length > 0) {
|
|
99
|
-
document.getElementById(cardId).
|
|
114
|
+
document.getElementById(cardId).classList.remove('hidden');
|
|
100
115
|
const list = document.getElementById(listId);
|
|
101
116
|
const tpl = document.getElementById('string-item-template');
|
|
102
117
|
array.forEach((item) => {
|
|
@@ -117,15 +132,45 @@ function renderTestExecutionReport(data) {
|
|
|
117
132
|
);
|
|
118
133
|
renderList(filteredErrs, 'list-exceptions', 'card-exceptions');
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
// Normalize to an array of videos
|
|
136
|
+
const videos = Array.isArray(data.videoPath)
|
|
137
|
+
? data.videoPath
|
|
138
|
+
: data.videoPath
|
|
139
|
+
? [data.videoPath]
|
|
140
|
+
: [];
|
|
141
|
+
|
|
142
|
+
if (videos.length > 0) {
|
|
143
|
+
document.getElementById('card-video').classList.remove('hidden');
|
|
144
|
+
const container = document.getElementById('report-video-container');
|
|
145
|
+
container.innerHTML = '';
|
|
146
|
+
|
|
147
|
+
videos.forEach((vPath, idx) => {
|
|
148
|
+
const wrapper = document.createElement('div');
|
|
149
|
+
wrapper.style.marginBottom = '12px';
|
|
150
|
+
|
|
151
|
+
const label = document.createElement('div');
|
|
152
|
+
label.style.fontSize = '0.85rem';
|
|
153
|
+
label.style.color = 'var(--text-muted)';
|
|
154
|
+
label.style.marginBottom = '4px';
|
|
155
|
+
label.textContent = videos.length > 1 ? `Recording ${idx + 1}` : 'Recording';
|
|
156
|
+
wrapper.appendChild(label);
|
|
157
|
+
|
|
158
|
+
const videoEl = document.createElement('video');
|
|
159
|
+
videoEl.controls = true;
|
|
160
|
+
videoEl.style.width = '100%';
|
|
161
|
+
|
|
162
|
+
const source = document.createElement('source');
|
|
163
|
+
source.type = 'video/webm';
|
|
164
|
+
source.src = vPath;
|
|
165
|
+
videoEl.appendChild(source);
|
|
166
|
+
|
|
167
|
+
wrapper.appendChild(videoEl);
|
|
168
|
+
container.appendChild(wrapper);
|
|
169
|
+
});
|
|
125
170
|
}
|
|
126
171
|
|
|
127
172
|
if (data.screenshotPaths && data.screenshotPaths.length > 0) {
|
|
128
|
-
document.getElementById('card-screenshots').
|
|
173
|
+
document.getElementById('card-screenshots').classList.remove('hidden');
|
|
129
174
|
const grid = document.getElementById('grid-screenshots');
|
|
130
175
|
const tpl = document.getElementById('screenshot-template');
|
|
131
176
|
data.screenshotPaths.forEach((p) => {
|
|
@@ -136,7 +181,7 @@ function renderTestExecutionReport(data) {
|
|
|
136
181
|
}
|
|
137
182
|
|
|
138
183
|
if (data.attachments && data.attachments.length > 0) {
|
|
139
|
-
document.getElementById('card-attachments').
|
|
184
|
+
document.getElementById('card-attachments').classList.remove('hidden');
|
|
140
185
|
const list = document.getElementById('list-attachments');
|
|
141
186
|
const tpl = document.getElementById('attachment-template');
|
|
142
187
|
data.attachments.forEach((att) => {
|
|
@@ -150,9 +195,9 @@ function renderTestExecutionReport(data) {
|
|
|
150
195
|
|
|
151
196
|
// Accessibility Success / Error Cards inside general test report
|
|
152
197
|
if (data.a11yReportPath && data.a11yErrorCount === 0) {
|
|
153
|
-
document.getElementById('card-a11y-success').
|
|
198
|
+
document.getElementById('card-a11y-success').classList.remove('hidden');
|
|
154
199
|
} else if (data.a11yErrors && data.a11yErrors.length > 0) {
|
|
155
|
-
document.getElementById('card-a11y-errors').
|
|
200
|
+
document.getElementById('card-a11y-errors').classList.remove('hidden');
|
|
156
201
|
const list = document.getElementById('list-a11y-errors');
|
|
157
202
|
const tplError = document.getElementById('a11y-error-template');
|
|
158
203
|
const tplInstance = document.getElementById('a11y-instance-template');
|
|
@@ -168,7 +213,7 @@ function renderTestExecutionReport(data) {
|
|
|
168
213
|
if (error.description) {
|
|
169
214
|
const desc = clone.querySelector('.desc-text');
|
|
170
215
|
desc.textContent = error.description;
|
|
171
|
-
desc.
|
|
216
|
+
desc.classList.remove('hidden');
|
|
172
217
|
}
|
|
173
218
|
clone.querySelector('.occ-count').textContent = error.total;
|
|
174
219
|
|
|
@@ -197,7 +242,7 @@ function renderTestExecutionReport(data) {
|
|
|
197
242
|
function renderExecutionSummary(data) {
|
|
198
243
|
const root = document.getElementById('report-summary-root');
|
|
199
244
|
if (!root) return;
|
|
200
|
-
root.
|
|
245
|
+
root.classList.remove('hidden');
|
|
201
246
|
|
|
202
247
|
// Hero Section
|
|
203
248
|
document.getElementById('summary-status-badge').classList.add(`status-${data.status}`);
|
|
@@ -219,15 +264,13 @@ function renderExecutionSummary(data) {
|
|
|
219
264
|
|
|
220
265
|
const browsers = Object.keys(data.browserSummaries);
|
|
221
266
|
|
|
222
|
-
const setElDisplay = (id, disp) => {
|
|
223
|
-
const el = document.getElementById(id);
|
|
224
|
-
if (el) el.style.display = disp;
|
|
225
|
-
};
|
|
226
267
|
|
|
227
268
|
if (data.totalA11yErrorCount > 0) {
|
|
228
|
-
|
|
269
|
+
const a11yBox = document.getElementById('summary-global-a11y-box');
|
|
270
|
+
if (a11yBox) a11yBox.classList.remove('hidden');
|
|
229
271
|
setElText('summary-a11y-total', data.totalA11yErrorCount);
|
|
230
|
-
|
|
272
|
+
const errContainer = document.getElementById('global-errors-container');
|
|
273
|
+
if (errContainer) errContainer.classList.remove('hidden');
|
|
231
274
|
|
|
232
275
|
// Populate WCAG Error Cards
|
|
233
276
|
const wcagGrid = document.getElementById('global-metrics-grid');
|
|
@@ -246,7 +289,7 @@ function renderExecutionSummary(data) {
|
|
|
246
289
|
if (info.description) {
|
|
247
290
|
const desc = clone.querySelector('.metric-desc');
|
|
248
291
|
desc.textContent = info.description;
|
|
249
|
-
desc.
|
|
292
|
+
desc.classList.remove('hidden');
|
|
250
293
|
}
|
|
251
294
|
|
|
252
295
|
const count = clone.querySelector('.metric-count');
|
|
@@ -256,13 +299,13 @@ function renderExecutionSummary(data) {
|
|
|
256
299
|
if (info.helpUrl) {
|
|
257
300
|
const btn = clone.querySelector('.btn-guide');
|
|
258
301
|
btn.href = info.helpUrl;
|
|
259
|
-
btn.
|
|
302
|
+
btn.classList.remove('hidden');
|
|
260
303
|
}
|
|
261
304
|
wcagGrid.appendChild(clone);
|
|
262
305
|
});
|
|
263
306
|
} else {
|
|
264
307
|
const successCard = document.getElementById('global-success-card');
|
|
265
|
-
successCard.
|
|
308
|
+
if (successCard) successCard.classList.remove('hidden');
|
|
266
309
|
const icon = document.getElementById('global-success-icon');
|
|
267
310
|
const title = document.getElementById('global-success-title');
|
|
268
311
|
const desc = document.getElementById('global-success-desc');
|
|
@@ -306,7 +349,8 @@ function renderExecutionSummary(data) {
|
|
|
306
349
|
tabDiv.id = `tab-${browser}`;
|
|
307
350
|
|
|
308
351
|
if (bStats.totalA11yErrorCount > 0) {
|
|
309
|
-
contentClone.querySelector('.browser-errors-container')
|
|
352
|
+
const bErrContainer = contentClone.querySelector('.browser-errors-container');
|
|
353
|
+
if (bErrContainer) bErrContainer.classList.remove('hidden');
|
|
310
354
|
contentClone.querySelector('.browser-chart-title').textContent = capBrowser;
|
|
311
355
|
contentClone.querySelector('.browser-chart-container').id =
|
|
312
356
|
`chart-${browser}-violations`;
|
|
@@ -328,7 +372,7 @@ function renderExecutionSummary(data) {
|
|
|
328
372
|
if (info.description) {
|
|
329
373
|
const desc = mClone.querySelector('.metric-desc');
|
|
330
374
|
desc.textContent = info.description;
|
|
331
|
-
desc.
|
|
375
|
+
desc.classList.remove('hidden');
|
|
332
376
|
}
|
|
333
377
|
|
|
334
378
|
const count = mClone.querySelector('.metric-count');
|
|
@@ -338,7 +382,7 @@ function renderExecutionSummary(data) {
|
|
|
338
382
|
});
|
|
339
383
|
} else {
|
|
340
384
|
const sucContainer = contentClone.querySelector('.browser-success-container');
|
|
341
|
-
sucContainer.
|
|
385
|
+
if (sucContainer) sucContainer.classList.remove('hidden');
|
|
342
386
|
const bTitle = sucContainer.querySelector('.browser-success-title');
|
|
343
387
|
if (bTitle) bTitle.textContent = `${capBrowser} Compliant`;
|
|
344
388
|
}
|
|
@@ -400,13 +444,16 @@ function renderExecutionSummary(data) {
|
|
|
400
444
|
|
|
401
445
|
// Render Charts if ApexCharts is loaded
|
|
402
446
|
if (typeof ApexCharts !== 'undefined') {
|
|
403
|
-
|
|
447
|
+
const globalChartEl = document.getElementById('chart-global-violations');
|
|
448
|
+
if (globalChartEl && data.totalA11yErrorCount > 0) {
|
|
404
449
|
renderBarChart('chart-global-violations', data.wcagErrors, data.colors);
|
|
405
450
|
}
|
|
406
451
|
browsers.forEach((browser) => {
|
|
407
|
-
|
|
452
|
+
const chartId = `chart-${browser}-violations`;
|
|
453
|
+
const browserChartEl = document.getElementById(chartId);
|
|
454
|
+
if (browserChartEl && data.browserSummaries[browser].totalA11yErrorCount > 0) {
|
|
408
455
|
renderBarChart(
|
|
409
|
-
|
|
456
|
+
chartId,
|
|
410
457
|
data.browserSummaries[browser].wcagErrors,
|
|
411
458
|
data.colors
|
|
412
459
|
);
|
|
@@ -421,7 +468,7 @@ function renderExecutionSummary(data) {
|
|
|
421
468
|
function renderAccessibilityReport(injectedData) {
|
|
422
469
|
const root = document.getElementById('accessibility-report-root');
|
|
423
470
|
if (!root) return;
|
|
424
|
-
root.
|
|
471
|
+
root.classList.remove('hidden');
|
|
425
472
|
|
|
426
473
|
document.title = 'Snap Ally - Accessibility Audit';
|
|
427
474
|
|
|
@@ -441,7 +488,14 @@ function renderAccessibilityReport(injectedData) {
|
|
|
441
488
|
0
|
|
442
489
|
);
|
|
443
490
|
}
|
|
444
|
-
|
|
491
|
+
// Support either a single video or an array of videos
|
|
492
|
+
const videoArray = Array.isArray(data.video || data.videoPath)
|
|
493
|
+
? data.video || data.videoPath
|
|
494
|
+
: data.video || data.videoPath
|
|
495
|
+
? [data.video || data.videoPath]
|
|
496
|
+
: [];
|
|
497
|
+
const videoPath = videoArray[0] || '';
|
|
498
|
+
const browser = data.browser || injectedData.browser || (window.snapAllyData && window.snapAllyData.browser) || 'Unknown';
|
|
445
499
|
|
|
446
500
|
// Hero Section
|
|
447
501
|
const pageUrlEl = document.getElementById('a11y-page-url');
|
|
@@ -450,14 +504,19 @@ function renderAccessibilityReport(injectedData) {
|
|
|
450
504
|
const timestampEl = document.getElementById('a11y-timestamp');
|
|
451
505
|
if (timestampEl) timestampEl.textContent = timestamp;
|
|
452
506
|
|
|
507
|
+
const browserContainer = document.getElementById('a11y-browser-container');
|
|
508
|
+
const browserText = document.getElementById('a11y-browser-text');
|
|
509
|
+
if (browserContainer) browserContainer.classList.remove('hidden');
|
|
510
|
+
if (browserText) browserText.textContent = browser;
|
|
511
|
+
|
|
453
512
|
if (failedCount === 0) {
|
|
454
513
|
const passedPill = document.getElementById('a11y-pill-passed');
|
|
455
|
-
if (passedPill) passedPill.
|
|
514
|
+
if (passedPill) passedPill.classList.remove('hidden');
|
|
456
515
|
const successCard = document.getElementById('a11y-success-card');
|
|
457
|
-
if (successCard) successCard.
|
|
516
|
+
if (successCard) successCard.classList.remove('hidden');
|
|
458
517
|
} else {
|
|
459
518
|
const failedPill = document.getElementById('a11y-pill-failed');
|
|
460
|
-
if (failedPill) failedPill.
|
|
519
|
+
if (failedPill) failedPill.classList.remove('hidden');
|
|
461
520
|
const failedCountEl = document.getElementById('a11y-failed-count');
|
|
462
521
|
if (failedCountEl) failedCountEl.textContent = failedCount;
|
|
463
522
|
}
|
|
@@ -469,11 +528,20 @@ function renderAccessibilityReport(injectedData) {
|
|
|
469
528
|
}
|
|
470
529
|
|
|
471
530
|
// Render video section if exists
|
|
472
|
-
if (
|
|
473
|
-
document.getElementById('a11y-video-card')
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
531
|
+
if (videoArray.length > 0) {
|
|
532
|
+
const videoCard = document.getElementById('a11y-video-card');
|
|
533
|
+
if (videoCard) videoCard.classList.remove('hidden');
|
|
534
|
+
|
|
535
|
+
const videoList = document.getElementById('a11y-videos-list');
|
|
536
|
+
if (videoList) {
|
|
537
|
+
videoList.innerHTML = ''; // Clear fallback
|
|
538
|
+
videoArray.forEach((v) => {
|
|
539
|
+
const video = document.createElement('video');
|
|
540
|
+
video.controls = true;
|
|
541
|
+
video.innerHTML = `<source src="${v}" type="video/webm">Your browser does not support the video tag.`;
|
|
542
|
+
videoList.appendChild(video);
|
|
543
|
+
});
|
|
544
|
+
}
|
|
477
545
|
}
|
|
478
546
|
|
|
479
547
|
// Iterate over violations
|
|
@@ -525,7 +593,7 @@ function renderAccessibilityReport(injectedData) {
|
|
|
525
593
|
bClone.querySelector('.bug-snippet-text').textContent = snippetText;
|
|
526
594
|
|
|
527
595
|
// Parse steps for both the card display and the bug dialog
|
|
528
|
-
let stepsArray = node.steps || [];
|
|
596
|
+
let stepsArray = (node.steps && node.steps.length > 0) ? node.steps : (data.steps || []);
|
|
529
597
|
if (typeof stepsArray === 'string') {
|
|
530
598
|
try {
|
|
531
599
|
stepsArray = JSON.parse(stepsArray);
|
|
@@ -539,9 +607,10 @@ function renderAccessibilityReport(injectedData) {
|
|
|
539
607
|
const safeSnippet = escapeHtml(snippetText);
|
|
540
608
|
const wcag = escapeHtml(v.wcagRule || (v.tags ? v.tags.join(', ') : ''));
|
|
541
609
|
const safeStepsJson = encodeURIComponent(JSON.stringify(stepsArray));
|
|
610
|
+
const safeHelpUrl = escapeHtml(v.helpUrl || '');
|
|
542
611
|
btn.setAttribute(
|
|
543
612
|
'onclick',
|
|
544
|
-
`event.preventDefault(); event.stopPropagation(); window.generateAdoPayload('${escapeHtml(v.id || 'Unknown ID')}', '${escapeHtml(v.help || 'No Help Provided')}', '${escapeHtml(node.failureSummary || '')}', '${escapeHtml(node.html || '')}', '${impact || 'unknown'}', '${escapeHtml(node.screenshotBase64 || node.screenshot || node.screenshotPath || '')}', '${escapeHtml(videoPath || '')}', '${safeSnippet}', '${wcag}', '${safeStepsJson}')`
|
|
613
|
+
`event.preventDefault(); event.stopPropagation(); window.generateAdoPayload('${escapeHtml(v.id || 'Unknown ID')}', '${escapeHtml(v.help || 'No Help Provided')}', '${escapeHtml(node.failureSummary || '')}', '${escapeHtml(node.html || '')}', '${impact || 'unknown'}', '${escapeHtml(node.screenshotBase64 || node.screenshot || node.screenshotPath || '')}', '${escapeHtml(videoPath || '')}', '${safeSnippet}', '${wcag}', '${safeStepsJson}', '${safeHelpUrl}', '${escapeHtml(browser)}')`
|
|
545
614
|
);
|
|
546
615
|
|
|
547
616
|
const failSec = bClone.querySelector('.bug-failure-summary');
|
|
@@ -558,7 +627,7 @@ function renderAccessibilityReport(injectedData) {
|
|
|
558
627
|
|
|
559
628
|
if (node.screenshot || node.screenshotPath) {
|
|
560
629
|
const visSec = bClone.querySelector('.visual-evidence-section');
|
|
561
|
-
visSec.
|
|
630
|
+
visSec.classList.remove('hidden');
|
|
562
631
|
bClone.querySelector('.bug-screenshot').src =
|
|
563
632
|
node.screenshot || node.screenshotPath;
|
|
564
633
|
}
|
|
@@ -569,6 +638,10 @@ function renderAccessibilityReport(injectedData) {
|
|
|
569
638
|
container.appendChild(vClone);
|
|
570
639
|
});
|
|
571
640
|
}
|
|
641
|
+
|
|
642
|
+
// Hide loader after rendering everything
|
|
643
|
+
const loader = document.getElementById('loader-overlay');
|
|
644
|
+
if (loader) loader.classList.add('hidden');
|
|
572
645
|
}
|
|
573
646
|
|
|
574
647
|
// ============================================================================
|
|
@@ -630,17 +703,15 @@ function escapeHtml(unsafe) {
|
|
|
630
703
|
|
|
631
704
|
// Chart Generation
|
|
632
705
|
function renderBarChart(elementId, wcagData, colors) {
|
|
633
|
-
const el = document.
|
|
634
|
-
if (!el)
|
|
635
|
-
throw new Error('CRITICAL_NULL_ELEMENT_ID: ' + elementId);
|
|
636
|
-
}
|
|
706
|
+
const el = document.getElementById(elementId);
|
|
707
|
+
if (!el) return;
|
|
637
708
|
|
|
638
709
|
const wcagEntries = Object.entries(wcagData).sort((a, b) => b[1].count - a[1].count);
|
|
639
710
|
if (wcagEntries.length === 0) return;
|
|
640
711
|
|
|
641
|
-
const chartColors = wcagEntries.map((e) => colors[e[1].severity] || '#ef4444');
|
|
712
|
+
const chartColors = wcagEntries.map((e) => (colors && colors[e[1].severity]) || '#ef4444');
|
|
642
713
|
|
|
643
|
-
new ApexCharts(
|
|
714
|
+
new ApexCharts(el, {
|
|
644
715
|
chart: { type: 'bar', height: 350, toolbar: { show: false } },
|
|
645
716
|
series: [{ name: 'Violations', data: wcagEntries.map((e) => e[1].count) }],
|
|
646
717
|
xaxis: {
|
|
@@ -752,7 +823,9 @@ window.generateAdoPayload = function (
|
|
|
752
823
|
videoPath,
|
|
753
824
|
snippet,
|
|
754
825
|
wcag,
|
|
755
|
-
stepsJson
|
|
826
|
+
stepsJson,
|
|
827
|
+
helpUrl,
|
|
828
|
+
browser
|
|
756
829
|
) {
|
|
757
830
|
const pat = sessionStorage.getItem('userToken');
|
|
758
831
|
if (!pat && window.bootstrap) {
|
|
@@ -770,6 +843,8 @@ window.generateAdoPayload = function (
|
|
|
770
843
|
const data = rawData.data || rawData;
|
|
771
844
|
const currentUrl = document.getElementById('bugUrlPreview');
|
|
772
845
|
if (currentUrl) currentUrl.textContent = data.pageUrl || data.pageKey || 'Resource';
|
|
846
|
+
const browserPreview = document.getElementById('bugBrowserPreview');
|
|
847
|
+
if (browserPreview) browserPreview.textContent = browser || 'Unknown';
|
|
773
848
|
|
|
774
849
|
// Decode the reproduction steps passed from the violation card
|
|
775
850
|
let reproSteps = [];
|
|
@@ -792,12 +867,27 @@ window.generateAdoPayload = function (
|
|
|
792
867
|
}
|
|
793
868
|
|
|
794
869
|
const failureHtml = `
|
|
795
|
-
<div
|
|
796
|
-
|
|
870
|
+
<div class="repro-section">
|
|
871
|
+
<div class="repro-section-label">Failure Message</div>
|
|
872
|
+
<div class="repro-mono-box">
|
|
873
|
+
${failureSummary ? failureSummary.replace(/\\n/g, '<br>') : 'Issue discovered via static analysis scans.'}
|
|
874
|
+
</div>
|
|
797
875
|
</div>
|
|
798
|
-
<
|
|
799
|
-
|
|
800
|
-
|
|
876
|
+
<div class="repro-section">
|
|
877
|
+
<div class="repro-section-label">How to Fix</div>
|
|
878
|
+
<div class="repro-hint-box">
|
|
879
|
+
<span class="material-symbols-outlined repro-hint-icon" aria-hidden="true">lightbulb</span>
|
|
880
|
+
<div>
|
|
881
|
+
<strong>${help || 'No recommendation available.'}</strong>
|
|
882
|
+
${helpUrl ? `<br><a href="${helpUrl}" target="_blank" rel="noopener" class="repro-deque-link"><span class="material-symbols-outlined" style="font-size:13px;vertical-align:middle">open_in_new</span> View Axe Rule Documentation (deque.com)</a>` : ''}
|
|
883
|
+
</div>
|
|
884
|
+
</div>
|
|
885
|
+
</div>
|
|
886
|
+
<div class="repro-section">
|
|
887
|
+
<div class="repro-section-label">DOM Element</div>
|
|
888
|
+
<div class="repro-mono-box repro-code">
|
|
889
|
+
${htmlSnippet ? htmlSnippet.replace(/</g, '<').replace(/>/g, '>') : 'No DOM snippet available.'}
|
|
890
|
+
</div>
|
|
801
891
|
</div>
|
|
802
892
|
`;
|
|
803
893
|
|
|
@@ -805,11 +895,18 @@ window.generateAdoPayload = function (
|
|
|
805
895
|
const stepsHtml = reproStepsHtml + failureHtml;
|
|
806
896
|
|
|
807
897
|
document.getElementById('bugReproPreview').innerHTML = `
|
|
808
|
-
<div
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
898
|
+
<div class="repro-preview-root">
|
|
899
|
+
<div class="repro-meta-pills">
|
|
900
|
+
<span class="repro-pill repro-pill-id">${axeId}</span>
|
|
901
|
+
<span class="repro-pill repro-pill-wcag">${wcag}</span>
|
|
902
|
+
<span class="repro-pill repro-pill-sev repro-pill-sev-${severity}">${severity}</span>
|
|
903
|
+
</div>
|
|
904
|
+
${reproStepsHtml ? `<div class="repro-section">
|
|
905
|
+
<div class="repro-section-label">Reproduction Steps</div>
|
|
906
|
+
${reproStepsHtml}
|
|
907
|
+
</div>` : ''}
|
|
908
|
+
${failureHtml}
|
|
909
|
+
</div>
|
|
813
910
|
`;
|
|
814
911
|
|
|
815
912
|
const screenshotPreview = document.getElementById('bugScreenshotPreview');
|
|
@@ -826,21 +923,21 @@ window.generateAdoPayload = function (
|
|
|
826
923
|
} else {
|
|
827
924
|
screenshotPreview.src = `data:image/png;base64,${screenshotBase64}`;
|
|
828
925
|
}
|
|
829
|
-
if (screenshotThumbContainer) screenshotThumbContainer.
|
|
926
|
+
if (screenshotThumbContainer) screenshotThumbContainer.classList.remove('hidden');
|
|
830
927
|
} else {
|
|
831
|
-
if (screenshotThumbContainer) screenshotThumbContainer.
|
|
928
|
+
if (screenshotThumbContainer) screenshotThumbContainer.classList.add('hidden');
|
|
832
929
|
}
|
|
833
930
|
|
|
834
931
|
const videoThumbContainer = document.getElementById('videoThumbContainer');
|
|
835
932
|
const videoPreview = document.getElementById('bugVideoPreview');
|
|
836
933
|
if (videoPath) {
|
|
837
934
|
if (videoPreview) videoPreview.src = videoPath;
|
|
838
|
-
if (videoThumbContainer) videoThumbContainer.
|
|
935
|
+
if (videoThumbContainer) videoThumbContainer.classList.remove('hidden');
|
|
839
936
|
} else {
|
|
840
|
-
if (videoThumbContainer) videoThumbContainer.
|
|
937
|
+
if (videoThumbContainer) videoThumbContainer.classList.add('hidden');
|
|
841
938
|
}
|
|
842
939
|
|
|
843
|
-
window.currentBugData = { axeId, wcag, help, stepsHtml, screenshotBase64, videoPath };
|
|
940
|
+
window.currentBugData = { axeId, wcag, help, stepsHtml, screenshotBase64, videoPath, browser };
|
|
844
941
|
|
|
845
942
|
if (window.bootstrap) {
|
|
846
943
|
const modal = bootstrap.Modal.getOrCreateInstance(
|
|
@@ -876,11 +973,11 @@ async function submitFinalBug() {
|
|
|
876
973
|
const org = data.adoOrganization;
|
|
877
974
|
const proj = data.adoProject;
|
|
878
975
|
const pat = sessionStorage.getItem('userToken');
|
|
879
|
-
const { axeId, wcag, help, stepsHtml, screenshotBase64, videoPath } = window.currentBugData;
|
|
976
|
+
const { axeId, wcag, help, stepsHtml, screenshotBase64, videoPath, browser } = window.currentBugData;
|
|
880
977
|
|
|
881
978
|
const title = document.getElementById('bugTitleInput').value;
|
|
882
979
|
const severity = document.getElementById('bugSeverityInput').value;
|
|
883
|
-
const area = document.getElementById('bugAreaInput').value;
|
|
980
|
+
const area = document.getElementById('bugAreaInput').value.replace(/\\+/g, '\\');
|
|
884
981
|
|
|
885
982
|
let screenshotUrl = null;
|
|
886
983
|
if (screenshotBase64) {
|
|
@@ -914,6 +1011,7 @@ async function submitFinalBug() {
|
|
|
914
1011
|
|
|
915
1012
|
const combinedReproHtml = `
|
|
916
1013
|
<div style="margin-bottom: 12px;"><b>Rule:</b> ${axeId} (${wcag})</div>
|
|
1014
|
+
<div style="margin-bottom: 12px;"><b>Browser:</b> ${browser}</div>
|
|
917
1015
|
<div style="margin-bottom: 12px;"><b>Recommendation:</b> ${help}</div>
|
|
918
1016
|
<hr>
|
|
919
1017
|
<div style="margin-bottom: 8px;"><b>Failure Trace & Details:</b></div>
|