@terra-symposium/standards-reporting 0.0.0-stage → 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.
@@ -0,0 +1,281 @@
1
+ /**
2
+ * packages/reporting/src/slideshow.ts
3
+ * Slideshow evidence writer for screenshot-backed test runs.
4
+ */
5
+ /*//////////////////////////////////////////////////
6
+ IMPORTS
7
+ //////////////////////////////////////////////////*/
8
+ // API
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import sharp from 'sharp';
12
+ import { createRequire } from 'node:module';
13
+ import { loadGradeCounts } from './load-testing.js';
14
+ import { neutralizeApplicationMetadata } from './metadata.js';
15
+ const COLOURS = { accent: '1F4E78', ink: '16202A', line: 'D8DEE6', muted: '52606D', surface: 'F5F7FA' };
16
+ /**
17
+ * Derives visual-review prompts from screenshot dimensions and test diagnostics.
18
+ *
19
+ * @param file Screenshot path used for dimension analysis.
20
+ * @param r Result metadata and diagnostics used to derive review cues.
21
+ * @returns Screenshot dimensions and prompts for visual review.
22
+ */
23
+ const reviewImg = async (file, r) => {
24
+ const metadata = await sharp(file).metadata();
25
+ const width = metadata.width || 0;
26
+ const height = metadata.height || 0;
27
+ const cues = [];
28
+ if (height > width * 2.2)
29
+ cues.push('Long full-page capture: inspect vertical rhythm, repeated whitespace, and section transitions.');
30
+ if (r.viewport !== 'xl')
31
+ cues.push(`Responsive capture: inspect breakpoint changes at ${r.viewportSize}, especially wrapping, navigation, grids, and overflow.`);
32
+ if (r.browserErrors)
33
+ cues.push('Browser diagnostics were captured; check whether the visible surface reflects the reported error.');
34
+ if (r.terminalErrors)
35
+ cues.push('Terminal diagnostics were captured; compare the visible state with the runtime warning or failure.');
36
+ if (r.status !== 'passed')
37
+ cues.push(`Test status is ${r.status}; confirm whether the visible defect is causal or incidental.`);
38
+ if (!cues.length)
39
+ cues.push('Inspect alignment, text wrapping, control density, whitespace, and visual hierarchy for issues not covered by assertions.');
40
+ return { cues, height, width };
41
+ };
42
+ /**
43
+ * Fits an image into a bounded slide region while preserving its aspect ratio.
44
+ *
45
+ * @param width Source image width.
46
+ * @param height Source image height.
47
+ * @param x Left edge of the target region.
48
+ * @param y Top edge of the target region.
49
+ * @param maxWidth Maximum target width.
50
+ * @param maxHeight Maximum target height.
51
+ * @returns Positioned dimensions that fit inside the target region.
52
+ */
53
+ const fitImg = (width, height, x, y, maxWidth, maxHeight) => {
54
+ const scale = Math.min(maxWidth / Math.max(width, 1), maxHeight / Math.max(height, 1));
55
+ const fittedWidth = width * scale;
56
+ const fittedHeight = height * scale;
57
+ return { h: fittedHeight, w: fittedWidth, x: x + (maxWidth - fittedWidth) / 2, y: y + (maxHeight - fittedHeight) / 2 };
58
+ };
59
+ /**
60
+ * Crops a tall screenshot into a slide-friendly preview while retaining the original in notes.
61
+ *
62
+ * @param file Screenshot path to preview.
63
+ * @returns Base64 image data and preview dimensions.
64
+ */
65
+ const previewImg = async (file, viewportSize) => {
66
+ const metadata = await sharp(file).metadata();
67
+ const width = metadata.width || 1;
68
+ const [viewportWidth, viewportHeight] = viewportSize.split('×').map((v) => Number.parseInt(v, 10));
69
+ const viewportPreviewHeight = viewportWidth && viewportHeight ? Math.round((width * viewportHeight) / viewportWidth) : Math.round(width / 0.38);
70
+ const height = Math.min(metadata.height || 1, Math.max(1, viewportPreviewHeight));
71
+ const data = await sharp(file).extract({ height, left: 0, top: 0, width }).png().toBuffer();
72
+ return { data: `data:image/png;base64,${data.toString('base64')}`, height, width };
73
+ };
74
+ /**
75
+ * Sorts responsive results by their rendered viewport width.
76
+ *
77
+ * @param r Result whose viewport label should be parsed.
78
+ * @returns Numeric viewport width, or a final sort value when unavailable.
79
+ */
80
+ const viewportWidth = (r) => Number.parseInt(r.viewportSize.split('×')[0] || '', 10) || Number.MAX_SAFE_INTEGER;
81
+ /**
82
+ * Builds the visible review copy and diagnostics for one result.
83
+ *
84
+ * @param r Result metadata and diagnostics to describe.
85
+ * @param review Screenshot review cues to include.
86
+ * @returns Text shown beside the screenshot and in speaker notes.
87
+ */
88
+ const resultLoadGrade = (r) => {
89
+ const counts = loadGradeCounts(r.loadMeasurements || []);
90
+ return counts.fail ? 'fail' : counts.warning ? 'warning' : counts.pass ? 'pass' : '';
91
+ };
92
+ const slideCopy = (r, review) => {
93
+ const grade = resultLoadGrade(r);
94
+ const measurements = r.loadMeasurements || [];
95
+ const lines = [
96
+ `${r.project} · ${r.viewport} · ${r.viewportSize}`,
97
+ r.groups || r.file,
98
+ `Status: ${r.status}${r.duration ? ` · ${r.duration} ms` : ''}${grade ? ` · Load: ${grade}` : ''}`,
99
+ ...measurements.map((i) => `Load ${i.kind}: ${i.name} — ${i.durationMs.toFixed(1)} ms (${i.grade}; warn ${i.budget.warnMs} / fail ${i.budget.failMs} ms)`),
100
+ '',
101
+ ...review.cues.map((c) => `• ${c}`),
102
+ ];
103
+ if (r.error)
104
+ lines.push('', `Test error: ${r.error}`);
105
+ if (r.browserErrors)
106
+ lines.push('', `Browser: ${r.browserErrors}`);
107
+ if (r.terminalErrors)
108
+ lines.push('', `Terminal: ${r.terminalErrors}`);
109
+ return lines.join('\n');
110
+ };
111
+ /**
112
+ * Adds a single-result slide with its screenshot and review prompts.
113
+ *
114
+ * @param presentation Presentation receiving the slide.
115
+ * @param r Screenshot-backed result to render.
116
+ * @param slideNumber One-based slide number shown in the title.
117
+ * @returns A promise that resolves after the slide and notes are added.
118
+ */
119
+ /**
120
+ * Adds a responsive comparison slide for results sharing one test identity.
121
+ *
122
+ * @param presentation Presentation receiving the slide.
123
+ * @param group Results for the same test across one or more viewports.
124
+ * @param slideNumber One-based slide number shown in the title.
125
+ * @returns A promise that resolves after the comparison slide is added.
126
+ */
127
+ const addResponsiveSlide = async (presentation, group, slideNumber) => {
128
+ const first = group[0];
129
+ if (!first)
130
+ return;
131
+ const slide = presentation.addSlide();
132
+ slide.background = { color: COLOURS.surface };
133
+ slide.addText(`${String(slideNumber).padStart(3, '0')} ${first.title}`, {
134
+ bold: true,
135
+ color: COLOURS.ink,
136
+ fit: 'shrink',
137
+ fontFace: 'Aptos Display',
138
+ fontSize: 18,
139
+ margin: 0,
140
+ x: 0.38,
141
+ y: 0.22,
142
+ w: 12.55,
143
+ h: 0.34,
144
+ });
145
+ slide.addText(`${first.project} · responsive comparison · ${first.groups || first.file}`, { color: COLOURS.muted, fontFace: 'Aptos', fontSize: 8.5, margin: 0, x: 0.38, y: 0.62, w: 12.55, h: 0.2 });
146
+ slide.addShape(presentation.ShapeType.line, { line: { color: COLOURS.line, width: 1 }, x: 0.38, y: 0.9, w: 12.55, h: 0 });
147
+ const notes = [];
148
+ const gap = 0.12;
149
+ const cols = Math.min(3, group.length);
150
+ const rows = Math.ceil(group.length / cols);
151
+ const width = (12.55 - gap * (cols - 1)) / cols;
152
+ const height = (6.02 - gap * (rows - 1)) / rows;
153
+ for (const [idx, r] of group.entries()) {
154
+ const col = idx % cols;
155
+ const row = Math.floor(idx / cols);
156
+ const x = 0.38 + col * (width + gap);
157
+ const y = 1.02 + row * (height + gap);
158
+ slide.addShape(presentation.ShapeType.roundRect, { fill: { color: 'FFFFFF' }, line: { color: COLOURS.line, width: 1 }, x, y, w: width, h: height, rectRadius: 0.04 });
159
+ const loadGrade = resultLoadGrade(r);
160
+ slide.addText(`${r.viewport} · ${r.viewportSize} · ${r.status}${loadGrade ? ` · Load ${loadGrade}` : ''}`, {
161
+ bold: true,
162
+ color: COLOURS.accent,
163
+ fontFace: 'Aptos',
164
+ fontSize: 7.2,
165
+ margin: 0,
166
+ x: x + 0.12,
167
+ y: y + 0.1,
168
+ w: width - 0.24,
169
+ h: 0.2,
170
+ });
171
+ if (r.screenshot && fs.existsSync(r.screenshot)) {
172
+ const review = await reviewImg(r.screenshot, r);
173
+ const preview = await previewImg(r.screenshot, r.viewportSize);
174
+ slide.addImage({ data: preview.data, ...fitImg(preview.width, preview.height, x + 0.08, y + 0.38, width - 0.16, height - 0.46) });
175
+ notes.push(`${r.viewport}: full-page screenshot images/${path.basename(r.screenshot)}\n${slideCopy(r, review)}`);
176
+ }
177
+ else {
178
+ slide.addText('SCREENSHOT MISSING', { align: 'center', bold: true, color: '9A3412', fontFace: 'Aptos', fontSize: 12, x: x + 0.2, y: y + height / 2 - 0.14, w: width - 0.4, h: 0.28 });
179
+ notes.push(`${r.viewport}: no screenshot captured`);
180
+ }
181
+ }
182
+ slide.addNotes(notes.join('\n\n'));
183
+ };
184
+ /** Adds a run-level load summary slide and names the slowest measurements. */
185
+ const addLoadSummarySlide = (presentation, results) => {
186
+ const measurements = results.flatMap((r) => (r.loadMeasurements || []).map((measurement) => ({ result: r, measurement })));
187
+ const counts = loadGradeCounts(measurements.map(({ measurement }) => measurement));
188
+ const slowest = [...measurements].sort((a, b) => b.measurement.durationMs - a.measurement.durationMs).slice(0, 6);
189
+ const slide = presentation.addSlide();
190
+ slide.background = { color: COLOURS.surface };
191
+ slide.addText('Load timing summary', { bold: true, color: COLOURS.ink, fontFace: 'Aptos Display', fontSize: 26, margin: 0, x: 0.55, y: 0.45, w: 12.2, h: 0.5 });
192
+ slide.addText(`${measurements.length} measurements · ${counts.pass} pass · ${counts.warning} warning · ${counts.fail} fail`, {
193
+ bold: true,
194
+ color: COLOURS.accent,
195
+ fontFace: 'Aptos',
196
+ fontSize: 17,
197
+ margin: 0,
198
+ x: 0.58,
199
+ y: 1.28,
200
+ w: 12.1,
201
+ h: 0.35,
202
+ });
203
+ slide.addText(slowest.length
204
+ ? `Slowest measurements\n${slowest.map(({ result: r, measurement }) => `${measurement.grade.toUpperCase()} ${measurement.durationMs.toFixed(1)} ms ${r.file} · ${r.title} · ${measurement.name}`).join('\n')}`
205
+ : 'No load measurements were collected.', { color: COLOURS.ink, fontFace: 'Aptos', fontSize: 13, fit: 'shrink', margin: 0.08, valign: 'mid', x: 0.58, y: 2.05, w: 12.1, h: 4.3 });
206
+ };
207
+ /** Adds paginated slides containing every individual test, page, and operation measurement. */
208
+ const addLoadDetailSlides = (presentation, results) => {
209
+ const measurements = results.flatMap((r) => (r.loadMeasurements || []).map((measurement) => ({ result: r, measurement })));
210
+ const pageSize = 12;
211
+ const pages = Math.max(1, Math.ceil(measurements.length / pageSize));
212
+ for (let page = 0; page < pages; page += 1) {
213
+ const lines = measurements
214
+ .slice(page * pageSize, (page + 1) * pageSize)
215
+ .map(({ result: r, measurement }) => `${measurement.grade.toUpperCase().padEnd(7)} ${measurement.durationMs.toFixed(1).padStart(9)} ms ${measurement.kind.padEnd(9)} ${r.file} · ${r.title} · ${measurement.name} [warn ${measurement.budget.warnMs} / fail ${measurement.budget.failMs} ms]`);
216
+ const slide = presentation.addSlide();
217
+ slide.background = { color: COLOURS.surface };
218
+ slide.addText(`Load timing details ${page + 1}/${pages}`, { bold: true, color: COLOURS.ink, fontFace: 'Aptos Display', fontSize: 22, margin: 0, x: 0.55, y: 0.4, w: 12.2, h: 0.45 });
219
+ slide.addText(lines.join('\n') || 'No load measurements were collected.', {
220
+ color: COLOURS.ink,
221
+ fontFace: 'Aptos',
222
+ fontSize: 11,
223
+ fit: 'shrink',
224
+ margin: 0.08,
225
+ valign: 'mid',
226
+ x: 0.55,
227
+ y: 1.05,
228
+ w: 12.2,
229
+ h: 5.95,
230
+ });
231
+ }
232
+ return pages;
233
+ };
234
+ /**
235
+ * Writes screenshot-backed results as single-viewport or responsive review slides.
236
+ *
237
+ * @param file Output path for the slideshow artifact.
238
+ * @param results Normalized results to group and render.
239
+ * @param opts Optional visible title and document metadata overrides.
240
+ * @returns A promise that resolves after the slideshow has been written.
241
+ */
242
+ export const writeSlideshow = async (file, results, opts = {}) => {
243
+ const loadEnabled = opts.loadTestingEnabled ?? results.some((r) => !!r.loadMeasurements?.length);
244
+ const presentation = new /* The runtime package is CommonJS while NodeNext exposes its constructor through a namespace type. */ (createRequire(import.meta.url)('pptxgenjs'))();
245
+ presentation.layout = 'LAYOUT_WIDE';
246
+ presentation.author = opts.author || 'Test evidence reporter';
247
+ presentation.company = opts.company || 'Test evidence';
248
+ presentation.subject = opts.subject || 'Screenshot evidence and UI review prompts';
249
+ presentation.title = opts.title || 'Test evidence slideshow';
250
+ let slideNumber = 0;
251
+ if (loadEnabled) {
252
+ addLoadSummarySlide(presentation, results);
253
+ slideNumber += 1;
254
+ }
255
+ const groups = new Map();
256
+ for (const r of results) {
257
+ const key = [r.project, r.file, r.groups, r.title].join('|');
258
+ groups.set(key, [...(groups.get(key) || []), r]);
259
+ }
260
+ for (const group of groups.values()) {
261
+ const byViewport = new Map();
262
+ for (const result of group) {
263
+ const prev = byViewport.get(result.viewport);
264
+ if (!prev || result.retry >= prev.retry)
265
+ byViewport.set(result.viewport, result);
266
+ }
267
+ const ordered = [...byViewport.values()].sort((a, b) => viewportWidth(a) - viewportWidth(b));
268
+ await addResponsiveSlide(presentation, ordered, ++slideNumber);
269
+ }
270
+ if (!slideNumber) {
271
+ const slide = presentation.addSlide();
272
+ slide.background = { color: COLOURS.surface };
273
+ slide.addText('Test evidence slideshow', { align: 'center', bold: true, color: COLOURS.accent, fontFace: 'Aptos Display', fontSize: 30, x: 0.8, y: 2.6, w: 11.7, h: 0.6 });
274
+ slide.addText('No browser test results were collected in this run.', { align: 'center', color: COLOURS.muted, fontFace: 'Aptos', fontSize: 16, x: 1.2, y: 3.35, w: 10.9, h: 0.5 });
275
+ }
276
+ if (loadEnabled)
277
+ addLoadDetailSlides(presentation, results);
278
+ await presentation.writeFile({ fileName: file });
279
+ await neutralizeApplicationMetadata(file);
280
+ };
281
+ //# sourceMappingURL=slideshow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slideshow.js","sourceRoot":"","sources":["../src/slideshow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * packages/reporting/src/spreadsheet.ts
3
+ * Spreadsheet evidence writer for Playwright test runs.
4
+ */
5
+ import type { ReportRun } from './core.js';
6
+ /**
7
+ * Writes the neutral spreadsheet artifact for a normalized report run.
8
+ *
9
+ * @param file Output path for the spreadsheet artifact.
10
+ * @param run Normalized results, project metadata, and diagnostics to write.
11
+ * @returns A promise that resolves after the workbook has been written.
12
+ */
13
+ export declare const writeSpreadsheet: (file: string, run: ReportRun) => Promise<void>;
14
+ //# sourceMappingURL=spreadsheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spreadsheet.d.ts","sourceRoot":"","sources":["../src/spreadsheet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,WAAW,CAAC;AA+OzD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,MAAM,EAAE,KAAK,SAAS,KAAG,OAAO,CAAC,IAAI,CAgBjF,CAAC"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * packages/reporting/src/spreadsheet.ts
3
+ * Spreadsheet evidence writer for Playwright test runs.
4
+ */
5
+ /*//////////////////////////////////////////////////
6
+ IMPORTS
7
+ //////////////////////////////////////////////////*/
8
+ // API
9
+ import fs from 'node:fs';
10
+ import { diagnosticCount, orderedFiles, resultsForFile, statusCounts, statusLabel } from './core.js';
11
+ import { loadGradeCounts } from './load-testing.js';
12
+ import { neutralizeApplicationMetadata } from './metadata.js';
13
+ // COMPONENTS
14
+ import ExcelJS from 'exceljs';
15
+ // DATA
16
+ import { VISUAL_STATUSES } from './core.js';
17
+ /*//////////////////////////////////////////////////
18
+ CONFIG
19
+ //////////////////////////////////////////////////*/
20
+ const STATUS_STYLES = {
21
+ passed: { fill: 'FFDCEFE0', font: 'FF166534' },
22
+ failed: { fill: 'FFFEE2E2', font: 'FF991B1B' },
23
+ timedOut: { fill: 'FFFEE2E2', font: 'FF991B1B' },
24
+ interrupted: { fill: 'FFFEE2E2', font: 'FF991B1B' },
25
+ skipped: { fill: 'FFFEF3C7', font: 'FF92400E' },
26
+ };
27
+ const LOAD_STYLES = {
28
+ pass: { fill: 'FFDCEFE0', font: 'FF166534' },
29
+ warning: { fill: 'FFFEF3C7', font: 'FF92400E' },
30
+ fail: { fill: 'FFFEE2E2', font: 'FF991B1B' },
31
+ };
32
+ /**
33
+ * Applies the shared header layout to a worksheet.
34
+ *
35
+ * @param sheet Worksheet whose header and columns should be styled.
36
+ * @returns Nothing; the worksheet is mutated in place.
37
+ */
38
+ const styleHeader = (sheet) => {
39
+ sheet.views = [{ showGridLines: false, state: 'frozen', ySplit: 1 }];
40
+ sheet.columns = [{ width: 18 }, { width: 24 }, { width: 42 }, { width: 12 }, { width: 14 }, { width: 12 }, { width: 12 }, { width: 8 }, { width: 28 }, { width: 14 }, { width: 14 }, { width: 18 }];
41
+ sheet.getRow(1).font = { bold: true, color: { argb: 'FFFFFFFF' } };
42
+ sheet.getRow(1).fill = { fgColor: { argb: 'FF1F4E78' }, pattern: 'solid', type: 'pattern' };
43
+ sheet.getRow(1).alignment = { vertical: 'middle' };
44
+ sheet.getRow(1).height = 22;
45
+ };
46
+ /**
47
+ * Applies the status label and its semantic color treatment to a cell.
48
+ *
49
+ * @param cell Cell that will display the status.
50
+ * @param status Normalized status key used to select the style.
51
+ * @returns Nothing; the cell is mutated in place.
52
+ */
53
+ const styleStatus = (cell, status) => {
54
+ const style = STATUS_STYLES[status] || STATUS_STYLES.failed;
55
+ cell.value = statusLabel(status);
56
+ cell.fill = { fgColor: { argb: style.fill }, pattern: 'solid', type: 'pattern' };
57
+ cell.font = { bold: true, color: { argb: style.font } };
58
+ cell.alignment = { horizontal: 'center', vertical: 'middle' };
59
+ cell.border = {
60
+ bottom: { color: { argb: style.font }, style: 'thin' },
61
+ left: { color: { argb: style.font }, style: 'thin' },
62
+ right: { color: { argb: style.font }, style: 'thin' },
63
+ top: { color: { argb: style.font }, style: 'thin' },
64
+ };
65
+ };
66
+ /** Applies a timing grade and its semantic color treatment to a cell. */
67
+ const styleLoadGrade = (cell, grade) => {
68
+ const style = LOAD_STYLES[grade] || LOAD_STYLES.fail;
69
+ cell.value = grade;
70
+ cell.fill = { fgColor: { argb: style.fill }, pattern: 'solid', type: 'pattern' };
71
+ cell.font = { bold: true, color: { argb: style.font } };
72
+ cell.alignment = { horizontal: 'center', vertical: 'middle' };
73
+ };
74
+ /**
75
+ * Adds one feature-file result sheet, including available screenshot evidence.
76
+ *
77
+ * @param book Workbook receiving the sheet.
78
+ * @param name Feature-file name used as the worksheet name.
79
+ * @param vals Results belonging to the feature file.
80
+ * @returns Nothing; the workbook is mutated in place.
81
+ */
82
+ const resultSheetName = (book, src) => {
83
+ const base = [...src]
84
+ .map((c) => ('\\/:*?[]'.includes(c) ? '_' : c))
85
+ .join('')
86
+ .replace(/^'+|'+$/g, '')
87
+ .slice(0, 31) || 'Results';
88
+ const reserved = new Set(['summary', 'projects', 'run diagnostics']);
89
+ const used = new Set([...book.worksheets.map((s) => s.name.toLowerCase()), ...reserved]);
90
+ let name = base;
91
+ let suffix = 2;
92
+ while (used.has(name.toLowerCase())) {
93
+ const label = ` (${suffix++})`;
94
+ name = `${base.slice(0, 31 - label.length)}${label}`;
95
+ }
96
+ return name;
97
+ };
98
+ const resultLoadGrade = (val) => {
99
+ const counts = loadGradeCounts(val.loadMeasurements || []);
100
+ return counts.fail ? 'fail' : counts.warning ? 'warning' : counts.pass ? 'pass' : '';
101
+ };
102
+ const addResultSheet = (book, name, vals, loadEnabled) => {
103
+ const sheet = book.addWorksheet(resultSheetName(book, name));
104
+ sheet.addRow([
105
+ 'Project',
106
+ 'Groups',
107
+ 'Test title',
108
+ 'Viewport',
109
+ 'Viewport size',
110
+ 'Status',
111
+ ...(loadEnabled ? ['Load grade'] : []),
112
+ 'Duration (ms)',
113
+ 'Retries',
114
+ 'Error',
115
+ 'Browser errors',
116
+ 'Terminal errors',
117
+ 'Evidence',
118
+ ]);
119
+ styleHeader(sheet);
120
+ if (loadEnabled)
121
+ sheet.columns = [
122
+ { width: 18 },
123
+ { width: 24 },
124
+ { width: 42 },
125
+ { width: 12 },
126
+ { width: 14 },
127
+ { width: 12 },
128
+ { width: 12 },
129
+ { width: 14 },
130
+ { width: 8 },
131
+ { width: 28 },
132
+ { width: 14 },
133
+ { width: 14 },
134
+ { width: 18 },
135
+ ];
136
+ for (const val of vals) {
137
+ const row = sheet.addRow([
138
+ val.project,
139
+ val.groups,
140
+ val.title,
141
+ val.viewport,
142
+ val.viewportSize,
143
+ statusLabel(val.status),
144
+ ...(loadEnabled ? [resultLoadGrade(val)] : []),
145
+ val.duration,
146
+ val.retry,
147
+ val.error,
148
+ diagnosticCount(val.browserErrors),
149
+ diagnosticCount(val.terminalErrors),
150
+ val.visual === 'Embedded' ? '' : val.visual,
151
+ ]);
152
+ row.alignment = { vertical: 'top' };
153
+ const durationCol = loadEnabled ? 8 : 7;
154
+ const retryCol = loadEnabled ? 9 : 8;
155
+ row.getCell(durationCol).numFmt = '0';
156
+ row.getCell(retryCol).numFmt = '0';
157
+ styleStatus(row.getCell(6), val.status);
158
+ if (loadEnabled && resultLoadGrade(val))
159
+ styleLoadGrade(row.getCell(7), resultLoadGrade(val));
160
+ if (val.browserErrors)
161
+ row.getCell(loadEnabled ? 11 : 10).note = val.browserErrors;
162
+ if (val.terminalErrors)
163
+ row.getCell(loadEnabled ? 12 : 11).note = val.terminalErrors;
164
+ if (!val.screenshot || !fs.existsSync(val.screenshot))
165
+ continue;
166
+ const img = fs.readFileSync(val.screenshot);
167
+ const width = img.readUInt32BE(16);
168
+ const height = img.readUInt32BE(20);
169
+ const scale = Math.min(180 / width, 135 / height);
170
+ const size = { height: Math.round(height * scale), width: Math.round(width * scale) };
171
+ row.height = Math.ceil(size.height * 0.75) + 6;
172
+ sheet.addImage(book.addImage({ buffer: img, extension: 'png' }), { editAs: 'oneCell', ext: size, tl: { col: loadEnabled ? 12 : 11, row: row.number - 1 } });
173
+ }
174
+ };
175
+ /**
176
+ * Adds the file-level status summary for the run.
177
+ *
178
+ * @param book Workbook receiving the summary sheet.
179
+ * @param run Normalized report run to summarize.
180
+ * @returns Nothing; the workbook is mutated in place.
181
+ */
182
+ const addSummary = (book, run, loadEnabled) => {
183
+ const sheet = book.addWorksheet('Summary');
184
+ sheet.addRow(['File', 'Passed', 'Failed', 'Timed out', 'Skipped', 'Interrupted', 'Total', ...(loadEnabled ? ['Load passes', 'Load warnings', 'Load failures'] : [])]);
185
+ for (const file of orderedFiles(run)) {
186
+ const vals = resultsForFile(run, file);
187
+ const counts = statusCounts(vals);
188
+ const loadCounts = loadGradeCounts(vals.flatMap((r) => r.loadMeasurements || []));
189
+ sheet.addRow([file, ...VISUAL_STATUSES.map((s) => counts[s]), VISUAL_STATUSES.reduce((t, s) => t + counts[s], 0), ...(loadEnabled ? [loadCounts.pass, loadCounts.warning, loadCounts.fail] : [])]);
190
+ }
191
+ styleHeader(sheet);
192
+ sheet.columns = [{ width: 32 }, ...Array.from({ length: loadEnabled ? 9 : 6 }, () => ({ width: 14 }))];
193
+ };
194
+ /** Adds a row for every timed test, page navigation, and named operation. */
195
+ const addLoadTimings = (book, results) => {
196
+ const sheet = book.addWorksheet('Load timings');
197
+ sheet.addRow(['File', 'Test title', 'Project', 'Viewport', 'Kind', 'Measurement', 'Duration (ms)', 'Warn at (ms)', 'Fail at (ms)', 'Grade']);
198
+ for (const result of results) {
199
+ for (const measurement of result.loadMeasurements || []) {
200
+ const row = sheet.addRow([
201
+ result.file,
202
+ result.title,
203
+ result.project,
204
+ result.viewport,
205
+ measurement.kind,
206
+ measurement.name,
207
+ measurement.durationMs,
208
+ measurement.budget.warnMs,
209
+ measurement.budget.failMs,
210
+ measurement.grade,
211
+ ]);
212
+ row.getCell(7).numFmt = '0.0';
213
+ row.getCell(8).numFmt = '0';
214
+ row.getCell(9).numFmt = '0';
215
+ styleLoadGrade(row.getCell(10), measurement.grade);
216
+ row.alignment = { vertical: 'top' };
217
+ }
218
+ }
219
+ sheet.columns = [{ width: 32 }, { width: 42 }, { width: 24 }, { width: 12 }, { width: 14 }, { width: 42 }, { width: 16 }, { width: 16 }, { width: 16 }, { width: 14 }];
220
+ styleHeader(sheet);
221
+ };
222
+ /**
223
+ * Adds project configuration and status totals for the run.
224
+ *
225
+ * @param book Workbook receiving the project sheet.
226
+ * @param run Normalized report run to summarize.
227
+ * @returns Nothing; the workbook is mutated in place.
228
+ */
229
+ const addProjects = (book, run) => {
230
+ const sheet = book.addWorksheet('Projects');
231
+ sheet.addRow(['Project', 'Configured files', 'Passed', 'Failed', 'Timed out', 'Skipped', 'Interrupted', 'Total']);
232
+ for (const project of run.projects) {
233
+ const counts = statusCounts(run.results.filter((r) => r.project === project.name));
234
+ sheet.addRow([project.name, project.configuredFiles.join(', '), ...VISUAL_STATUSES.map((s) => counts[s]), VISUAL_STATUSES.reduce((t, s) => t + counts[s], 0)]);
235
+ }
236
+ sheet.columns = [{ width: 30 }, { width: 48 }, ...Array.from({ length: 6 }, () => ({ width: 14 }))];
237
+ styleHeader(sheet);
238
+ for (const row of sheet.getRows(2, sheet.rowCount) || [])
239
+ row.alignment = { vertical: 'top', wrapText: true };
240
+ };
241
+ /**
242
+ * Adds run-level terminal diagnostics, including an explicit empty-run row.
243
+ *
244
+ * @param book Workbook receiving the diagnostics sheet.
245
+ * @param run Normalized report run whose diagnostics should be written.
246
+ * @returns Nothing; the workbook is mutated in place.
247
+ */
248
+ const addDiagnostics = (book, run) => {
249
+ const sheet = book.addWorksheet('Run diagnostics');
250
+ sheet.addRow(['Source', 'Message']);
251
+ for (const val of run.runDiagnostics)
252
+ sheet.addRow(['Terminal', val]);
253
+ if (!run.runDiagnostics.length)
254
+ sheet.addRow(['Run', 'No run-level diagnostics captured.']);
255
+ sheet.columns = [{ width: 18 }, { width: 120 }];
256
+ styleHeader(sheet);
257
+ for (const row of sheet.getRows(2, sheet.rowCount) || [])
258
+ row.alignment = { vertical: 'top', wrapText: true };
259
+ };
260
+ /**
261
+ * Writes the neutral spreadsheet artifact for a normalized report run.
262
+ *
263
+ * @param file Output path for the spreadsheet artifact.
264
+ * @param run Normalized results, project metadata, and diagnostics to write.
265
+ * @returns A promise that resolves after the workbook has been written.
266
+ */
267
+ export const writeSpreadsheet = async (file, run) => {
268
+ const loadEnabled = run.loadTestingEnabled ?? run.results.some((r) => !!r.loadMeasurements?.length);
269
+ const book = new ExcelJS.Workbook();
270
+ book.creator = 'Test evidence reporter';
271
+ book.lastModifiedBy = 'Test evidence reporter';
272
+ book.title = 'Test evidence spreadsheet';
273
+ book.subject = 'Test evidence and diagnostics';
274
+ book.description = 'Spreadsheet evidence from an automated test run.';
275
+ addSummary(book, run, loadEnabled);
276
+ for (const fileName of orderedFiles(run))
277
+ addResultSheet(book, fileName, resultsForFile(run, fileName), loadEnabled);
278
+ if (loadEnabled)
279
+ addLoadTimings(book, run.results);
280
+ addProjects(book, run);
281
+ addDiagnostics(book, run);
282
+ book.views = [{ x: 0, y: 0, width: 19200, height: 10800, visibility: 'visible', activeTab: 0, firstSheet: 0 }];
283
+ await book.xlsx.writeFile(file);
284
+ await neutralizeApplicationMetadata(file);
285
+ };
286
+ //# sourceMappingURL=spreadsheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spreadsheet.js","sourceRoot":"","sources":["../src/spreadsheet.ts"],"names":[],"mappings":"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"}