@vizzly-testing/cli 0.20.1-beta.0 → 0.20.1-beta.1
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/cli.js +177 -2
- package/dist/client/index.js +144 -77
- package/dist/commands/doctor.js +118 -33
- package/dist/commands/finalize.js +8 -3
- package/dist/commands/init.js +13 -18
- package/dist/commands/login.js +42 -49
- package/dist/commands/logout.js +13 -5
- package/dist/commands/project.js +95 -67
- package/dist/commands/run.js +32 -6
- package/dist/commands/status.js +81 -50
- package/dist/commands/tdd-daemon.js +61 -32
- package/dist/commands/tdd.js +4 -25
- package/dist/commands/upload.js +18 -9
- package/dist/commands/whoami.js +40 -38
- package/dist/reporter/reporter-bundle.css +1 -1
- package/dist/reporter/reporter-bundle.iife.js +11 -11
- package/dist/server/handlers/tdd-handler.js +113 -7
- package/dist/server/http-server.js +9 -3
- package/dist/server/routers/baseline.js +58 -0
- package/dist/server/routers/dashboard.js +10 -6
- package/dist/server/routers/screenshot.js +32 -0
- package/dist/server-manager/core.js +5 -2
- package/dist/server-manager/operations.js +2 -1
- package/dist/tdd/tdd-service.js +190 -126
- package/dist/types/client.d.ts +25 -2
- package/dist/utils/colors.js +187 -39
- package/dist/utils/config-loader.js +3 -6
- package/dist/utils/context.js +228 -0
- package/dist/utils/output.js +449 -14
- package/docs/api-reference.md +173 -8
- package/docs/tui-elements.md +560 -0
- package/package.json +12 -7
- package/dist/report-generator/core.js +0 -315
- package/dist/report-generator/index.js +0 -8
- package/dist/report-generator/operations.js +0 -196
- package/dist/services/static-report-generator.js +0 -65
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Report Generator Core - Pure functions for report generation
|
|
3
|
-
*
|
|
4
|
-
* No I/O, no side effects - just data transformations.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { join } from 'node:path';
|
|
8
|
-
|
|
9
|
-
// ============================================================================
|
|
10
|
-
// Constants
|
|
11
|
-
// ============================================================================
|
|
12
|
-
|
|
13
|
-
export const DEFAULT_REPORT_DIR_NAME = 'report';
|
|
14
|
-
export const BUNDLE_FILENAME = 'reporter-bundle.js';
|
|
15
|
-
export const CSS_FILENAME = 'reporter-bundle.css';
|
|
16
|
-
export const INDEX_FILENAME = 'index.html';
|
|
17
|
-
|
|
18
|
-
// ============================================================================
|
|
19
|
-
// Path Building
|
|
20
|
-
// ============================================================================
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Build report directory path
|
|
24
|
-
* @param {string} workingDir - Working directory
|
|
25
|
-
* @returns {string} Report directory path
|
|
26
|
-
*/
|
|
27
|
-
export function buildReportDir(workingDir) {
|
|
28
|
-
return join(workingDir, '.vizzly', DEFAULT_REPORT_DIR_NAME);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Build report HTML path
|
|
33
|
-
* @param {string} reportDir - Report directory
|
|
34
|
-
* @returns {string} Report HTML path
|
|
35
|
-
*/
|
|
36
|
-
export function buildReportPath(reportDir) {
|
|
37
|
-
return join(reportDir, INDEX_FILENAME);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Build bundle source paths
|
|
42
|
-
* @param {string} projectRoot - Project root directory
|
|
43
|
-
* @returns {{ bundlePath: string, cssPath: string }}
|
|
44
|
-
*/
|
|
45
|
-
export function buildBundleSourcePaths(projectRoot) {
|
|
46
|
-
return {
|
|
47
|
-
bundlePath: join(projectRoot, 'dist', 'reporter', 'reporter-bundle.iife.js'),
|
|
48
|
-
cssPath: join(projectRoot, 'dist', 'reporter', 'reporter-bundle.css')
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Build bundle destination paths
|
|
54
|
-
* @param {string} reportDir - Report directory
|
|
55
|
-
* @returns {{ bundleDest: string, cssDest: string }}
|
|
56
|
-
*/
|
|
57
|
-
export function buildBundleDestPaths(reportDir) {
|
|
58
|
-
return {
|
|
59
|
-
bundleDest: join(reportDir, BUNDLE_FILENAME),
|
|
60
|
-
cssDest: join(reportDir, CSS_FILENAME)
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ============================================================================
|
|
65
|
-
// Validation
|
|
66
|
-
// ============================================================================
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Validate report data
|
|
70
|
-
* @param {any} reportData - Report data to validate
|
|
71
|
-
* @returns {{ valid: boolean, error: string|null }}
|
|
72
|
-
*/
|
|
73
|
-
export function validateReportData(reportData) {
|
|
74
|
-
if (!reportData || typeof reportData !== 'object') {
|
|
75
|
-
return {
|
|
76
|
-
valid: false,
|
|
77
|
-
error: 'Invalid report data provided'
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
valid: true,
|
|
82
|
-
error: null
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Check if bundles exist
|
|
88
|
-
* @param {boolean} bundleExists - Whether bundle JS exists
|
|
89
|
-
* @param {boolean} cssExists - Whether bundle CSS exists
|
|
90
|
-
* @returns {{ valid: boolean, error: string|null }}
|
|
91
|
-
*/
|
|
92
|
-
export function validateBundlesExist(bundleExists, cssExists) {
|
|
93
|
-
if (!bundleExists || !cssExists) {
|
|
94
|
-
return {
|
|
95
|
-
valid: false,
|
|
96
|
-
error: 'Reporter bundles not found. Run "npm run build:reporter" first.'
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
return {
|
|
100
|
-
valid: true,
|
|
101
|
-
error: null
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// ============================================================================
|
|
106
|
-
// Data Serialization
|
|
107
|
-
// ============================================================================
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Safely serialize data for embedding in HTML script tag
|
|
111
|
-
* Escapes characters that could break out of script context
|
|
112
|
-
* @param {Object} data - Data to serialize
|
|
113
|
-
* @returns {string} Safely serialized JSON string
|
|
114
|
-
*/
|
|
115
|
-
export function serializeForHtml(data) {
|
|
116
|
-
return JSON.stringify(data).replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ============================================================================
|
|
120
|
-
// HTML Template Generation
|
|
121
|
-
// ============================================================================
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Generate the main HTML template with React reporter
|
|
125
|
-
* @param {Object} options - Template options
|
|
126
|
-
* @param {string} options.serializedData - Serialized report data
|
|
127
|
-
* @param {string} options.timestamp - ISO timestamp string
|
|
128
|
-
* @param {string} options.displayDate - Human-readable date string
|
|
129
|
-
* @returns {string} HTML content
|
|
130
|
-
*/
|
|
131
|
-
export function generateMainTemplate({
|
|
132
|
-
serializedData,
|
|
133
|
-
timestamp,
|
|
134
|
-
displayDate
|
|
135
|
-
}) {
|
|
136
|
-
return `<!DOCTYPE html>
|
|
137
|
-
<html lang="en">
|
|
138
|
-
<head>
|
|
139
|
-
<meta charset="UTF-8">
|
|
140
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
141
|
-
<title>Vizzly Dev Report - ${displayDate}</title>
|
|
142
|
-
<link rel="stylesheet" href="./reporter-bundle.css">
|
|
143
|
-
<style>
|
|
144
|
-
/* Loading spinner styles */
|
|
145
|
-
.reporter-loading {
|
|
146
|
-
display: flex;
|
|
147
|
-
align-items: center;
|
|
148
|
-
justify-content: center;
|
|
149
|
-
min-height: 100vh;
|
|
150
|
-
background: #0f172a;
|
|
151
|
-
color: #f59e0b;
|
|
152
|
-
}
|
|
153
|
-
.spinner {
|
|
154
|
-
width: 48px;
|
|
155
|
-
height: 48px;
|
|
156
|
-
border: 4px solid rgba(245, 158, 11, 0.2);
|
|
157
|
-
border-top-color: #f59e0b;
|
|
158
|
-
border-radius: 50%;
|
|
159
|
-
animation: spin 1s linear infinite;
|
|
160
|
-
margin-bottom: 1rem;
|
|
161
|
-
}
|
|
162
|
-
@keyframes spin {
|
|
163
|
-
to { transform: rotate(360deg); }
|
|
164
|
-
}
|
|
165
|
-
</style>
|
|
166
|
-
</head>
|
|
167
|
-
<body>
|
|
168
|
-
<div id="vizzly-reporter-root">
|
|
169
|
-
<div class="reporter-loading">
|
|
170
|
-
<div style="text-align: center;">
|
|
171
|
-
<div class="spinner"></div>
|
|
172
|
-
<p>Loading Vizzly Report...</p>
|
|
173
|
-
</div>
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
|
|
177
|
-
<script>
|
|
178
|
-
// Embedded report data (static mode)
|
|
179
|
-
window.VIZZLY_REPORTER_DATA = ${serializedData};
|
|
180
|
-
window.VIZZLY_STATIC_MODE = true;
|
|
181
|
-
|
|
182
|
-
// Generate timestamp for "generated at" display
|
|
183
|
-
window.VIZZLY_REPORT_GENERATED_AT = "${timestamp}";
|
|
184
|
-
|
|
185
|
-
console.log('Vizzly Static Report loaded');
|
|
186
|
-
console.log('Report data:', window.VIZZLY_REPORTER_DATA?.summary);
|
|
187
|
-
</script>
|
|
188
|
-
<script src="./reporter-bundle.js"></script>
|
|
189
|
-
</body>
|
|
190
|
-
</html>`;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Generate fallback HTML template (when bundles are missing)
|
|
195
|
-
* @param {Object} options - Template options
|
|
196
|
-
* @param {Object} options.summary - Report summary
|
|
197
|
-
* @param {Array} options.comparisons - Comparison results
|
|
198
|
-
* @param {string} options.displayDate - Human-readable date string
|
|
199
|
-
* @returns {string} HTML content
|
|
200
|
-
*/
|
|
201
|
-
export function generateFallbackTemplate({
|
|
202
|
-
summary,
|
|
203
|
-
comparisons,
|
|
204
|
-
displayDate
|
|
205
|
-
}) {
|
|
206
|
-
let failed = comparisons.filter(c => c.status === 'failed');
|
|
207
|
-
let failedSection = failed.length > 0 ? `
|
|
208
|
-
<h2>Failed Comparisons</h2>
|
|
209
|
-
<ul>
|
|
210
|
-
${failed.map(c => `<li>${c.name} - ${c.diffPercentage || 0}% difference</li>`).join('')}
|
|
211
|
-
</ul>
|
|
212
|
-
` : '<p style="text-align: center; font-size: 1.5rem;">✅ All tests passed!</p>';
|
|
213
|
-
return `<!DOCTYPE html>
|
|
214
|
-
<html lang="en">
|
|
215
|
-
<head>
|
|
216
|
-
<meta charset="UTF-8">
|
|
217
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
218
|
-
<title>Vizzly Dev Report</title>
|
|
219
|
-
<style>
|
|
220
|
-
body {
|
|
221
|
-
font-family: system-ui, -apple-system, sans-serif;
|
|
222
|
-
background: #0f172a;
|
|
223
|
-
color: #e2e8f0;
|
|
224
|
-
padding: 2rem;
|
|
225
|
-
}
|
|
226
|
-
.container { max-width: 1200px; margin: 0 auto; }
|
|
227
|
-
.header { text-align: center; margin-bottom: 2rem; }
|
|
228
|
-
.summary {
|
|
229
|
-
display: flex;
|
|
230
|
-
gap: 2rem;
|
|
231
|
-
justify-content: center;
|
|
232
|
-
margin: 2rem 0;
|
|
233
|
-
}
|
|
234
|
-
.stat { text-align: center; }
|
|
235
|
-
.stat-number {
|
|
236
|
-
font-size: 3rem;
|
|
237
|
-
font-weight: bold;
|
|
238
|
-
display: block;
|
|
239
|
-
}
|
|
240
|
-
.warning {
|
|
241
|
-
background: #fef3c7;
|
|
242
|
-
color: #92400e;
|
|
243
|
-
padding: 1rem;
|
|
244
|
-
border-radius: 0.5rem;
|
|
245
|
-
margin: 2rem 0;
|
|
246
|
-
}
|
|
247
|
-
</style>
|
|
248
|
-
</head>
|
|
249
|
-
<body>
|
|
250
|
-
<div class="container">
|
|
251
|
-
<div class="header">
|
|
252
|
-
<h1>🐻 Vizzly Dev Report</h1>
|
|
253
|
-
<p>Generated: ${displayDate}</p>
|
|
254
|
-
</div>
|
|
255
|
-
|
|
256
|
-
<div class="summary">
|
|
257
|
-
<div class="stat">
|
|
258
|
-
<span class="stat-number">${summary.total || 0}</span>
|
|
259
|
-
<span>Total</span>
|
|
260
|
-
</div>
|
|
261
|
-
<div class="stat">
|
|
262
|
-
<span class="stat-number" style="color: #10b981;">${summary.passed || 0}</span>
|
|
263
|
-
<span>Passed</span>
|
|
264
|
-
</div>
|
|
265
|
-
<div class="stat">
|
|
266
|
-
<span class="stat-number" style="color: #ef4444;">${summary.failed || 0}</span>
|
|
267
|
-
<span>Failed</span>
|
|
268
|
-
</div>
|
|
269
|
-
</div>
|
|
270
|
-
|
|
271
|
-
<div class="warning">
|
|
272
|
-
<strong>⚠️ Limited Report</strong>
|
|
273
|
-
<p>This is a fallback report. For the full interactive experience, ensure the reporter bundle is built:</p>
|
|
274
|
-
<code>npm run build:reporter</code>
|
|
275
|
-
</div>
|
|
276
|
-
|
|
277
|
-
${failedSection}
|
|
278
|
-
</div>
|
|
279
|
-
</body>
|
|
280
|
-
</html>`;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Build HTML content for the report
|
|
285
|
-
* @param {Object} reportData - Report data
|
|
286
|
-
* @param {Date} date - Current date
|
|
287
|
-
* @returns {string} HTML content
|
|
288
|
-
*/
|
|
289
|
-
export function buildHtmlContent(reportData, date) {
|
|
290
|
-
let serializedData = serializeForHtml(reportData);
|
|
291
|
-
let timestamp = date.toISOString();
|
|
292
|
-
let displayDate = date.toLocaleString();
|
|
293
|
-
return generateMainTemplate({
|
|
294
|
-
serializedData,
|
|
295
|
-
timestamp,
|
|
296
|
-
displayDate
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Build fallback HTML content
|
|
302
|
-
* @param {Object} reportData - Report data
|
|
303
|
-
* @param {Date} date - Current date
|
|
304
|
-
* @returns {string} HTML content
|
|
305
|
-
*/
|
|
306
|
-
export function buildFallbackHtmlContent(reportData, date) {
|
|
307
|
-
let summary = reportData.summary || {};
|
|
308
|
-
let comparisons = reportData.comparisons || [];
|
|
309
|
-
let displayDate = date.toLocaleString();
|
|
310
|
-
return generateFallbackTemplate({
|
|
311
|
-
summary,
|
|
312
|
-
comparisons,
|
|
313
|
-
displayDate
|
|
314
|
-
});
|
|
315
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Report Generator Operations - I/O operations with dependency injection
|
|
3
|
-
*
|
|
4
|
-
* Each operation takes its dependencies as parameters for testability.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { buildBundleDestPaths, buildBundleSourcePaths, buildHtmlContent, buildReportDir, buildReportPath, validateBundlesExist, validateReportData } from './core.js';
|
|
8
|
-
|
|
9
|
-
// ============================================================================
|
|
10
|
-
// File Operations
|
|
11
|
-
// ============================================================================
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Ensure a directory exists
|
|
15
|
-
* @param {Object} options - Options
|
|
16
|
-
* @param {string} options.path - Directory path
|
|
17
|
-
* @param {Object} options.deps - Dependencies
|
|
18
|
-
* @param {Function} options.deps.mkdir - mkdir function
|
|
19
|
-
* @returns {Promise<void>}
|
|
20
|
-
*/
|
|
21
|
-
export async function ensureDirectory({
|
|
22
|
-
path,
|
|
23
|
-
deps
|
|
24
|
-
}) {
|
|
25
|
-
let {
|
|
26
|
-
mkdir
|
|
27
|
-
} = deps;
|
|
28
|
-
await mkdir(path, {
|
|
29
|
-
recursive: true
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Check if bundles exist
|
|
35
|
-
* @param {Object} options - Options
|
|
36
|
-
* @param {string} options.projectRoot - Project root directory
|
|
37
|
-
* @param {Object} options.deps - Dependencies
|
|
38
|
-
* @param {Function} options.deps.existsSync - existsSync function
|
|
39
|
-
* @returns {{ bundleExists: boolean, cssExists: boolean, bundlePath: string, cssPath: string }}
|
|
40
|
-
*/
|
|
41
|
-
export function checkBundlesExist({
|
|
42
|
-
projectRoot,
|
|
43
|
-
deps
|
|
44
|
-
}) {
|
|
45
|
-
let {
|
|
46
|
-
existsSync
|
|
47
|
-
} = deps;
|
|
48
|
-
let {
|
|
49
|
-
bundlePath,
|
|
50
|
-
cssPath
|
|
51
|
-
} = buildBundleSourcePaths(projectRoot);
|
|
52
|
-
return {
|
|
53
|
-
bundleExists: existsSync(bundlePath),
|
|
54
|
-
cssExists: existsSync(cssPath),
|
|
55
|
-
bundlePath,
|
|
56
|
-
cssPath
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Copy bundle files to report directory
|
|
62
|
-
* @param {Object} options - Options
|
|
63
|
-
* @param {string} options.bundlePath - Source bundle path
|
|
64
|
-
* @param {string} options.cssPath - Source CSS path
|
|
65
|
-
* @param {string} options.reportDir - Report directory
|
|
66
|
-
* @param {Object} options.deps - Dependencies
|
|
67
|
-
* @param {Function} options.deps.copyFile - copyFile function
|
|
68
|
-
* @returns {Promise<void>}
|
|
69
|
-
*/
|
|
70
|
-
export async function copyBundles({
|
|
71
|
-
bundlePath,
|
|
72
|
-
cssPath,
|
|
73
|
-
reportDir,
|
|
74
|
-
deps
|
|
75
|
-
}) {
|
|
76
|
-
let {
|
|
77
|
-
copyFile
|
|
78
|
-
} = deps;
|
|
79
|
-
let {
|
|
80
|
-
bundleDest,
|
|
81
|
-
cssDest
|
|
82
|
-
} = buildBundleDestPaths(reportDir);
|
|
83
|
-
await copyFile(bundlePath, bundleDest);
|
|
84
|
-
await copyFile(cssPath, cssDest);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Write HTML content to file
|
|
89
|
-
* @param {Object} options - Options
|
|
90
|
-
* @param {string} options.path - File path
|
|
91
|
-
* @param {string} options.content - HTML content
|
|
92
|
-
* @param {Object} options.deps - Dependencies
|
|
93
|
-
* @param {Function} options.deps.writeFile - writeFile function
|
|
94
|
-
* @returns {Promise<void>}
|
|
95
|
-
*/
|
|
96
|
-
export async function writeHtmlFile({
|
|
97
|
-
path,
|
|
98
|
-
content,
|
|
99
|
-
deps
|
|
100
|
-
}) {
|
|
101
|
-
let {
|
|
102
|
-
writeFile
|
|
103
|
-
} = deps;
|
|
104
|
-
await writeFile(path, content, 'utf8');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ============================================================================
|
|
108
|
-
// Main Report Generation
|
|
109
|
-
// ============================================================================
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Generate a static HTML report with React reporter
|
|
113
|
-
* @param {Object} options - Options
|
|
114
|
-
* @param {Object} options.reportData - Report data
|
|
115
|
-
* @param {string} options.workingDir - Working directory
|
|
116
|
-
* @param {string} options.projectRoot - Project root directory
|
|
117
|
-
* @param {Object} options.deps - Dependencies
|
|
118
|
-
* @param {Function} options.deps.mkdir - mkdir function
|
|
119
|
-
* @param {Function} options.deps.existsSync - existsSync function
|
|
120
|
-
* @param {Function} options.deps.copyFile - copyFile function
|
|
121
|
-
* @param {Function} options.deps.writeFile - writeFile function
|
|
122
|
-
* @param {Object} options.deps.output - Output utilities
|
|
123
|
-
* @param {Function} options.deps.getDate - Function that returns current Date
|
|
124
|
-
* @returns {Promise<string>} Path to generated report
|
|
125
|
-
*/
|
|
126
|
-
export async function generateReport({
|
|
127
|
-
reportData,
|
|
128
|
-
workingDir,
|
|
129
|
-
projectRoot,
|
|
130
|
-
deps
|
|
131
|
-
}) {
|
|
132
|
-
let {
|
|
133
|
-
mkdir,
|
|
134
|
-
existsSync,
|
|
135
|
-
copyFile,
|
|
136
|
-
writeFile,
|
|
137
|
-
output,
|
|
138
|
-
getDate
|
|
139
|
-
} = deps;
|
|
140
|
-
|
|
141
|
-
// Validate report data
|
|
142
|
-
let validation = validateReportData(reportData);
|
|
143
|
-
if (!validation.valid) {
|
|
144
|
-
throw new Error(validation.error);
|
|
145
|
-
}
|
|
146
|
-
let reportDir = buildReportDir(workingDir);
|
|
147
|
-
let reportPath = buildReportPath(reportDir);
|
|
148
|
-
try {
|
|
149
|
-
// Ensure report directory exists
|
|
150
|
-
await ensureDirectory({
|
|
151
|
-
path: reportDir,
|
|
152
|
-
deps: {
|
|
153
|
-
mkdir
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// Check if bundles exist
|
|
158
|
-
let bundleCheck = checkBundlesExist({
|
|
159
|
-
projectRoot,
|
|
160
|
-
deps: {
|
|
161
|
-
existsSync
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
let bundleValidation = validateBundlesExist(bundleCheck.bundleExists, bundleCheck.cssExists);
|
|
165
|
-
if (!bundleValidation.valid) {
|
|
166
|
-
throw new Error(bundleValidation.error);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Copy bundles to report directory
|
|
170
|
-
await copyBundles({
|
|
171
|
-
bundlePath: bundleCheck.bundlePath,
|
|
172
|
-
cssPath: bundleCheck.cssPath,
|
|
173
|
-
reportDir,
|
|
174
|
-
deps: {
|
|
175
|
-
copyFile
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
// Generate HTML content
|
|
180
|
-
let htmlContent = buildHtmlContent(reportData, getDate());
|
|
181
|
-
|
|
182
|
-
// Write HTML file
|
|
183
|
-
await writeHtmlFile({
|
|
184
|
-
path: reportPath,
|
|
185
|
-
content: htmlContent,
|
|
186
|
-
deps: {
|
|
187
|
-
writeFile
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
output.debug('report', 'generated static report');
|
|
191
|
-
return reportPath;
|
|
192
|
-
} catch (error) {
|
|
193
|
-
output.error(`Failed to generate static report: ${error.message}`);
|
|
194
|
-
throw new Error(`Report generation failed: ${error.message}`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Static Report Generator using React Reporter
|
|
3
|
-
* Generates a self-contained HTML file with the React dashboard and embedded data
|
|
4
|
-
*
|
|
5
|
-
* This class is a thin wrapper around the functional report-generator module.
|
|
6
|
-
* For new code, consider using the functions directly from '../report-generator/'.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { existsSync } from 'node:fs';
|
|
10
|
-
import { copyFile, mkdir, writeFile } from 'node:fs/promises';
|
|
11
|
-
import { dirname, join } from 'node:path';
|
|
12
|
-
import { fileURLToPath } from 'node:url';
|
|
13
|
-
import { buildFallbackHtmlContent, buildHtmlContent, buildReportDir, buildReportPath, generateReport } from '../report-generator/index.js';
|
|
14
|
-
import * as output from '../utils/output.js';
|
|
15
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
-
const __dirname = dirname(__filename);
|
|
17
|
-
const PROJECT_ROOT = join(__dirname, '..', '..');
|
|
18
|
-
export class StaticReportGenerator {
|
|
19
|
-
constructor(workingDir, config) {
|
|
20
|
-
this.workingDir = workingDir;
|
|
21
|
-
this.config = config;
|
|
22
|
-
this.reportDir = buildReportDir(workingDir);
|
|
23
|
-
this.reportPath = buildReportPath(this.reportDir);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Generate static HTML report with React reporter bundle
|
|
28
|
-
* @param {Object} reportData - Complete report data (same format as live dashboard)
|
|
29
|
-
* @returns {Promise<string>} Path to generated report
|
|
30
|
-
*/
|
|
31
|
-
async generateReport(reportData) {
|
|
32
|
-
return generateReport({
|
|
33
|
-
reportData,
|
|
34
|
-
workingDir: this.workingDir,
|
|
35
|
-
projectRoot: PROJECT_ROOT,
|
|
36
|
-
deps: {
|
|
37
|
-
mkdir,
|
|
38
|
-
existsSync,
|
|
39
|
-
copyFile,
|
|
40
|
-
writeFile,
|
|
41
|
-
output,
|
|
42
|
-
getDate: () => new Date()
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Generate HTML template with embedded React app
|
|
49
|
-
* @param {Object} reportData - Report data to embed
|
|
50
|
-
* @returns {string} HTML content
|
|
51
|
-
* @deprecated Use buildHtmlContent from report-generator/core.js
|
|
52
|
-
*/
|
|
53
|
-
generateHtmlTemplate(reportData) {
|
|
54
|
-
return buildHtmlContent(reportData, new Date());
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Generate a minimal HTML report when bundles are missing (fallback)
|
|
59
|
-
* @param {Object} reportData - Report data
|
|
60
|
-
* @returns {string} Minimal HTML content
|
|
61
|
-
*/
|
|
62
|
-
generateFallbackHtml(reportData) {
|
|
63
|
-
return buildFallbackHtmlContent(reportData, new Date());
|
|
64
|
-
}
|
|
65
|
-
}
|