ortoni-report 4.0.3 → 4.0.4

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.
@@ -195,6 +195,67 @@ function groupResults(config, results) {
195
195
  }
196
196
  }
197
197
 
198
+ // src/utils/utils.ts
199
+ var import_path3 = __toESM(require("path"));
200
+ function normalizeFilePath(filePath) {
201
+ const normalizedPath = import_path3.default.normalize(filePath);
202
+ return import_path3.default.basename(normalizedPath);
203
+ }
204
+ function ensureHtmlExtension(filename) {
205
+ const ext = import_path3.default.extname(filename);
206
+ if (ext && ext.toLowerCase() === ".html") {
207
+ return filename;
208
+ }
209
+ return `${filename}.html`;
210
+ }
211
+ function escapeHtml(unsafe) {
212
+ if (typeof unsafe !== "string") {
213
+ return String(unsafe);
214
+ }
215
+ return unsafe.replace(/[&<"']/g, function(match) {
216
+ const escapeMap = {
217
+ "&": "&amp;",
218
+ "<": "&lt;",
219
+ ">": "&gt;",
220
+ '"': "&quot;",
221
+ "'": "&#039;"
222
+ };
223
+ return escapeMap[match] || match;
224
+ });
225
+ }
226
+ function formatDateLocal(dateInput) {
227
+ if (!dateInput) return "N/A";
228
+ try {
229
+ const date = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
230
+ if (isNaN(date.getTime())) {
231
+ return "N/A";
232
+ }
233
+ const options = {
234
+ year: "numeric",
235
+ month: "short",
236
+ day: "2-digit",
237
+ hour: "2-digit",
238
+ minute: "2-digit",
239
+ hour12: true
240
+ };
241
+ return new Intl.DateTimeFormat("en-US", options).format(date);
242
+ } catch (e) {
243
+ return "N/A";
244
+ }
245
+ }
246
+ function extractSuites(titlePath) {
247
+ const tagPattern = /@[\w]+/g;
248
+ const suiteParts = titlePath.slice(3, titlePath.length - 1).map((p) => p.replace(tagPattern, "").trim());
249
+ return {
250
+ hierarchy: suiteParts.join(" > "),
251
+ // full hierarchy
252
+ topLevelSuite: suiteParts[0] ?? "",
253
+ // first suite
254
+ parentSuite: suiteParts[suiteParts.length - 1] ?? ""
255
+ // last suite
256
+ };
257
+ }
258
+
198
259
  // src/helpers/HTMLGenerator.ts
199
260
  var HTMLGenerator = class {
200
261
  constructor(ortoniConfig, dbManager) {
@@ -268,7 +329,7 @@ var HTMLGenerator = class {
268
329
  results,
269
330
  projectSet
270
331
  );
271
- const lastRunDate = (/* @__PURE__ */ new Date()).toLocaleString();
332
+ const lastRunDate = formatDateLocal(/* @__PURE__ */ new Date());
272
333
  const testHistories = await Promise.all(
273
334
  results.map(async (result) => {
274
335
  const testId = `${result.filePath}:${result.projectName}:${result.title}`;
@@ -375,7 +436,7 @@ var import_ansi_to_html = __toESM(require("ansi-to-html"));
375
436
  var import_path5 = __toESM(require("path"));
376
437
 
377
438
  // src/utils/attachFiles.ts
378
- var import_path3 = __toESM(require("path"));
439
+ var import_path4 = __toESM(require("path"));
379
440
  var import_fs4 = __toESM(require("fs"));
380
441
 
381
442
  // src/helpers/markdownConverter.ts
@@ -1518,7 +1579,7 @@ function convertMarkdownToHtml(markdownPath, htmlOutputPath) {
1518
1579
  // src/utils/attachFiles.ts
1519
1580
  function attachFiles(subFolder, result, testResult, config, steps, errors) {
1520
1581
  const folderPath = config.folderPath || "ortoni-report";
1521
- const attachmentsFolder = import_path3.default.join(
1582
+ const attachmentsFolder = import_path4.default.join(
1522
1583
  folderPath,
1523
1584
  "ortoni-data",
1524
1585
  "attachments",
@@ -1534,14 +1595,14 @@ function attachFiles(subFolder, result, testResult, config, steps, errors) {
1534
1595
  result.attachments.forEach((attachment) => {
1535
1596
  const { contentType, name, path: attachmentPath, body } = attachment;
1536
1597
  if (!attachmentPath && !body) return;
1537
- const fileName = attachmentPath ? import_path3.default.basename(attachmentPath) : `${name}.${getFileExtension(contentType)}`;
1538
- const relativePath = import_path3.default.join(
1598
+ const fileName = attachmentPath ? import_path4.default.basename(attachmentPath) : `${name}.${getFileExtension(contentType)}`;
1599
+ const relativePath = import_path4.default.join(
1539
1600
  "ortoni-data",
1540
1601
  "attachments",
1541
1602
  subFolder,
1542
1603
  fileName
1543
1604
  );
1544
- const fullPath = import_path3.default.join(attachmentsFolder, fileName);
1605
+ const fullPath = import_path4.default.join(attachmentsFolder, fileName);
1545
1606
  if (contentType === "image/png") {
1546
1607
  handleImage(
1547
1608
  attachmentPath,
@@ -1632,61 +1693,6 @@ function getFileExtension(contentType) {
1632
1693
  return extensions[contentType] || "unknown";
1633
1694
  }
1634
1695
 
1635
- // src/utils/utils.ts
1636
- var import_path4 = __toESM(require("path"));
1637
- function normalizeFilePath(filePath) {
1638
- const normalizedPath = import_path4.default.normalize(filePath);
1639
- return import_path4.default.basename(normalizedPath);
1640
- }
1641
- function ensureHtmlExtension(filename) {
1642
- const ext = import_path4.default.extname(filename);
1643
- if (ext && ext.toLowerCase() === ".html") {
1644
- return filename;
1645
- }
1646
- return `${filename}.html`;
1647
- }
1648
- function escapeHtml(unsafe) {
1649
- if (typeof unsafe !== "string") {
1650
- return String(unsafe);
1651
- }
1652
- return unsafe.replace(/[&<"']/g, function(match) {
1653
- const escapeMap = {
1654
- "&": "&amp;",
1655
- "<": "&lt;",
1656
- ">": "&gt;",
1657
- '"': "&quot;",
1658
- "'": "&#039;"
1659
- };
1660
- return escapeMap[match] || match;
1661
- });
1662
- }
1663
- function formatDateLocal(dateInput) {
1664
- const date = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
1665
- const options = {
1666
- year: "numeric",
1667
- month: "short",
1668
- day: "2-digit",
1669
- hour: "2-digit",
1670
- minute: "2-digit",
1671
- hour12: true,
1672
- timeZoneName: "short"
1673
- // or "Asia/Kolkata"
1674
- };
1675
- return new Intl.DateTimeFormat(void 0, options).format(date);
1676
- }
1677
- function extractSuites(titlePath) {
1678
- const tagPattern = /@[\w]+/g;
1679
- const suiteParts = titlePath.slice(3, titlePath.length - 1).map((p) => p.replace(tagPattern, "").trim());
1680
- return {
1681
- hierarchy: suiteParts.join(" > "),
1682
- // full hierarchy
1683
- topLevelSuite: suiteParts[0] ?? "",
1684
- // first suite
1685
- parentSuite: suiteParts[suiteParts.length - 1] ?? ""
1686
- // last suite
1687
- };
1688
- }
1689
-
1690
1696
  // src/helpers/resultProcessor.ts
1691
1697
  var TestResultProcessor = class {
1692
1698
  constructor(projectRoot) {
@@ -1961,7 +1967,8 @@ var DatabaseManager = class {
1961
1967
  );
1962
1968
  return results.map((result) => ({
1963
1969
  ...result,
1964
- run_date: formatDateLocal(result.run_date)
1970
+ run_date: result.run_date
1971
+ // Return raw ISO string to avoid parsing issues in browser
1965
1972
  }));
1966
1973
  } catch (error) {
1967
1974
  console.error("OrtoniReport: Error getting test history:", error);
@@ -2044,7 +2051,8 @@ var DatabaseManager = class {
2044
2051
  );
2045
2052
  return rows.reverse().map((row) => ({
2046
2053
  ...row,
2047
- run_date: formatDateLocal(row.run_date),
2054
+ run_date: row.run_date,
2055
+ // Return raw ISO string for chart compatibility
2048
2056
  avg_duration: Math.round(row.avg_duration || 0)
2049
2057
  // raw ms avg
2050
2058
  }));
@@ -8,7 +8,7 @@ import {
8
8
  extractSuites,
9
9
  normalizeFilePath,
10
10
  startReportServer
11
- } from "./chunk-4RZ5C7KY.mjs";
11
+ } from "./chunk-L6VOLEP2.mjs";
12
12
 
13
13
  // src/helpers/resultProcessor.ts
14
14
  import AnsiToHtml from "ansi-to-html";
@@ -4,7 +4,7 @@ export declare function safeStringify(obj: any, indent?: number): string;
4
4
  export declare function ensureHtmlExtension(filename: string): string;
5
5
  export declare function escapeHtml(unsafe: string): string;
6
6
  export declare function formatDateUTC(date: Date): string;
7
- export declare function formatDateLocal(dateInput: Date | string): string;
7
+ export declare function formatDateLocal(dateInput: Date | string | undefined | null): string;
8
8
  export declare function formatDateNoTimezone(isoString: string): string;
9
9
  type SuiteAndTitle = {
10
10
  hierarchy: string;
@@ -52,17 +52,26 @@ export function formatDateUTC(date) {
52
52
  return date.toISOString();
53
53
  }
54
54
  export function formatDateLocal(dateInput) {
55
- const date = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
56
- const options = {
57
- year: "numeric",
58
- month: "short",
59
- day: "2-digit",
60
- hour: "2-digit",
61
- minute: "2-digit",
62
- hour12: true,
63
- timeZoneName: "short", // or "Asia/Kolkata"
64
- };
65
- return new Intl.DateTimeFormat(undefined, options).format(date);
55
+ if (!dateInput)
56
+ return "N/A";
57
+ try {
58
+ const date = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
59
+ if (isNaN(date.getTime())) {
60
+ return "N/A";
61
+ }
62
+ const options = {
63
+ year: "numeric",
64
+ month: "short",
65
+ day: "2-digit",
66
+ hour: "2-digit",
67
+ minute: "2-digit",
68
+ hour12: true,
69
+ };
70
+ return new Intl.DateTimeFormat("en-US", options).format(date);
71
+ }
72
+ catch (e) {
73
+ return "N/A";
74
+ }
66
75
  }
67
76
  export function formatDateNoTimezone(isoString) {
68
77
  const date = new Date(isoString);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ortoni-report",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "description": "Playwright Report By LetCode with Koushik",
5
5
  "scripts": {
6
6
  "tsc": "tsc",