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
|
@@ -5,374 +5,18 @@
|
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
7
|
<title>Snap Ally - Test Summary</title>
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
<!-- Modern Typography and Core Styles -->
|
|
9
10
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@600;700&display=swap"
|
|
12
|
-
|
|
12
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@600;700&display=swap"
|
|
13
|
+
rel="stylesheet">
|
|
14
|
+
<link rel="stylesheet"
|
|
15
|
+
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
13
16
|
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
|
14
|
-
<style>
|
|
15
|
-
:root {
|
|
16
|
-
--bg-color: #f8fafc;
|
|
17
|
-
--card-bg: rgba(255, 255, 255, 0.7);
|
|
18
|
-
--primary: #4f46e5;
|
|
19
|
-
--primary-dark: #4338ca;
|
|
20
|
-
--text-main: #1e293b;
|
|
21
|
-
--text-muted: #64748b;
|
|
22
|
-
--passed: #10b981;
|
|
23
|
-
--failed: #ef4444;
|
|
24
|
-
--flaky: #f59e0b;
|
|
25
|
-
--skipped: #6366f1;
|
|
26
|
-
--glass-border: rgba(255, 255, 255, 0.4);
|
|
27
|
-
--glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.07);
|
|
28
|
-
|
|
29
|
-
/* Severity Colors */
|
|
30
|
-
--critical: <%= colors.critical %>;
|
|
31
|
-
--serious: <%= colors.serious %>;
|
|
32
|
-
--moderate: <%= colors.moderate %>;
|
|
33
|
-
--minor: <%= colors.minor %>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
* {
|
|
37
|
-
box-sizing: border-box;
|
|
38
|
-
margin: 0;
|
|
39
|
-
padding: 0;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/* Fixed Header */
|
|
43
|
-
header {
|
|
44
|
-
position: fixed;
|
|
45
|
-
top: 0; left: 0; right: 0;
|
|
46
|
-
z-index: 1000;
|
|
47
|
-
background: rgba(255, 255, 255, 0.8);
|
|
48
|
-
backdrop-filter: blur(20px) saturate(180%);
|
|
49
|
-
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
50
|
-
border-bottom: 1px solid var(--glass-border);
|
|
51
|
-
padding: 14px 40px;
|
|
52
|
-
display: flex;
|
|
53
|
-
justify-content: space-between;
|
|
54
|
-
align-items: center;
|
|
55
|
-
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.03);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.brand {
|
|
59
|
-
display: flex;
|
|
60
|
-
align-items: center;
|
|
61
|
-
gap: 12px;
|
|
62
|
-
text-decoration: none;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.brand-icon {
|
|
66
|
-
width: 38px;
|
|
67
|
-
height: 38px;
|
|
68
|
-
background: linear-gradient(135deg, var(--primary), var(--primary-dark));
|
|
69
|
-
border-radius: 12px;
|
|
70
|
-
display: flex;
|
|
71
|
-
align-items: center;
|
|
72
|
-
justify-content: center;
|
|
73
|
-
color: white;
|
|
74
|
-
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.25);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
header h1 {
|
|
78
|
-
font-family: 'Outfit', sans-serif;
|
|
79
|
-
font-size: 1.4rem;
|
|
80
|
-
font-weight: 700;
|
|
81
|
-
margin: 0;
|
|
82
|
-
background: linear-gradient(to right, var(--primary-dark), #818cf8);
|
|
83
|
-
-webkit-background-clip: text;
|
|
84
|
-
background-clip: text;
|
|
85
|
-
-webkit-text-fill-color: transparent;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
body {
|
|
89
|
-
font-family: 'Inter', sans-serif;
|
|
90
|
-
background-color: var(--bg-color);
|
|
91
|
-
color: var(--text-main);
|
|
92
|
-
padding: 100px 20px 0; /* Removed bottom padding */
|
|
93
|
-
line-height: 1.5;
|
|
94
|
-
display: flex;
|
|
95
|
-
flex-direction: column;
|
|
96
|
-
min-height: 100vh;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/* Tabs UI */
|
|
100
|
-
.tabs-container {
|
|
101
|
-
display: flex;
|
|
102
|
-
gap: 12px;
|
|
103
|
-
margin-bottom: 32px;
|
|
104
|
-
padding: 4px;
|
|
105
|
-
background: #e2e8f0;
|
|
106
|
-
border-radius: 14px;
|
|
107
|
-
width: fit-content;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.tab-btn {
|
|
111
|
-
padding: 10px 20px;
|
|
112
|
-
border: none;
|
|
113
|
-
background: none;
|
|
114
|
-
font-family: 'Inter', sans-serif;
|
|
115
|
-
font-weight: 600;
|
|
116
|
-
font-size: 0.9rem;
|
|
117
|
-
color: var(--text-muted);
|
|
118
|
-
cursor: pointer;
|
|
119
|
-
border-radius: 10px;
|
|
120
|
-
transition: all 0.2s ease;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.tab-btn.active {
|
|
124
|
-
background: white;
|
|
125
|
-
color: var(--primary);
|
|
126
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.tab-content {
|
|
130
|
-
display: none;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.tab-content.active {
|
|
134
|
-
display: block;
|
|
135
|
-
animation: fadeIn 0.3s ease;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
@keyframes fadeIn {
|
|
139
|
-
from { opacity: 0; transform: translateY(10px); }
|
|
140
|
-
to { opacity: 1; transform: translateY(0); }
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/* Footer */
|
|
144
|
-
footer {
|
|
145
|
-
background: rgba(255, 255, 255, 0.7);
|
|
146
|
-
backdrop-filter: blur(12px);
|
|
147
|
-
-webkit-backdrop-filter: blur(12px);
|
|
148
|
-
border-top: 1px solid var(--glass-border);
|
|
149
|
-
padding: 24px 40px;
|
|
150
|
-
margin-top: auto; /* Sticky footer */
|
|
151
|
-
display: flex;
|
|
152
|
-
justify-content: space-between;
|
|
153
|
-
align-items: center;
|
|
154
|
-
color: var(--text-muted);
|
|
155
|
-
font-size: 0.9rem;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.powered-by { display: flex; align-items: center; gap: 8px; font-weight: 500; }
|
|
159
|
-
.badge-tool { background: #f1f5f9; padding: 2px 10px; border-radius: 8px; font-weight: 700; color: #334155; font-size: 0.8rem; }
|
|
160
|
-
|
|
161
|
-
/* Summary Hero */
|
|
162
|
-
.summary-hero {
|
|
163
|
-
background: #fff;
|
|
164
|
-
border: 1px solid var(--glass-border);
|
|
165
|
-
border-radius: 24px;
|
|
166
|
-
padding: 20px;
|
|
167
|
-
margin-bottom: 20px;
|
|
168
|
-
box-shadow: var(--glass-shadow);
|
|
169
|
-
display: flex;
|
|
170
|
-
justify-content: space-between;
|
|
171
|
-
align-items: center;
|
|
172
|
-
gap: 24px;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.report-status {
|
|
176
|
-
display: flex;
|
|
177
|
-
align-items: center;
|
|
178
|
-
gap: 10px;
|
|
179
|
-
font-weight: 500;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.status-icon {
|
|
183
|
-
width: 40px;
|
|
184
|
-
height: 40px;
|
|
185
|
-
border-radius: 12px;
|
|
186
|
-
display: flex;
|
|
187
|
-
align-items: center;
|
|
188
|
-
justify-content: center;
|
|
189
|
-
font-size: 24px;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.status-passed { background: #e6f9f3; color: var(--passed); }
|
|
193
|
-
.status-failed { background: #fee2e2; color: var(--failed); }
|
|
194
|
-
|
|
195
|
-
.status-label { font-size: 0.85rem; color: var(--text-muted); font-weight: 600; text-transform: uppercase; }
|
|
196
|
-
.status-val { font-weight: 700; font-size: 1.25rem; text-transform: capitalize; }
|
|
197
|
-
.hero-right { text-align: right; }
|
|
198
|
-
.gen-date { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 6px; }
|
|
199
|
-
.gen-date-val { font-weight: 600; color: var(--text-main); }
|
|
200
|
-
.runtime-box { font-size: 0.9rem; color: var(--text-muted); }
|
|
201
|
-
.runtime-val { color: var(--text-main); font-size: 1.1rem; }
|
|
202
|
-
|
|
203
|
-
/* Grid Layout */
|
|
204
|
-
.metrics-grid {
|
|
205
|
-
display: grid;
|
|
206
|
-
grid-template-columns: repeat(3, 1fr);
|
|
207
|
-
gap: 20px;
|
|
208
|
-
margin-bottom: 40px;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.metric-card {
|
|
212
|
-
background: white;
|
|
213
|
-
border-radius: 16px;
|
|
214
|
-
padding: 20px;
|
|
215
|
-
display: flex;
|
|
216
|
-
flex-direction: column;
|
|
217
|
-
justify-content: space-between;
|
|
218
|
-
gap: 16px;
|
|
219
|
-
border: 1px solid #f1f5f9;
|
|
220
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.03);
|
|
221
|
-
transition: transform 0.2s, box-shadow 0.2s;
|
|
222
|
-
}
|
|
223
|
-
.metric-card:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgba(0,0,0,0.06); }
|
|
224
|
-
|
|
225
|
-
.metric-card.critical { border-top: 4px solid var(--critical); }
|
|
226
|
-
.metric-card.serious { border-top: 4px solid var(--serious); }
|
|
227
|
-
.metric-card.moderate { border-top: 4px solid var(--moderate); }
|
|
228
|
-
.metric-card.minor { border-top: 4px solid var(--minor); }
|
|
229
17
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
.metric-sev { font-size: 0.75rem; font-weight: 800; text-transform: uppercase; padding: 2px 8px; border-radius: 6px; }
|
|
234
|
-
.metric-sev.critical { color: var(--critical); background: rgba(201, 42, 42, 0.1); }
|
|
235
|
-
.metric-sev.serious { color: var(--serious); background: rgba(230, 119, 0, 0.1); }
|
|
236
|
-
.metric-sev.moderate { color: var(--moderate); background: rgba(202, 138, 4, 0.1); }
|
|
237
|
-
.metric-sev.minor { color: var(--minor); background: rgba(8, 145, 178, 0.1); }
|
|
238
|
-
|
|
239
|
-
.metric-desc { font-size: 0.85rem; color: var(--text-muted); margin-top: 8px; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
240
|
-
.metric-footer { display: flex; justify-content: space-between; align-items: center; margin-top: auto; }
|
|
241
|
-
|
|
242
|
-
.metric-count { font-size: 1.8rem; font-weight: 800; font-family: 'Outfit', sans-serif; line-height: 1; }
|
|
243
|
-
.metric-count.critical { color: var(--critical); }
|
|
244
|
-
.metric-count.serious { color: var(--serious); }
|
|
245
|
-
.metric-count.moderate { color: var(--moderate); }
|
|
246
|
-
.metric-count.minor { color: var(--minor); }
|
|
247
|
-
.btn-guide { color: var(--text-muted); text-decoration: none; display: flex; align-items: center; gap: 4px; font-size: 0.7rem; font-weight: 700; background: #f1f5f9; padding: 6px 10px; border-radius: 6px; }
|
|
248
|
-
|
|
249
|
-
/* Charts */
|
|
250
|
-
.chart-box {
|
|
251
|
-
background: var(--card-bg);
|
|
252
|
-
backdrop-filter: blur(12px);
|
|
253
|
-
border: 1px solid var(--glass-border);
|
|
254
|
-
border-radius: 24px;
|
|
255
|
-
padding: 24px;
|
|
256
|
-
box-shadow: var(--glass-shadow);
|
|
257
|
-
margin-bottom: 40px;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.chart-title {
|
|
261
|
-
font-family: 'Outfit', sans-serif;
|
|
262
|
-
font-size: 1.1rem;
|
|
263
|
-
margin-bottom: 20px;
|
|
264
|
-
color: var(--text-main);
|
|
265
|
-
display: flex; justify-content: space-between; align-items: center;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
.chart-legend { display: flex; gap: 16px; font-size: 0.85rem; font-weight: 600; }
|
|
269
|
-
.legend-item { display: flex; align-items: center; gap: 6px; }
|
|
270
|
-
.legend-dot { width: 14px; height: 14px; border-radius: 4px; }
|
|
271
|
-
.legend-dot.critical { background: var(--critical); }
|
|
272
|
-
.legend-dot.serious { background: var(--serious); }
|
|
273
|
-
.legend-dot.moderate { background: var(--moderate); }
|
|
274
|
-
.legend-dot.minor { background: var(--minor); }
|
|
275
|
-
|
|
276
|
-
/* Success State */
|
|
277
|
-
.success-verified-card { text-align: center; padding: 80px 0; background: white; border-radius: 32px; border: 1px solid var(--glass-border); box-shadow: var(--glass-shadow); margin-bottom: 40px; }
|
|
278
|
-
.success-hero-icon { font-size: 80px; color: #10b981; margin-bottom: 24px; filter: drop-shadow(0 4px 12px rgba(16,185,129,0.25)); }
|
|
279
|
-
.success-hero-title { font-family: 'Outfit', sans-serif; font-size: 1.8rem; color: var(--text-main); margin-bottom: 12px; font-weight: 700; }
|
|
280
|
-
.success-hero-desc { color: var(--text-muted); max-width: 480px; font-size: 1rem; margin: 0 auto; }
|
|
281
|
-
|
|
282
|
-
/* Results Groups - Accordion Unified Redesign */
|
|
283
|
-
.group-section {
|
|
284
|
-
margin-bottom: 30px;
|
|
285
|
-
border: 1px solid var(--glass-border);
|
|
286
|
-
border-radius: 20px;
|
|
287
|
-
overflow: hidden;
|
|
288
|
-
background: white;
|
|
289
|
-
box-shadow: var(--glass-shadow);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
.group-header {
|
|
293
|
-
background: #eff6ff;
|
|
294
|
-
padding: 20px 24px;
|
|
295
|
-
font-weight: 700;
|
|
296
|
-
color: var(--primary-dark);
|
|
297
|
-
display: flex;
|
|
298
|
-
justify-content: space-between;
|
|
299
|
-
align-items: center;
|
|
300
|
-
cursor: pointer;
|
|
301
|
-
transition: background 0.2s ease;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
.group-header:hover { background: #dbeafe; }
|
|
305
|
-
.group-content { padding: 8px 16px 16px; }
|
|
306
|
-
|
|
307
|
-
.insights-header { font-family: 'Outfit', sans-serif; font-size: 1.25rem; margin-bottom: 24px; color: var(--text-main); display: flex; align-items: center; gap: 8px; }
|
|
308
|
-
|
|
309
|
-
.test-card {
|
|
310
|
-
background: #fff;
|
|
311
|
-
border-radius: 12px;
|
|
312
|
-
padding: 16px 20px;
|
|
313
|
-
margin-top: 8px;
|
|
314
|
-
display: flex;
|
|
315
|
-
align-items: center;
|
|
316
|
-
gap: 16px;
|
|
317
|
-
border: 1px solid #f1f5f9;
|
|
318
|
-
transition: all 0.2s ease;
|
|
319
|
-
text-decoration: none;
|
|
320
|
-
color: inherit;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
.test-card:hover {
|
|
324
|
-
border-color: var(--primary);
|
|
325
|
-
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.08);
|
|
326
|
-
transform: translateX(4px);
|
|
327
|
-
background: #f8fafc;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
.status-icon-small {
|
|
331
|
-
font-size: 20px;
|
|
332
|
-
flex-shrink: 0;
|
|
333
|
-
}
|
|
334
|
-
.status-icon-passed { color: var(--passed); }
|
|
335
|
-
.status-icon-failed { color: var(--failed); }
|
|
336
|
-
.status-icon-flaky { color: var(--flaky); }
|
|
337
|
-
.status-icon-skipped { color: var(--skipped); }
|
|
338
|
-
|
|
339
|
-
.test-main-info { flex: 1; display: flex; align-items: center; justify-content: space-between; width: 100%; }
|
|
340
|
-
.test-title-group { display: flex; align-items: center; gap: 16px; }
|
|
341
|
-
.test-title { font-weight: 600; margin: 0; display: block; }
|
|
342
|
-
|
|
343
|
-
.test-meta {
|
|
344
|
-
display: flex;
|
|
345
|
-
gap: 12px;
|
|
346
|
-
font-size: 0.8rem;
|
|
347
|
-
color: var(--text-muted);
|
|
348
|
-
align-items: center;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
.err-badge { background: #fee2e2; color: #ef4444; font-size: 0.7rem; font-weight: 800; padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
|
|
352
|
-
.test-dur { font-size: 0.8rem; color: var(--text-muted); font-weight: 700; }
|
|
353
|
-
|
|
354
|
-
.browser-chip {
|
|
355
|
-
padding: 2px 8px;
|
|
356
|
-
border-radius: 6px;
|
|
357
|
-
background: #f1f5f9;
|
|
358
|
-
color: #475569;
|
|
359
|
-
font-weight: 500;
|
|
360
|
-
font-size: 0.75rem;
|
|
361
|
-
text-transform: capitalize;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
.chip-chromium, .chip-desktop-chromium { background: #e0f2fe; color: #0284c7; }
|
|
365
|
-
.chip-firefox, .chip-desktop-firefox { background: #ffedd5; color: #c2410c; }
|
|
366
|
-
.chip-webkit, .chip-desktop-webkit { background: #f3f4f6; color: #4b5563; }
|
|
367
|
-
.chip-mobile-chrome { background: #e0f2fe; color: #0284c7; }
|
|
368
|
-
.chip-mobile-safari { background: #f3f4f6; color: #4b5563; }
|
|
369
|
-
|
|
370
|
-
.group-toggle-icon { transition: transform 0.2s ease; }
|
|
371
|
-
.collapsed .group-toggle-icon { transform: rotate(-90deg); }
|
|
372
|
-
.collapsed .group-content { display: none; }
|
|
373
|
-
|
|
374
|
-
.container { max-width: 1200px !important; margin: 0 auto; width: 100%; padding-bottom: 40px; }
|
|
375
|
-
</style>
|
|
18
|
+
<!-- Snap Ally Shared Template Styles -->
|
|
19
|
+
<link rel="stylesheet" href="global-report-styles.css">
|
|
376
20
|
</head>
|
|
377
21
|
|
|
378
22
|
<body>
|
|
@@ -385,311 +29,178 @@
|
|
|
385
29
|
</a>
|
|
386
30
|
</header>
|
|
387
31
|
|
|
388
|
-
<div class="container">
|
|
32
|
+
<div class="container" id="report-summary-root" style="display: none;">
|
|
33
|
+
|
|
34
|
+
<!-- Hero Section -->
|
|
389
35
|
<div class="summary-hero">
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
<
|
|
396
|
-
<
|
|
397
|
-
|
|
398
|
-
|
|
36
|
+
<div style="display: flex; align-items: center; gap: 16px; margin-bottom: 8px;">
|
|
37
|
+
<h2 style="margin: 0; font-weight: 600; font-size: 1.4rem; color: var(--text-main);">
|
|
38
|
+
Test Execution Summary
|
|
39
|
+
</h2>
|
|
40
|
+
<div class="status-badge" id="summary-status-badge">
|
|
41
|
+
<span class="material-symbols-outlined" id="summary-status-icon" style="font-size: 16px;"></span>
|
|
42
|
+
<span id="summary-status-text"></span>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
399
45
|
<div class="hero-right">
|
|
400
|
-
<div class="gen-date">Generated on <span
|
|
401
|
-
<div class="runtime-box">Total
|
|
46
|
+
<div class="gen-date">Generated on: <span class="gen-date-val" id="summary-date"></span></div>
|
|
47
|
+
<div class="runtime-box">Total Runtime: <span class="runtime-val" id="summary-duration"></span></div>
|
|
402
48
|
</div>
|
|
403
49
|
</div>
|
|
404
50
|
|
|
405
|
-
<!-- Tabs Container -->
|
|
406
|
-
<div class="tabs-container">
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
Object.keys(results.browserSummaries).forEach(function(browser) { %>
|
|
410
|
-
<button class="tab-btn" onclick="showTab('<%= browser %>', this)"><%= browser.charAt(0).toUpperCase() + browser.slice(1) %></button>
|
|
411
|
-
<% });
|
|
412
|
-
} %>
|
|
51
|
+
<!-- Browser Tabs Container -->
|
|
52
|
+
<div class="tabs-container" id="summary-tabs-container">
|
|
53
|
+
<button class="tab-btn active" data-target="global">Global</button>
|
|
54
|
+
<!-- Browser tabs injected here -->
|
|
413
55
|
</div>
|
|
56
|
+
<template id="browser-tab-btn-template">
|
|
57
|
+
<button class="tab-btn"></button>
|
|
58
|
+
</template>
|
|
414
59
|
|
|
415
60
|
<!-- Global Tab Content -->
|
|
416
61
|
<div id="tab-global" class="tab-content active">
|
|
417
|
-
<% if (results.totalA11yErrorCount > 0) { %>
|
|
418
|
-
<div style="margin-bottom: 40px;">
|
|
419
|
-
<h2 class="insights-header">
|
|
420
|
-
<span class="material-symbols-outlined" style="color: var(--failed);">report_problem</span>
|
|
421
|
-
Global Accessibility Insights (Deduplicated)
|
|
422
|
-
</h2>
|
|
423
|
-
<div class="metrics-grid">
|
|
424
|
-
<% Object.entries(results.wcagErrors).sort((a,b) => b[1].count - a[1].count).forEach(function([rule, info]) { %>
|
|
425
|
-
<div class="metric-card <%= info.severity %>">
|
|
426
|
-
<div>
|
|
427
|
-
<div class="metric-header">
|
|
428
|
-
<span class="metric-rule"><%= rule %></span>
|
|
429
|
-
<span class="metric-sev <%= info.severity %>"><%= info.severity %></span>
|
|
430
|
-
</div>
|
|
431
|
-
<% if (info.description) { %>
|
|
432
|
-
<div class="metric-desc">
|
|
433
|
-
<%= info.description %>
|
|
434
|
-
</div>
|
|
435
|
-
<% } %>
|
|
436
|
-
</div>
|
|
437
|
-
<div class="metric-footer">
|
|
438
|
-
<div class="metric-count <%= info.severity %>"><%= info.count %></div>
|
|
439
|
-
<% if (info.helpUrl) { %>
|
|
440
|
-
<a href="<%= info.helpUrl %>" target="_blank" class="btn-guide">
|
|
441
|
-
<span class="material-symbols-outlined" style="font-size: 16px;">menu_book</span> Guide
|
|
442
|
-
</a>
|
|
443
|
-
<% } %>
|
|
444
|
-
</div>
|
|
445
|
-
</div>
|
|
446
|
-
<% }); %>
|
|
447
|
-
</div>
|
|
448
|
-
</div>
|
|
449
62
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
63
|
+
<!-- Global Success -->
|
|
64
|
+
<div class="success-verified-card" id="global-success-card" style="display: none;">
|
|
65
|
+
<div class="success-content-layout">
|
|
66
|
+
<div class="success-icon-container">
|
|
67
|
+
<span class="material-symbols-outlined" id="global-success-icon">check_circle</span>
|
|
68
|
+
<div class="icon-pulse"></div>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="success-text-group">
|
|
71
|
+
<h3 class="success-hero-title" id="global-success-title">Compliance Verified</h3>
|
|
72
|
+
<p class="success-hero-desc" id="global-success-desc">Congratulations! No accessibility violations were detected across your audited application.</p>
|
|
73
|
+
<div class="success-badges">
|
|
74
|
+
<span class="success-msg-badge"><span class="material-symbols-outlined">verified</span> 0 Violations Found</span>
|
|
75
|
+
<span class="success-msg-badge"><span class="material-symbols-outlined">health_and_safety</span> 100% Compliant</span>
|
|
461
76
|
</div>
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<!-- Global Errors -->
|
|
82
|
+
<div id="global-errors-container" style="display: none;">
|
|
83
|
+
<div class="metrics-grid" id="global-metrics-grid"></div>
|
|
84
|
+
<div class="chart-box">
|
|
85
|
+
<div class="chart-title">
|
|
86
|
+
Global Violation Distribution
|
|
87
|
+
<div class="chart-legend">
|
|
88
|
+
<span class="legend-item"><span class="legend-dot critical"></span> Critical</span>
|
|
89
|
+
<span class="legend-item"><span class="legend-dot serious"></span> Serious</span>
|
|
90
|
+
<span class="legend-item"><span class="legend-dot moderate"></span> Moderate</span>
|
|
91
|
+
<span class="legend-item"><span class="legend-dot minor"></span> Minor</span>
|
|
477
92
|
</div>
|
|
478
|
-
|
|
93
|
+
</div>
|
|
94
|
+
<div id="chart-global-violations"></div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
479
97
|
</div>
|
|
480
98
|
|
|
481
|
-
<!-- Browser
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
</div>
|
|
502
|
-
<div class="metric-footer">
|
|
503
|
-
<div class="metric-count <%= info.severity %>"><%= info.count %></div>
|
|
504
|
-
</div>
|
|
505
|
-
</div>
|
|
506
|
-
<% }); %>
|
|
507
|
-
</div>
|
|
508
|
-
|
|
509
|
-
<div class="chart-box">
|
|
510
|
-
<div class="chart-title">
|
|
511
|
-
<%= browser.charAt(0).toUpperCase() + browser.slice(1) %> Violations by Rule
|
|
512
|
-
<div class="chart-legend">
|
|
513
|
-
<span class="legend-item"><span class="legend-dot critical"></span> Critical</span>
|
|
514
|
-
<span class="legend-item"><span class="legend-dot serious"></span> Serious</span>
|
|
515
|
-
<span class="legend-item"><span class="legend-dot moderate"></span> Moderate</span>
|
|
516
|
-
<span class="legend-item"><span class="legend-dot minor"></span> Minor</span>
|
|
517
|
-
</div>
|
|
518
|
-
</div>
|
|
519
|
-
<div id="chart-<%= browser %>-violations"></div>
|
|
520
|
-
</div>
|
|
521
|
-
<% } else { %>
|
|
522
|
-
<div class="success-verified-card">
|
|
523
|
-
<span class="material-symbols-outlined success-hero-icon">check_circle</span>
|
|
524
|
-
<h3 class="success-hero-title">No Violations in <%= browser.charAt(0).toUpperCase() + browser.slice(1) %></h3>
|
|
525
|
-
<p class="success-hero-desc">
|
|
526
|
-
Great job! No accessibility issues were found in this browser.
|
|
527
|
-
</p>
|
|
528
|
-
</div>
|
|
529
|
-
<% } %>
|
|
99
|
+
<!-- Browser Tab Content Container -->
|
|
100
|
+
<div id="browser-tabs-content"></div>
|
|
101
|
+
|
|
102
|
+
<template id="browser-tab-content-template">
|
|
103
|
+
<div class="tab-content">
|
|
104
|
+
<!-- Error State -->
|
|
105
|
+
<div class="browser-errors-container" style="display: none;">
|
|
106
|
+
<div class="metrics-grid browser-metrics-grid"></div>
|
|
107
|
+
<div class="chart-box">
|
|
108
|
+
<div class="chart-title">
|
|
109
|
+
<span class="browser-chart-title"></span> Violations by Rule
|
|
110
|
+
<div class="chart-legend">
|
|
111
|
+
<span class="legend-item"><span class="legend-dot critical"></span> Critical</span>
|
|
112
|
+
<span class="legend-item"><span class="legend-dot serious"></span> Serious</span>
|
|
113
|
+
<span class="legend-item"><span class="legend-dot moderate"></span> Moderate</span>
|
|
114
|
+
<span class="legend-item"><span class="legend-dot minor"></span> Minor</span>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
<div class="browser-chart-container"></div>
|
|
118
|
+
</div>
|
|
530
119
|
</div>
|
|
531
|
-
<% });
|
|
532
|
-
} %>
|
|
533
120
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
<
|
|
121
|
+
<!-- Success State -->
|
|
122
|
+
<div class="success-verified-card browser-success-container" style="display: none;">
|
|
123
|
+
<div class="success-content-layout">
|
|
124
|
+
<div class="success-icon-container">
|
|
125
|
+
<span class="material-symbols-outlined success-hero-icon">verified_user</span>
|
|
126
|
+
<div class="icon-pulse"></div>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="success-text-group">
|
|
129
|
+
<h3 class="success-hero-title browser-success-title">Browser Compliant</h3>
|
|
130
|
+
<p class="success-hero-desc">Great job! No accessibility issues were found in this specific browser environment.</p>
|
|
131
|
+
</div>
|
|
542
132
|
</div>
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
<% if (test.a11yErrorCount && test.a11yErrorCount > 0) { %>
|
|
554
|
-
<span class="err-badge">
|
|
555
|
-
<%= test.a11yErrorCount %> errors
|
|
556
|
-
</span>
|
|
557
|
-
<% } else if (test.status === 'failed') { %>
|
|
558
|
-
<span class="err-badge" style="background: #fee2e2; color: #ef4444; border: 1px solid #fecdd3;">
|
|
559
|
-
Functional Error
|
|
560
|
-
</span>
|
|
561
|
-
<% } %>
|
|
562
|
-
<div class="test-dur"><%= test.duration %></div>
|
|
563
|
-
</div>
|
|
564
|
-
</div>
|
|
565
|
-
</a>
|
|
566
|
-
<% }); %>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</template>
|
|
136
|
+
|
|
137
|
+
<template id="wcag-metric-template">
|
|
138
|
+
<div class="metric-card">
|
|
139
|
+
<div>
|
|
140
|
+
<div class="metric-header">
|
|
141
|
+
<span class="metric-rule"></span>
|
|
142
|
+
<span class="metric-sev"></span>
|
|
567
143
|
</div>
|
|
144
|
+
<div class="metric-desc" style="display: none;"></div>
|
|
568
145
|
</div>
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
document.getElementById('tab-' + browserId).classList.add('active');
|
|
578
|
-
btn.classList.add('active');
|
|
579
|
-
|
|
580
|
-
// Filter Test Suite Details
|
|
581
|
-
const allCards = document.querySelectorAll('.test-card');
|
|
582
|
-
allCards.forEach(card => {
|
|
583
|
-
if (browserId === 'global') {
|
|
584
|
-
card.style.display = 'flex';
|
|
585
|
-
} else {
|
|
586
|
-
if (card.getAttribute('data-browser') === browserId) {
|
|
587
|
-
card.style.display = 'flex';
|
|
588
|
-
} else {
|
|
589
|
-
card.style.display = 'none';
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
// Hide empty groups
|
|
595
|
-
document.querySelectorAll('.group-section').forEach(group => {
|
|
596
|
-
const visibleChildren = group.querySelectorAll('.test-card[style="display: flex;"]');
|
|
597
|
-
if (browserId !== 'global' && visibleChildren.length === 0) {
|
|
598
|
-
group.style.display = 'none';
|
|
599
|
-
} else {
|
|
600
|
-
group.style.display = 'block';
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
window.dispatchEvent(new Event('resize'));
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
function formatDate(date) {
|
|
608
|
-
const day = String(date.getDate()).padStart(2, '0');
|
|
609
|
-
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
610
|
-
const month = monthNames[date.getMonth()];
|
|
611
|
-
const year = date.getFullYear();
|
|
612
|
-
let hours = date.getHours();
|
|
613
|
-
const ampm = hours >= 12 ? 'PM' : 'AM';
|
|
614
|
-
hours = hours % 12 || 12;
|
|
615
|
-
const formattedHours = String(hours).padStart(2, '0');
|
|
616
|
-
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
617
|
-
return `${day} ${month} ${year}, ${formattedHours}:${minutes} ${ampm}`;
|
|
618
|
-
}
|
|
619
|
-
document.getElementById("currentDate").textContent = formatDate(new Date());
|
|
620
|
-
|
|
621
|
-
const themeColors = <%- JSON.stringify(colors) %>;
|
|
622
|
-
|
|
623
|
-
// --- Chart Generation Function ---
|
|
624
|
-
function renderBarChart(elementId, wcagData, title) {
|
|
625
|
-
const wcagEntries = Object.entries(wcagData).sort((a, b) => b[1].count - a[1].count);
|
|
626
|
-
if (wcagEntries.length === 0) return;
|
|
627
|
-
|
|
628
|
-
const chartColors = wcagEntries.map(e => themeColors[e[1].severity] || '#ef4444');
|
|
146
|
+
<div class="metric-footer">
|
|
147
|
+
<div class="metric-count"></div>
|
|
148
|
+
<a target="_blank" class="btn-guide" style="display: none;">
|
|
149
|
+
<span class="material-symbols-outlined" style="font-size: 16px;">menu_book</span> Guide
|
|
150
|
+
</a>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</template>
|
|
629
154
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
forceNiceScale: true,
|
|
637
|
-
decimalsInFloat: 0
|
|
638
|
-
},
|
|
639
|
-
yaxis: { labels: { style: { fontWeight: 600, fontSize: '15px' } } },
|
|
640
|
-
colors: chartColors,
|
|
641
|
-
plotOptions: {
|
|
642
|
-
bar: {
|
|
643
|
-
borderRadius: 6,
|
|
644
|
-
horizontal: true,
|
|
645
|
-
barHeight: '70%',
|
|
646
|
-
distributed: true,
|
|
647
|
-
dataLabels: {
|
|
648
|
-
position: 'top'
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
},
|
|
652
|
-
fill: {
|
|
653
|
-
type: 'solid',
|
|
654
|
-
opacity: 1
|
|
655
|
-
},
|
|
656
|
-
states: { hover: { filter: { type: 'darken', value: 0.9 } } },
|
|
657
|
-
grid: {
|
|
658
|
-
borderColor: '#f1f5f9',
|
|
659
|
-
padding: { right: 50, left: 10 }
|
|
660
|
-
},
|
|
661
|
-
dataLabels: {
|
|
662
|
-
enabled: true,
|
|
663
|
-
textAnchor: 'start',
|
|
664
|
-
offsetX: 10,
|
|
665
|
-
style: {
|
|
666
|
-
fontSize: '16px',
|
|
667
|
-
fontWeight: 900,
|
|
668
|
-
colors: ['#0f172a']
|
|
669
|
-
},
|
|
670
|
-
background: { enabled: false },
|
|
671
|
-
dropShadow: { enabled: false }
|
|
672
|
-
},
|
|
673
|
-
legend: { show: false },
|
|
674
|
-
tooltip: { theme: 'light', style: { fontFamily: 'Inter' } }
|
|
675
|
-
}).render();
|
|
676
|
-
}
|
|
155
|
+
<!-- Test Suite Details Accordion -->
|
|
156
|
+
<div class="results-list" style="margin-top: 40px;">
|
|
157
|
+
<h2 style="font-family: 'Outfit', sans-serif; font-size: 1.25rem; margin-bottom: 24px; color: var(--text-main);">
|
|
158
|
+
Test Suite Details</h2>
|
|
159
|
+
<div id="accordion-container"></div>
|
|
160
|
+
</div>
|
|
677
161
|
|
|
678
|
-
|
|
679
|
-
|
|
162
|
+
<template id="group-section-template">
|
|
163
|
+
<div class="group-section">
|
|
164
|
+
<div class="group-header">
|
|
165
|
+
<span class="group-title"></span>
|
|
166
|
+
<span class="material-symbols-outlined group-toggle-icon">expand_more</span>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="group-content"></div>
|
|
169
|
+
</div>
|
|
170
|
+
</template>
|
|
171
|
+
|
|
172
|
+
<template id="test-card-template">
|
|
173
|
+
<a class="test-card" data-browser="">
|
|
174
|
+
<span class="material-symbols-outlined status-icon-small"></span>
|
|
175
|
+
<div class="test-main-info">
|
|
176
|
+
<div class="test-title-group">
|
|
177
|
+
<span class="test-title"></span>
|
|
178
|
+
<span class="browser-chip"></span>
|
|
179
|
+
</div>
|
|
180
|
+
<div class="test-meta">
|
|
181
|
+
<span class="err-badge"
|
|
182
|
+
style="display: none; background: #fee2e2; color: #ef4444; font-size: 0.7rem; font-weight: 800; padding: 2px 8px; border-radius: 6px;"></span>
|
|
183
|
+
<div class="test-dur" style="font-size: 0.8rem; color: var(--text-muted); font-weight: 700;"></div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
</a>
|
|
187
|
+
</template>
|
|
680
188
|
|
|
681
|
-
|
|
682
|
-
<% if (results.browserSummaries) {
|
|
683
|
-
Object.keys(results.browserSummaries).forEach(function(browser) { %>
|
|
684
|
-
renderBarChart('chart-<%= browser %>-violations', <%- JSON.stringify(results.browserSummaries[browser].wcagErrors) %>, '<%= browser %> Violations');
|
|
685
|
-
<% });
|
|
686
|
-
} %>
|
|
687
|
-
</script>
|
|
189
|
+
</div>
|
|
688
190
|
|
|
689
191
|
<footer>
|
|
690
192
|
<div class="powered-by">Generated by <span class="badge-tool">Snap Ally</span></div>
|
|
691
|
-
<div><span style="opacity: 0.7;">©
|
|
193
|
+
<div><span style="opacity: 0.7;">© <span id="year"></span> Snap Ally</span></div>
|
|
692
194
|
</footer>
|
|
195
|
+
|
|
196
|
+
<!-- Scripts -->
|
|
197
|
+
<script>document.getElementById('year').textContent = new Date().getFullYear();</script>
|
|
198
|
+
|
|
199
|
+
<!-- Injected JSON Payload -->
|
|
200
|
+
<script src="data.js"></script>
|
|
201
|
+
|
|
202
|
+
<!-- Report Logic -->
|
|
203
|
+
<script src="report-app.js"></script>
|
|
693
204
|
</body>
|
|
694
|
-
</html>
|
|
695
205
|
|
|
206
|
+
</html>
|