ortoni-report 4.0.1-beta.0 → 4.0.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/chunk-4RZ5C7KY.mjs +744 -0
  2. package/dist/{chunk-MPZLDOCN.mjs → chunk-HOOC3MDY.mjs} +305 -304
  3. package/dist/chunk-ISCRDMPY.mjs +693 -0
  4. package/dist/{chunk-INS3E7E6.mjs → chunk-P72FKFLZ.mjs} +352 -298
  5. package/dist/chunk-S45BZGXX.mjs +744 -0
  6. package/dist/{chunk-OZS6QIJS.mjs → chunk-ZG4JPYLC.mjs} +352 -298
  7. package/dist/{chunk-TI33PMMQ.mjs → chunk-ZSPTPISU.mjs} +352 -299
  8. package/dist/{cli/cli.js → cli.js} +403 -189
  9. package/dist/cli.mjs +206 -0
  10. package/dist/index.html +2 -2
  11. package/dist/ortoni-report.d.mts +7 -0
  12. package/dist/ortoni-report.d.ts +7 -0
  13. package/dist/ortoni-report.js +189 -72
  14. package/dist/ortoni-report.mjs +9 -5
  15. package/package.json +11 -4
  16. package/dist/chunk-45EJSEX2.mjs +0 -632
  17. package/dist/chunk-75EAJL2U.mjs +0 -632
  18. package/dist/chunk-A6HCKATU.mjs +0 -76
  19. package/dist/chunk-FGIYOFIC.mjs +0 -632
  20. package/dist/chunk-FHKWBHU6.mjs +0 -633
  21. package/dist/chunk-GLICR3VS.mjs +0 -637
  22. package/dist/chunk-HFO6XSKC.mjs +0 -633
  23. package/dist/chunk-HOZD6YIV.mjs +0 -634
  24. package/dist/chunk-IJO2YIFE.mjs +0 -637
  25. package/dist/chunk-JEIWNUQY.mjs +0 -632
  26. package/dist/chunk-JPLAGYR7.mjs +0 -632
  27. package/dist/chunk-NM6ULN2O.mjs +0 -632
  28. package/dist/chunk-P57227VN.mjs +0 -633
  29. package/dist/chunk-QMTRYN5N.js +0 -635
  30. package/dist/chunk-Z5NBP5TS.mjs +0 -635
  31. package/dist/cli/cli.cjs +0 -678
  32. package/dist/cli/cli.d.cts +0 -1
  33. package/dist/cli/cli.mjs +0 -103
  34. package/dist/ortoni-report.cjs +0 -2134
  35. package/dist/ortoni-report.d.cts +0 -111
  36. /package/dist/{cli/cli.d.mts → cli.d.mts} +0 -0
  37. /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
@@ -8,242 +8,14 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
  });
9
9
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
10
 
11
- // src/helpers/fileManager.ts
12
- import fs from "fs";
13
- import path from "path";
14
- var FileManager = class {
15
- constructor(folderPath) {
16
- this.folderPath = folderPath;
17
- }
18
- ensureReportDirectory() {
19
- const ortoniDataFolder = path.join(this.folderPath, "ortoni-data");
20
- if (!fs.existsSync(this.folderPath)) {
21
- fs.mkdirSync(this.folderPath, { recursive: true });
22
- } else {
23
- if (fs.existsSync(ortoniDataFolder)) {
24
- fs.rmSync(ortoniDataFolder, { recursive: true, force: true });
25
- }
26
- }
27
- }
28
- writeReportFile(filename, data) {
29
- const templatePath = path.join(__dirname, "..", "index.html");
30
- console.log(templatePath);
31
- let html = fs.readFileSync(templatePath, "utf-8");
32
- const reportJSON = JSON.stringify({
33
- data
34
- });
35
- html = html.replace("__ORTONI_TEST_REPORTDATA__", reportJSON);
36
- console.log(`Writing report to ${reportJSON}`);
37
- const outputDir = path.join(process.cwd(), this.folderPath);
38
- if (!fs.existsSync(outputDir)) {
39
- fs.mkdirSync(outputDir, { recursive: true });
40
- }
41
- const outputPath = path.join(outputDir, filename);
42
- console.log(`Writing report to ${outputPath}`);
43
- fs.writeFileSync(outputPath, html);
44
- return outputPath;
45
- }
46
- writeRawFile(filename, data) {
47
- const outputPath = path.join(process.cwd(), this.folderPath, filename);
48
- fs.mkdirSync(path.dirname(outputPath), { recursive: true });
49
- const content = typeof data === "string" ? data : JSON.stringify(data, null, 2);
50
- fs.writeFileSync(outputPath, content, "utf-8");
51
- return outputPath;
52
- }
53
- copyTraceViewerAssets(skip) {
54
- if (skip) return;
55
- const traceViewerFolder = path.join(
56
- __require.resolve("playwright-core"),
57
- "..",
58
- "lib",
59
- "vite",
60
- "traceViewer"
61
- );
62
- const traceViewerTargetFolder = path.join(this.folderPath, "trace");
63
- const traceViewerAssetsTargetFolder = path.join(
64
- traceViewerTargetFolder,
65
- "assets"
66
- );
67
- fs.mkdirSync(traceViewerAssetsTargetFolder, { recursive: true });
68
- for (const file of fs.readdirSync(traceViewerFolder)) {
69
- if (file.endsWith(".map") || file.includes("watch") || file.includes("assets"))
70
- continue;
71
- fs.copyFileSync(
72
- path.join(traceViewerFolder, file),
73
- path.join(traceViewerTargetFolder, file)
74
- );
75
- }
76
- const assetsFolder = path.join(traceViewerFolder, "assets");
77
- for (const file of fs.readdirSync(assetsFolder)) {
78
- if (file.endsWith(".map") || file.includes("xtermModule")) continue;
79
- fs.copyFileSync(
80
- path.join(assetsFolder, file),
81
- path.join(traceViewerAssetsTargetFolder, file)
82
- );
83
- }
84
- }
85
- };
86
-
87
- // src/utils/groupProjects.ts
88
- function groupResults(config, results) {
89
- if (config.showProject) {
90
- const groupedResults = results.reduce((acc, result, index) => {
91
- const testId = `${result.filePath}:${result.projectName}:${result.title}`;
92
- const key = `${testId}-${result.key}-${result.retryAttemptCount}`;
93
- const { filePath, suite, projectName } = result;
94
- acc[filePath] = acc[filePath] || {};
95
- acc[filePath][suite] = acc[filePath][suite] || {};
96
- acc[filePath][suite][projectName] = acc[filePath][suite][projectName] || [];
97
- acc[filePath][suite][projectName].push({ ...result, index, testId, key });
98
- return acc;
99
- }, {});
100
- return groupedResults;
101
- } else {
102
- const groupedResults = results.reduce((acc, result, index) => {
103
- const testId = `${result.filePath}:${result.projectName}:${result.title}`;
104
- const key = `${testId}-${result.key}-${result.retryAttemptCount}`;
105
- const { filePath, suite } = result;
106
- acc[filePath] = acc[filePath] || {};
107
- acc[filePath][suite] = acc[filePath][suite] || [];
108
- acc[filePath][suite].push({ ...result, index, testId, key });
109
- return acc;
110
- }, {});
111
- return groupedResults;
112
- }
113
- }
114
-
115
- // src/helpers/HTMLGenerator.ts
116
- var HTMLGenerator = class {
117
- constructor(ortoniConfig, dbManager) {
118
- this.ortoniConfig = ortoniConfig;
119
- this.dbManager = dbManager;
120
- }
121
- async generateFinalReport(filteredResults, totalDuration, results, projectSet) {
122
- const data = await this.prepareReportData(
123
- filteredResults,
124
- totalDuration,
125
- results,
126
- projectSet
127
- );
128
- return data;
129
- }
130
- async getReportData() {
131
- return {
132
- summary: await this.dbManager.getSummaryData(),
133
- trends: await this.dbManager.getTrends(),
134
- flakyTests: await this.dbManager.getFlakyTests(),
135
- slowTests: await this.dbManager.getSlowTests()
136
- };
137
- }
138
- async prepareReportData(filteredResults, totalDuration, results, projectSet) {
139
- const totalTests = filteredResults.length;
140
- const passedTests = results.filter((r) => r.status === "passed").length;
141
- const flakyTests = results.filter((r) => r.status === "flaky").length;
142
- const failed = filteredResults.filter(
143
- (r) => r.status === "failed" || r.status === "timedOut"
144
- ).length;
145
- const successRate = ((passedTests + flakyTests) / totalTests * 100).toFixed(2);
146
- const allTags = /* @__PURE__ */ new Set();
147
- results.forEach(
148
- (result) => result.testTags.forEach((tag) => allTags.add(tag))
149
- );
150
- const projectResults = this.calculateProjectResults(
151
- filteredResults,
152
- results,
153
- projectSet
154
- );
155
- const lastRunDate = (/* @__PURE__ */ new Date()).toLocaleString();
156
- const testHistories = await Promise.all(
157
- results.map(async (result) => {
158
- const testId = `${result.filePath}:${result.projectName}:${result.title}`;
159
- const history = await this.dbManager.getTestHistory(testId);
160
- return {
161
- testId,
162
- history
163
- };
164
- })
165
- );
166
- return {
167
- summary: {
168
- overAllResult: {
169
- pass: passedTests,
170
- fail: failed,
171
- skip: results.filter((r) => r.status === "skipped").length,
172
- retry: results.filter((r) => r.retryAttemptCount).length,
173
- flaky: flakyTests,
174
- total: filteredResults.length
175
- },
176
- successRate,
177
- lastRunDate,
178
- totalDuration,
179
- stats: this.extractProjectStats(projectResults)
180
- },
181
- testResult: {
182
- tests: groupResults(this.ortoniConfig, results),
183
- testHistories,
184
- allTags: Array.from(allTags),
185
- set: projectSet
186
- },
187
- userConfig: {
188
- projectName: this.ortoniConfig.projectName,
189
- authorName: this.ortoniConfig.authorName,
190
- type: this.ortoniConfig.testType,
191
- title: this.ortoniConfig.title
192
- },
193
- userMeta: {
194
- meta: this.ortoniConfig.meta
195
- },
196
- preferences: {
197
- logo: this.ortoniConfig.logo || void 0,
198
- showProject: this.ortoniConfig.showProject || false
199
- },
200
- analytics: {
201
- reportData: await this.getReportData()
202
- }
203
- };
204
- }
205
- calculateProjectResults(filteredResults, results, projectSet) {
206
- return Array.from(projectSet).map((projectName) => {
207
- const projectTests = filteredResults.filter(
208
- (r) => r.projectName === projectName
209
- );
210
- const allProjectTests = results.filter(
211
- (r) => r.projectName === projectName
212
- );
213
- return {
214
- projectName,
215
- passedTests: projectTests.filter((r) => r.status === "passed").length,
216
- failedTests: projectTests.filter(
217
- (r) => r.status === "failed" || r.status === "timedOut"
218
- ).length,
219
- skippedTests: allProjectTests.filter((r) => r.status === "skipped").length,
220
- retryTests: allProjectTests.filter((r) => r.retryAttemptCount).length,
221
- flakyTests: allProjectTests.filter((r) => r.status === "flaky").length,
222
- totalTests: projectTests.length
223
- };
224
- });
225
- }
226
- extractProjectStats(projectResults) {
227
- return {
228
- projectNames: projectResults.map((result) => result.projectName),
229
- totalTests: projectResults.map((result) => result.totalTests),
230
- passedTests: projectResults.map((result) => result.passedTests),
231
- failedTests: projectResults.map((result) => result.failedTests),
232
- skippedTests: projectResults.map((result) => result.skippedTests),
233
- retryTests: projectResults.map((result) => result.retryTests),
234
- flakyTests: projectResults.map((result) => result.flakyTests)
235
- };
236
- }
237
- };
238
-
239
11
  // src/utils/utils.ts
240
- import path2 from "path";
12
+ import path from "path";
241
13
  function normalizeFilePath(filePath) {
242
- const normalizedPath = path2.normalize(filePath);
243
- return path2.basename(normalizedPath);
14
+ const normalizedPath = path.normalize(filePath);
15
+ return path.basename(normalizedPath);
244
16
  }
245
17
  function ensureHtmlExtension(filename) {
246
- const ext = path2.extname(filename);
18
+ const ext = path.extname(filename);
247
19
  if (ext && ext.toLowerCase() === ".html") {
248
20
  return filename;
249
21
  }
@@ -291,67 +63,6 @@ function extractSuites(titlePath) {
291
63
  };
292
64
  }
293
65
 
294
- // src/utils/expressServer.ts
295
- import express from "express";
296
- import path3 from "path";
297
- import { spawn } from "child_process";
298
- function startReportServer(reportFolder, reportFilename, port = 2004, open2) {
299
- const app = express();
300
- app.use(express.static(reportFolder));
301
- app.get("/", (_req, res) => {
302
- try {
303
- res.sendFile(path3.resolve(reportFolder, reportFilename));
304
- } catch (error) {
305
- console.error("Ortoni-Report: Error sending report file:", error);
306
- res.status(500).send("Error loading report");
307
- }
308
- });
309
- try {
310
- const server = app.listen(port, () => {
311
- console.log(
312
- `Server is running at http://localhost:${port}
313
- Press Ctrl+C to stop.`
314
- );
315
- if (open2 === "always" || open2 === "on-failure") {
316
- try {
317
- openBrowser(`http://localhost:${port}`);
318
- } catch (error) {
319
- console.error("Ortoni-Report: Error opening browser:", error);
320
- }
321
- }
322
- });
323
- server.on("error", (error) => {
324
- if (error.code === "EADDRINUSE") {
325
- console.error(
326
- `Ortoni-Report: Port ${port} is already in use. Trying a different port...`
327
- );
328
- } else {
329
- console.error("Ortoni-Report: Server error:", error);
330
- }
331
- });
332
- } catch (error) {
333
- console.error("Ortoni-Report: Error starting the server:", error);
334
- }
335
- }
336
- function openBrowser(url) {
337
- const platform = process.platform;
338
- let command;
339
- try {
340
- if (platform === "win32") {
341
- command = "cmd";
342
- spawn(command, ["/c", "start", url]);
343
- } else if (platform === "darwin") {
344
- command = "open";
345
- spawn(command, [url]);
346
- } else {
347
- command = "xdg-open";
348
- spawn(command, [url]);
349
- }
350
- } catch (error) {
351
- console.error("Ortoni-Report: Error opening the browser:", error);
352
- }
353
- }
354
-
355
66
  // src/helpers/databaseManager.ts
356
67
  import { open } from "sqlite";
357
68
  import sqlite3 from "sqlite3";
@@ -626,14 +337,356 @@ var DatabaseManager = class {
626
337
  }
627
338
  };
628
339
 
629
- export {
630
- __publicField,
631
- FileManager,
632
- HTMLGenerator,
340
+ // src/utils/groupProjects.ts
341
+ function groupResults(config, results) {
342
+ if (config.showProject) {
343
+ const groupedResults = results.reduce((acc, result, index) => {
344
+ const testId = `${result.filePath}:${result.projectName}:${result.title}`;
345
+ const key = `${testId}-${result.key}-${result.retryAttemptCount}`;
346
+ const { filePath, suite, projectName } = result;
347
+ acc[filePath] = acc[filePath] || {};
348
+ acc[filePath][suite] = acc[filePath][suite] || {};
349
+ acc[filePath][suite][projectName] = acc[filePath][suite][projectName] || [];
350
+ acc[filePath][suite][projectName].push({ ...result, index, testId, key });
351
+ return acc;
352
+ }, {});
353
+ return groupedResults;
354
+ } else {
355
+ const groupedResults = results.reduce((acc, result, index) => {
356
+ const testId = `${result.filePath}:${result.projectName}:${result.title}`;
357
+ const key = `${testId}-${result.key}-${result.retryAttemptCount}`;
358
+ const { filePath, suite } = result;
359
+ acc[filePath] = acc[filePath] || {};
360
+ acc[filePath][suite] = acc[filePath][suite] || [];
361
+ acc[filePath][suite].push({ ...result, index, testId, key });
362
+ return acc;
363
+ }, {});
364
+ return groupedResults;
365
+ }
366
+ }
367
+
368
+ // src/helpers/HTMLGenerator.ts
369
+ var HTMLGenerator = class {
370
+ constructor(ortoniConfig, dbManager) {
371
+ this.ortoniConfig = ortoniConfig;
372
+ this.dbManager = dbManager;
373
+ }
374
+ async generateFinalReport(filteredResults, totalDuration, results, projectSet) {
375
+ const data = await this.prepareReportData(
376
+ filteredResults,
377
+ totalDuration,
378
+ results,
379
+ projectSet
380
+ );
381
+ return data;
382
+ }
383
+ async getReportData() {
384
+ return {
385
+ summary: await this.dbManager.getSummaryData(),
386
+ trends: await this.dbManager.getTrends(),
387
+ flakyTests: await this.dbManager.getFlakyTests(),
388
+ slowTests: await this.dbManager.getSlowTests()
389
+ };
390
+ }
391
+ async prepareReportData(filteredResults, totalDuration, results, projectSet) {
392
+ const totalTests = filteredResults.length;
393
+ const passedTests = results.filter((r) => r.status === "passed").length;
394
+ const flakyTests = results.filter((r) => r.status === "flaky").length;
395
+ const failed = filteredResults.filter(
396
+ (r) => r.status === "failed" || r.status === "timedOut"
397
+ ).length;
398
+ const successRate = ((passedTests + flakyTests) / totalTests * 100).toFixed(2);
399
+ const allTags = /* @__PURE__ */ new Set();
400
+ results.forEach(
401
+ (result) => result.testTags.forEach((tag) => allTags.add(tag))
402
+ );
403
+ const projectResults = this.calculateProjectResults(
404
+ filteredResults,
405
+ results,
406
+ projectSet
407
+ );
408
+ const lastRunDate = (/* @__PURE__ */ new Date()).toLocaleString();
409
+ const testHistories = await Promise.all(
410
+ results.map(async (result) => {
411
+ const testId = `${result.filePath}:${result.projectName}:${result.title}`;
412
+ const history = await this.dbManager.getTestHistory(testId);
413
+ return {
414
+ testId,
415
+ history
416
+ };
417
+ })
418
+ );
419
+ return {
420
+ summary: {
421
+ overAllResult: {
422
+ pass: passedTests,
423
+ fail: failed,
424
+ skip: results.filter((r) => r.status === "skipped").length,
425
+ retry: results.filter((r) => r.retryAttemptCount).length,
426
+ flaky: flakyTests,
427
+ total: filteredResults.length
428
+ },
429
+ successRate,
430
+ lastRunDate,
431
+ totalDuration,
432
+ stats: this.extractProjectStats(projectResults)
433
+ },
434
+ testResult: {
435
+ tests: groupResults(this.ortoniConfig, results),
436
+ testHistories,
437
+ allTags: Array.from(allTags),
438
+ set: projectSet
439
+ },
440
+ userConfig: {
441
+ projectName: this.ortoniConfig.projectName,
442
+ authorName: this.ortoniConfig.authorName,
443
+ type: this.ortoniConfig.testType,
444
+ title: this.ortoniConfig.title
445
+ },
446
+ userMeta: {
447
+ meta: this.ortoniConfig.meta
448
+ },
449
+ preferences: {
450
+ logo: this.ortoniConfig.logo || void 0,
451
+ showProject: this.ortoniConfig.showProject || false
452
+ },
453
+ analytics: {
454
+ reportData: await this.getReportData()
455
+ }
456
+ };
457
+ }
458
+ calculateProjectResults(filteredResults, results, projectSet) {
459
+ return Array.from(projectSet).map((projectName) => {
460
+ const projectTests = filteredResults.filter(
461
+ (r) => r.projectName === projectName
462
+ );
463
+ const allProjectTests = results.filter(
464
+ (r) => r.projectName === projectName
465
+ );
466
+ return {
467
+ projectName,
468
+ passedTests: projectTests.filter((r) => r.status === "passed").length,
469
+ failedTests: projectTests.filter(
470
+ (r) => r.status === "failed" || r.status === "timedOut"
471
+ ).length,
472
+ skippedTests: allProjectTests.filter((r) => r.status === "skipped").length,
473
+ retryTests: allProjectTests.filter((r) => r.retryAttemptCount).length,
474
+ flakyTests: allProjectTests.filter((r) => r.status === "flaky").length,
475
+ totalTests: projectTests.length
476
+ };
477
+ });
478
+ }
479
+ extractProjectStats(projectResults) {
480
+ return {
481
+ projectNames: projectResults.map((result) => result.projectName),
482
+ totalTests: projectResults.map((result) => result.totalTests),
483
+ passedTests: projectResults.map((result) => result.passedTests),
484
+ failedTests: projectResults.map((result) => result.failedTests),
485
+ skippedTests: projectResults.map((result) => result.skippedTests),
486
+ retryTests: projectResults.map((result) => result.retryTests),
487
+ flakyTests: projectResults.map((result) => result.flakyTests)
488
+ };
489
+ }
490
+ };
491
+
492
+ // src/helpers/fileManager.ts
493
+ import fs2 from "fs";
494
+ import path3 from "path";
495
+
496
+ // src/helpers/templateLoader.ts
497
+ import fs from "fs";
498
+ import path2 from "path";
499
+ function getCreateRequire() {
500
+ try {
501
+ const { createRequire } = __require("module");
502
+ return createRequire;
503
+ } catch (e) {
504
+ try {
505
+ const m = eval("require('module')");
506
+ return m.createRequire;
507
+ } catch {
508
+ return null;
509
+ }
510
+ }
511
+ }
512
+ function readBundledTemplate(pkgName = "ortoni-report") {
513
+ const packagedRel = "dist/index.html";
514
+ const createRequire = getCreateRequire();
515
+ if (createRequire) {
516
+ try {
517
+ const requireFn = createRequire(__filename);
518
+ const resolved = requireFn.resolve(`${pkgName}/${packagedRel}`);
519
+ if (fs.existsSync(resolved)) {
520
+ return fs.readFileSync(resolved, "utf-8");
521
+ }
522
+ } catch {
523
+ }
524
+ }
525
+ try {
526
+ const here = path2.resolve(__dirname, "../dist/index.html");
527
+ if (fs.existsSync(here)) return fs.readFileSync(here, "utf-8");
528
+ } catch {
529
+ }
530
+ try {
531
+ const nm = path2.join(process.cwd(), "node_modules", pkgName, packagedRel);
532
+ if (fs.existsSync(nm)) return fs.readFileSync(nm, "utf-8");
533
+ } catch {
534
+ }
535
+ try {
536
+ const alt = path2.join(process.cwd(), "dist", "index.html");
537
+ if (fs.existsSync(alt)) return fs.readFileSync(alt, "utf-8");
538
+ } catch {
539
+ }
540
+ throw new Error(
541
+ `ortoni-report template not found (tried:
542
+ - require.resolve('${pkgName}/${packagedRel}')
543
+ - relative ../dist/index.html
544
+ - ${path2.join(
545
+ process.cwd(),
546
+ "node_modules",
547
+ pkgName,
548
+ packagedRel
549
+ )}
550
+ - ${path2.join(process.cwd(), "dist", "index.html")}
551
+ Ensure 'dist/index.html' is present in the package and that your package.json 'files' includes 'dist/'.`
552
+ );
553
+ }
554
+
555
+ // src/helpers/fileManager.ts
556
+ var FileManager = class {
557
+ constructor(folderPath) {
558
+ this.folderPath = folderPath;
559
+ }
560
+ ensureReportDirectory() {
561
+ const ortoniDataFolder = path3.join(this.folderPath, "ortoni-data");
562
+ if (!fs2.existsSync(this.folderPath)) {
563
+ fs2.mkdirSync(this.folderPath, { recursive: true });
564
+ } else {
565
+ if (fs2.existsSync(ortoniDataFolder)) {
566
+ fs2.rmSync(ortoniDataFolder, { recursive: true, force: true });
567
+ }
568
+ }
569
+ }
570
+ writeReportFile(filename, data) {
571
+ let html = readBundledTemplate();
572
+ const reportJSON = JSON.stringify({
573
+ data
574
+ });
575
+ html = html.replace("__ORTONI_TEST_REPORTDATA__", reportJSON);
576
+ const outputPath = path3.join(process.cwd(), this.folderPath, filename);
577
+ fs2.writeFileSync(outputPath, html);
578
+ return outputPath;
579
+ }
580
+ writeRawFile(filename, data) {
581
+ const outputPath = path3.join(process.cwd(), this.folderPath, filename);
582
+ fs2.mkdirSync(path3.dirname(outputPath), { recursive: true });
583
+ const content = typeof data === "string" ? data : JSON.stringify(data, null, 2);
584
+ fs2.writeFileSync(outputPath, content, "utf-8");
585
+ return outputPath;
586
+ }
587
+ copyTraceViewerAssets(skip) {
588
+ if (skip) return;
589
+ const traceViewerFolder = path3.join(
590
+ __require.resolve("playwright-core"),
591
+ "..",
592
+ "lib",
593
+ "vite",
594
+ "traceViewer"
595
+ );
596
+ const traceViewerTargetFolder = path3.join(this.folderPath, "trace");
597
+ const traceViewerAssetsTargetFolder = path3.join(
598
+ traceViewerTargetFolder,
599
+ "assets"
600
+ );
601
+ fs2.mkdirSync(traceViewerAssetsTargetFolder, { recursive: true });
602
+ for (const file of fs2.readdirSync(traceViewerFolder)) {
603
+ if (file.endsWith(".map") || file.includes("watch") || file.includes("assets"))
604
+ continue;
605
+ fs2.copyFileSync(
606
+ path3.join(traceViewerFolder, file),
607
+ path3.join(traceViewerTargetFolder, file)
608
+ );
609
+ }
610
+ const assetsFolder = path3.join(traceViewerFolder, "assets");
611
+ for (const file of fs2.readdirSync(assetsFolder)) {
612
+ if (file.endsWith(".map") || file.includes("xtermModule")) continue;
613
+ fs2.copyFileSync(
614
+ path3.join(assetsFolder, file),
615
+ path3.join(traceViewerAssetsTargetFolder, file)
616
+ );
617
+ }
618
+ }
619
+ };
620
+
621
+ // src/utils/expressServer.ts
622
+ import express from "express";
623
+ import path4 from "path";
624
+ import { spawn } from "child_process";
625
+ function startReportServer(reportFolder, reportFilename, port = 2004, open2) {
626
+ const app = express();
627
+ app.use(express.static(reportFolder));
628
+ app.get("/", (_req, res) => {
629
+ try {
630
+ res.sendFile(path4.resolve(reportFolder, reportFilename));
631
+ } catch (error) {
632
+ console.error("Ortoni Report: Error sending report file:", error);
633
+ res.status(500).send("Error loading report");
634
+ }
635
+ });
636
+ try {
637
+ const server = app.listen(port, () => {
638
+ console.log(
639
+ `Server is running at http://localhost:${port}
640
+ Press Ctrl+C to stop.`
641
+ );
642
+ if (open2 === "always" || open2 === "on-failure") {
643
+ try {
644
+ openBrowser(`http://localhost:${port}`);
645
+ } catch (error) {
646
+ console.error("Ortoni Report: Error opening browser:", error);
647
+ }
648
+ }
649
+ });
650
+ server.on("error", (error) => {
651
+ if (error.code === "EADDRINUSE") {
652
+ console.error(
653
+ `Ortoni Report: Port ${port} is already in use. Trying a different port...`
654
+ );
655
+ } else {
656
+ console.error("Ortoni Report: Server error:", error);
657
+ }
658
+ });
659
+ } catch (error) {
660
+ console.error("Ortoni Report: Error starting the server:", error);
661
+ }
662
+ }
663
+ function openBrowser(url) {
664
+ const platform = process.platform;
665
+ let command;
666
+ try {
667
+ if (platform === "win32") {
668
+ command = "cmd";
669
+ spawn(command, ["/c", "start", url]);
670
+ } else if (platform === "darwin") {
671
+ command = "open";
672
+ spawn(command, [url]);
673
+ } else {
674
+ command = "xdg-open";
675
+ spawn(command, [url]);
676
+ }
677
+ } catch (error) {
678
+ console.error("Ortoni Report: Error opening the browser:", error);
679
+ }
680
+ }
681
+
682
+ export {
683
+ __publicField,
633
684
  normalizeFilePath,
634
685
  ensureHtmlExtension,
635
686
  escapeHtml,
636
687
  extractSuites,
637
- startReportServer,
638
- DatabaseManager
688
+ DatabaseManager,
689
+ HTMLGenerator,
690
+ FileManager,
691
+ startReportServer
639
692
  };