@arghajit/dummy 0.1.0-beta-14 → 0.1.0-beta-16

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.
@@ -5,7 +5,6 @@ import { readFileSync, existsSync as fsExistsSync } from "fs"; // ADD THIS LINE
5
5
  import path from "path";
6
6
  import { fork } from "child_process"; // Add this
7
7
  import { fileURLToPath } from "url"; // Add this for resolving path in ESM
8
- import prettyAnsi from "pretty-ansi";
9
8
 
10
9
  // Use dynamic import for chalk as it's ESM only
11
10
  let chalk;
@@ -27,6 +26,129 @@ const DEFAULT_OUTPUT_DIR = "pulse-report";
27
26
  const DEFAULT_JSON_FILE = "playwright-pulse-report.json";
28
27
  const DEFAULT_HTML_FILE = "playwright-pulse-static-report.html";
29
28
  // Helper functions
29
+ export function ansiToHtml(text) {
30
+ if (!text) {
31
+ return "";
32
+ }
33
+
34
+ const codes = {
35
+ 0: "color:inherit;font-weight:normal;font-style:normal;text-decoration:none;opacity:1;background-color:inherit;",
36
+ 1: "font-weight:bold",
37
+ 2: "opacity:0.6",
38
+ 3: "font-style:italic",
39
+ 4: "text-decoration:underline",
40
+ 30: "color:#000", // black
41
+ 31: "color:#d00", // red
42
+ 32: "color:#0a0", // green
43
+ 33: "color:#aa0", // yellow
44
+ 34: "color:#00d", // blue
45
+ 35: "color:#a0a", // magenta
46
+ 36: "color:#0aa", // cyan
47
+ 37: "color:#aaa", // light grey
48
+ 39: "color:inherit", // default foreground color
49
+ 40: "background-color:#000", // black background
50
+ 41: "background-color:#d00", // red background
51
+ 42: "background-color:#0a0", // green background
52
+ 43: "background-color:#aa0", // yellow background
53
+ 44: "background-color:#00d", // blue background
54
+ 45: "background-color:#a0a", // magenta background
55
+ 46: "background-color:#0aa", // cyan background
56
+ 47: "background-color:#aaa", // light grey background
57
+ 49: "background-color:inherit", // default background color
58
+ 90: "color:#555", // dark grey
59
+ 91: "color:#f55", // light red
60
+ 92: "color:#5f5", // light green
61
+ 93: "color:#ff5", // light yellow
62
+ 94: "color:#55f", // light blue
63
+ 95: "color:#f5f", // light magenta
64
+ 96: "color:#5ff", // light cyan
65
+ 97: "color:#fff", // white
66
+ };
67
+
68
+ let currentStylesArray = [];
69
+ let html = "";
70
+ let openSpan = false;
71
+
72
+ const applyStyles = () => {
73
+ if (openSpan) {
74
+ html += "</span>";
75
+ openSpan = false;
76
+ }
77
+ if (currentStylesArray.length > 0) {
78
+ const styleString = currentStylesArray.filter((s) => s).join(";");
79
+ if (styleString) {
80
+ html += `<span style="${styleString}">`;
81
+ openSpan = true;
82
+ }
83
+ }
84
+ };
85
+
86
+ const resetAndApplyNewCodes = (newCodesStr) => {
87
+ const newCodes = newCodesStr.split(";");
88
+
89
+ if (newCodes.includes("0")) {
90
+ currentStylesArray = [];
91
+ if (codes["0"]) currentStylesArray.push(codes["0"]);
92
+ }
93
+
94
+ for (const code of newCodes) {
95
+ if (code === "0") continue;
96
+
97
+ if (codes[code]) {
98
+ if (code === "39") {
99
+ currentStylesArray = currentStylesArray.filter(
100
+ (s) => !s.startsWith("color:")
101
+ );
102
+ currentStylesArray.push("color:inherit");
103
+ } else if (code === "49") {
104
+ currentStylesArray = currentStylesArray.filter(
105
+ (s) => !s.startsWith("background-color:")
106
+ );
107
+ currentStylesArray.push("background-color:inherit");
108
+ } else {
109
+ currentStylesArray.push(codes[code]);
110
+ }
111
+ } else if (code.startsWith("38;2;") || code.startsWith("48;2;")) {
112
+ const parts = code.split(";");
113
+ const type = parts[0] === "38" ? "color" : "background-color";
114
+ if (parts.length === 5) {
115
+ currentStylesArray = currentStylesArray.filter(
116
+ (s) => !s.startsWith(type + ":")
117
+ );
118
+ currentStylesArray.push(
119
+ `${type}:rgb(${parts[2]},${parts[3]},${parts[4]})`
120
+ );
121
+ }
122
+ }
123
+ }
124
+ applyStyles();
125
+ };
126
+
127
+ const segments = text.split(/(\x1b\[[0-9;]*m)/g);
128
+
129
+ for (const segment of segments) {
130
+ if (!segment) continue;
131
+
132
+ if (segment.startsWith("\x1b[") && segment.endsWith("m")) {
133
+ const command = segment.slice(2, -1);
134
+ resetAndApplyNewCodes(command);
135
+ } else {
136
+ const escapedContent = segment
137
+ .replace(/&/g, "&amp;")
138
+ .replace(/</g, "&lt;")
139
+ .replace(/>/g, "&gt;")
140
+ .replace(/"/g, "&quot;")
141
+ .replace(/'/g, "&#039;");
142
+ html += escapedContent;
143
+ }
144
+ }
145
+
146
+ if (openSpan) {
147
+ html += "</span>";
148
+ }
149
+
150
+ return html;
151
+ }
30
152
  function sanitizeHTML(str) {
31
153
  if (str === null || str === undefined) return "";
32
154
  return String(str).replace(/[&<>"']/g, (match) => {
@@ -45,7 +167,7 @@ function capitalize(str) {
45
167
  return str[0].toUpperCase() + str.slice(1).toLowerCase();
46
168
  }
47
169
  function formatPlaywrightError(error) {
48
- const commandOutput = prettyAnsi(error || error.message);
170
+ const commandOutput = ansiToHtml(error || error.message);
49
171
  return convertPlaywrightErrorToHTML(commandOutput);
50
172
  }
51
173
  function convertPlaywrightErrorToHTML(str) {
@@ -585,6 +707,335 @@ function generatePieChart(data, chartWidth = 300, chartHeight = 300) {
585
707
  </div>
586
708
  `;
587
709
  }
710
+ function generateEnvironmentDashboard(environment, dashboardHeight = 600) {
711
+ // Format memory for display
712
+ const formattedMemory = environment.memory.replace(/(\d+\.\d{2})GB/, "$1 GB");
713
+
714
+ // Generate a unique ID for the dashboard
715
+ const dashboardId = `envDashboard-${Date.now()}-${Math.random()
716
+ .toString(36)
717
+ .substring(2, 7)}`;
718
+
719
+ const cardHeight = Math.floor(dashboardHeight * 0.44);
720
+ const cardContentPadding = 16; // px
721
+
722
+ return `
723
+ <div class="environment-dashboard-wrapper" id="${dashboardId}">
724
+ <style>
725
+ .environment-dashboard-wrapper *,
726
+ .environment-dashboard-wrapper *::before,
727
+ .environment-dashboard-wrapper *::after {
728
+ box-sizing: border-box;
729
+ }
730
+
731
+ .environment-dashboard-wrapper {
732
+ --primary-color: #007bff;
733
+ --primary-light-color: #e6f2ff;
734
+ --secondary-color: #6c757d;
735
+ --success-color: #28a745;
736
+ --success-light-color: #eaf6ec;
737
+ --warning-color: #ffc107;
738
+ --warning-light-color: #fff9e6;
739
+ --danger-color: #dc3545;
740
+
741
+ --background-color: #ffffff;
742
+ --card-background-color: #ffffff;
743
+ --text-color: #212529;
744
+ --text-color-secondary: #6c757d;
745
+ --border-color: #dee2e6;
746
+ --border-light-color: #f1f3f5;
747
+ --icon-color: #495057;
748
+ --chip-background: #e9ecef;
749
+ --chip-text: #495057;
750
+ --shadow-color: rgba(0, 0, 0, 0.075);
751
+
752
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
753
+ background-color: var(--background-color);
754
+ border-radius: 12px;
755
+ box-shadow: 0 6px 12px var(--shadow-color);
756
+ padding: 24px;
757
+ color: var(--text-color);
758
+ display: grid;
759
+ grid-template-columns: 1fr 1fr;
760
+ grid-template-rows: auto 1fr;
761
+ gap: 20px;
762
+ font-size: 14px;
763
+ }
764
+
765
+ .env-dashboard-header {
766
+ grid-column: 1 / -1;
767
+ display: flex;
768
+ justify-content: space-between;
769
+ align-items: center;
770
+ border-bottom: 1px solid var(--border-color);
771
+ padding-bottom: 16px;
772
+ margin-bottom: 8px;
773
+ }
774
+
775
+ .env-dashboard-title {
776
+ font-size: 1.5rem;
777
+ font-weight: 600;
778
+ color: var(--text-color);
779
+ margin: 0;
780
+ }
781
+
782
+ .env-dashboard-subtitle {
783
+ font-size: 0.875rem;
784
+ color: var(--text-color-secondary);
785
+ margin-top: 4px;
786
+ }
787
+
788
+ .env-card {
789
+ background-color: var(--card-background-color);
790
+ border-radius: 8px;
791
+ padding: ${cardContentPadding}px;
792
+ box-shadow: 0 3px 6px var(--shadow-color);
793
+ height: ${cardHeight}px;
794
+ display: flex;
795
+ flex-direction: column;
796
+ overflow: hidden;
797
+ }
798
+
799
+ .env-card-header {
800
+ font-weight: 600;
801
+ font-size: 1rem;
802
+ margin-bottom: 12px;
803
+ color: var(--text-color);
804
+ display: flex;
805
+ align-items: center;
806
+ padding-bottom: 8px;
807
+ border-bottom: 1px solid var(--border-light-color);
808
+ }
809
+
810
+ .env-card-header svg {
811
+ margin-right: 10px;
812
+ width: 18px;
813
+ height: 18px;
814
+ fill: var(--icon-color);
815
+ }
816
+
817
+ .env-card-content {
818
+ flex-grow: 1;
819
+ overflow-y: auto;
820
+ padding-right: 5px;
821
+ }
822
+
823
+ .env-detail-row {
824
+ display: flex;
825
+ justify-content: space-between;
826
+ align-items: center;
827
+ padding: 10px 0;
828
+ border-bottom: 1px solid var(--border-light-color);
829
+ font-size: 0.875rem;
830
+ }
831
+
832
+ .env-detail-row:last-child {
833
+ border-bottom: none;
834
+ }
835
+
836
+ .env-detail-label {
837
+ color: var(--text-color-secondary);
838
+ font-weight: 500;
839
+ margin-right: 10px;
840
+ }
841
+
842
+ .env-detail-value {
843
+ color: var(--text-color);
844
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
845
+ text-align: right;
846
+ word-break: break-all;
847
+ }
848
+
849
+ .env-chip {
850
+ display: inline-block;
851
+ padding: 4px 10px;
852
+ border-radius: 16px;
853
+ font-size: 0.75rem;
854
+ font-weight: 500;
855
+ line-height: 1.2;
856
+ background-color: var(--chip-background);
857
+ color: var(--chip-text);
858
+ }
859
+
860
+ .env-chip-primary {
861
+ background-color: var(--primary-light-color);
862
+ color: var(--primary-color);
863
+ }
864
+
865
+ .env-chip-success {
866
+ background-color: var(--success-light-color);
867
+ color: var(--success-color);
868
+ }
869
+
870
+ .env-chip-warning {
871
+ background-color: var(--warning-light-color);
872
+ color: var(--warning-color);
873
+ }
874
+
875
+ .env-cpu-cores {
876
+ display: flex;
877
+ align-items: center;
878
+ gap: 6px;
879
+ }
880
+
881
+ .env-core-indicator {
882
+ width: 12px;
883
+ height: 12px;
884
+ border-radius: 50%;
885
+ background-color: var(--success-color);
886
+ border: 1px solid rgba(0,0,0,0.1);
887
+ }
888
+
889
+ .env-core-indicator.inactive {
890
+ background-color: var(--border-light-color);
891
+ opacity: 0.7;
892
+ border-color: var(--border-color);
893
+ }
894
+ </style>
895
+
896
+ <div class="env-dashboard-header">
897
+ <div>
898
+ <h3 class="env-dashboard-title">System Environment</h3>
899
+ <p class="env-dashboard-subtitle">Snapshot of the execution environment</p>
900
+ </div>
901
+ <span class="env-chip env-chip-primary">${environment.host}</span>
902
+ </div>
903
+
904
+ <div class="env-card">
905
+ <div class="env-card-header">
906
+ <svg viewBox="0 0 24 24"><path d="M4 6h16V4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h-2v10H4V6zm18-2h-4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2H6a2 2 0 0 0-2 2v2h20V6a2 2 0 0 0-2-2zM8 12h8v2H8v-2zm0 4h8v2H8v-2z"/></svg>
907
+ Hardware
908
+ </div>
909
+ <div class="env-card-content">
910
+ <div class="env-detail-row">
911
+ <span class="env-detail-label">CPU Model</span>
912
+ <span class="env-detail-value">${environment.cpu.model}</span>
913
+ </div>
914
+ <div class="env-detail-row">
915
+ <span class="env-detail-label">CPU Cores</span>
916
+ <span class="env-detail-value">
917
+ <div class="env-cpu-cores">
918
+ ${Array.from(
919
+ { length: Math.max(0, environment.cpu.cores || 0) },
920
+ (_, i) =>
921
+ `<div class="env-core-indicator ${
922
+ i >=
923
+ (environment.cpu.cores >= 8 ? 8 : environment.cpu.cores)
924
+ ? "inactive"
925
+ : ""
926
+ }" title="Core ${i + 1}"></div>`
927
+ ).join("")}
928
+ <span>${environment.cpu.cores || "N/A"} cores</span>
929
+ </div>
930
+ </span>
931
+ </div>
932
+ <div class="env-detail-row">
933
+ <span class="env-detail-label">Memory</span>
934
+ <span class="env-detail-value">${formattedMemory}</span>
935
+ </div>
936
+ </div>
937
+ </div>
938
+
939
+ <div class="env-card">
940
+ <div class="env-card-header">
941
+ <svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-0.01 18c-2.76 0-5.26-1.12-7.07-2.93A7.973 7.973 0 0 1 4 12c0-2.21.9-4.21 2.36-5.64A7.994 7.994 0 0 1 11.99 4c4.41 0 8 3.59 8 8 0 2.76-1.12 5.26-2.93 7.07A7.973 7.973 0 0 1 11.99 20zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"/></svg>
942
+ Operating System
943
+ </div>
944
+ <div class="env-card-content">
945
+ <div class="env-detail-row">
946
+ <span class="env-detail-label">OS Type</span>
947
+ <span class="env-detail-value">${
948
+ environment.os.split(" ")[0] === "darwin"
949
+ ? "darwin (macOS)"
950
+ : environment.os.split(" ")[0] || "Unknown"
951
+ }</span>
952
+ </div>
953
+ <div class="env-detail-row">
954
+ <span class="env-detail-label">OS Version</span>
955
+ <span class="env-detail-value">${
956
+ environment.os.split(" ")[1] || "N/A"
957
+ }</span>
958
+ </div>
959
+ <div class="env-detail-row">
960
+ <span class="env-detail-label">Hostname</span>
961
+ <span class="env-detail-value" title="${environment.host}">${
962
+ environment.host
963
+ }</span>
964
+ </div>
965
+ </div>
966
+ </div>
967
+
968
+ <div class="env-card">
969
+ <div class="env-card-header">
970
+ <svg viewBox="0 0 24 24"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>
971
+ Node.js Runtime
972
+ </div>
973
+ <div class="env-card-content">
974
+ <div class="env-detail-row">
975
+ <span class="env-detail-label">Node Version</span>
976
+ <span class="env-detail-value">${environment.node}</span>
977
+ </div>
978
+ <div class="env-detail-row">
979
+ <span class="env-detail-label">V8 Engine</span>
980
+ <span class="env-detail-value">${environment.v8}</span>
981
+ </div>
982
+ <div class="env-detail-row">
983
+ <span class="env-detail-label">Working Dir</span>
984
+ <span class="env-detail-value" title="${environment.cwd}">${
985
+ environment.cwd.length > 25
986
+ ? "..." + environment.cwd.slice(-22)
987
+ : environment.cwd
988
+ }</span>
989
+ </div>
990
+ </div>
991
+ </div>
992
+
993
+ <div class="env-card">
994
+ <div class="env-card-header">
995
+ <svg viewBox="0 0 24 24"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 8.69 9.48 7 12 7c2.76 0 5 2.24 5 5v1h2c1.66 0 3 1.34 3 3s-1.34 3-3 3z"/></svg>
996
+ System Summary
997
+ </div>
998
+ <div class="env-card-content">
999
+ <div class="env-detail-row">
1000
+ <span class="env-detail-label">Platform Arch</span>
1001
+ <span class="env-detail-value">
1002
+ <span class="env-chip ${
1003
+ environment.os.includes("darwin") &&
1004
+ environment.cpu.model.toLowerCase().includes("apple")
1005
+ ? "env-chip-success"
1006
+ : "env-chip-warning"
1007
+ }">
1008
+ ${
1009
+ environment.os.includes("darwin") &&
1010
+ environment.cpu.model.toLowerCase().includes("apple")
1011
+ ? "Apple Silicon"
1012
+ : environment.cpu.model.toLowerCase().includes("arm") ||
1013
+ environment.cpu.model.toLowerCase().includes("aarch64")
1014
+ ? "ARM-based"
1015
+ : "x86/Other"
1016
+ }
1017
+ </span>
1018
+ </span>
1019
+ </div>
1020
+ <div class="env-detail-row">
1021
+ <span class="env-detail-label">Memory per Core</span>
1022
+ <span class="env-detail-value">${
1023
+ environment.cpu.cores > 0
1024
+ ? (
1025
+ parseFloat(environment.memory) / environment.cpu.cores
1026
+ ).toFixed(2) + " GB"
1027
+ : "N/A"
1028
+ }</span>
1029
+ </div>
1030
+ <div class="env-detail-row">
1031
+ <span class="env-detail-label">Run Context</span>
1032
+ <span class="env-detail-value">CI/Local Test</span>
1033
+ </div>
1034
+ </div>
1035
+ </div>
1036
+ </div>
1037
+ `;
1038
+ }
588
1039
  function generateTestHistoryContent(trendData) {
589
1040
  if (
590
1041
  !trendData ||
@@ -1197,7 +1648,7 @@ function generateHTML(reportData, trendData = null) {
1197
1648
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1198
1649
  <link rel="icon" type="image/png" href="https://i.postimg.cc/XqVn1NhF/pulse.png">
1199
1650
  <link rel="apple-touch-icon" href="https://i.postimg.cc/XqVn1NhF/pulse.png">
1200
- <script src="https://code.highcharts.com/highcharts.js"></script>
1651
+ <script src="https://code.highcharts.com/highcharts.js" defer></script>
1201
1652
  <title>Playwright Pulse Report</title>
1202
1653
  <style>
1203
1654
  :root {
@@ -1397,6 +1848,7 @@ function generateHTML(reportData, trendData = null) {
1397
1848
  )}</div></div>
1398
1849
  </div>
1399
1850
  <div class="dashboard-bottom-row">
1851
+ <div style="display: grid; gap: 20px">
1400
1852
  ${generatePieChart(
1401
1853
  [
1402
1854
  { label: "Passed", value: runSummary.passed },
@@ -1406,6 +1858,13 @@ function generateHTML(reportData, trendData = null) {
1406
1858
  400,
1407
1859
  390
1408
1860
  )}
1861
+ ${
1862
+ runSummary.environment &&
1863
+ Object.keys(runSummary.environment).length > 0
1864
+ ? generateEnvironmentDashboard(runSummary.environment)
1865
+ : '<div class="no-data">Environment data not available.</div>'
1866
+ }
1867
+ </div>
1409
1868
  ${generateSuitesWidget(suitesData)}
1410
1869
  </div>
1411
1870
  </div>
@@ -39,6 +39,7 @@ function mergeReports(files) {
39
39
  combinedRun.failed += run.failed || 0;
40
40
  combinedRun.skipped += run.skipped || 0;
41
41
  combinedRun.duration += run.duration || 0;
42
+ combinedRun.environment = run.environment;
42
43
 
43
44
  if (json.results) {
44
45
  combinedResults.push(...json.results);