ortoni-report 1.1.1 → 1.1.2
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/changelog.md +22 -0
- package/dist/icon/fail.png +0 -0
- package/dist/icon/file.png +0 -0
- package/dist/icon/pass.png +0 -0
- package/dist/icon/retry.png +0 -0
- package/dist/icon/skip.png +0 -0
- package/dist/icon/test.png +0 -0
- package/dist/icon/timeout.png +0 -0
- package/dist/ortoni-report.d.ts +1 -0
- package/dist/ortoni-report.js +41 -14
- package/dist/ortoni-report.mjs +41 -14
- package/dist/report-template.hbs +221 -94
- package/dist/utils/chart.js +11128 -0
- package/dist/utils/modal.js +76 -0
- package/package.json +3 -3
- package/readme.md +4 -4
package/changelog.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Change Log:
|
|
2
2
|
|
|
3
|
+
## Version 1.1.2
|
|
4
|
+
|
|
5
|
+
**New Features:**
|
|
6
|
+
- **Ellipsis Styling for Test Names:** Long test names are now truncated with ellipsis for better readability.
|
|
7
|
+
- **Retry, Pass, Fail, and Skip Indicators:** Added visual indicators (images) to denote the status of each test, including retries.
|
|
8
|
+
- **Enhanced `msToTime` Function:** Duration now includes milliseconds for more precise time tracking.
|
|
9
|
+
- **Summary Filters:** Clicking on summary filters (passed, failed & other) to display the selected filter.
|
|
10
|
+
|
|
11
|
+
**Improvements:**
|
|
12
|
+
- **Unified Status Handling:** The `applyFilter` function now treats `failed` and `timedOut` statuses as the same for consistent filtering.
|
|
13
|
+
- **Date and Time Formatting:** Passed date in the format `DD-MMM-YYYY` and included time for more detailed reporting.
|
|
14
|
+
- **Success Rate and Last Run Data:** Added the ability to pass `successRate` and `lastRun` data to the `onEnd` method for comprehensive report details.
|
|
15
|
+
|
|
16
|
+
**Bug Fixes:**
|
|
17
|
+
- Fixed issues with conditionals in Handlebars for status checking.
|
|
18
|
+
- Improved event listener attachment for filtering and search functionalities.
|
|
19
|
+
|
|
20
|
+
**Notes:**
|
|
21
|
+
- Screenshot handling has been enhanced with modal dialogs, using Pico.css for styling.
|
|
22
|
+
|
|
23
|
+
This release includes several visual and functional enhancements aimed at improving the usability and readability of the Playwright test reports. The added features and improvements will help users better understand test outcomes and statuses at a glance.
|
|
24
|
+
|
|
3
25
|
### Version 1.1.0
|
|
4
26
|
|
|
5
27
|
## New Features
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/ortoni-report.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ declare class OrtoniReport implements Reporter {
|
|
|
15
15
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
16
16
|
onTestBegin(test: TestCase, result: TestResult): void;
|
|
17
17
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
18
|
+
private _successRate;
|
|
18
19
|
onEnd(result: FullResult): void;
|
|
19
20
|
generateHTML(): string;
|
|
20
21
|
}
|
package/dist/ortoni-report.js
CHANGED
|
@@ -38,30 +38,36 @@ var import_path2 = __toESM(require("path"));
|
|
|
38
38
|
var import_handlebars = __toESM(require("handlebars"));
|
|
39
39
|
var import_safe = __toESM(require("colors/safe"));
|
|
40
40
|
|
|
41
|
-
// src/utils/
|
|
41
|
+
// src/utils/utils.ts
|
|
42
42
|
var import_path = __toESM(require("path"));
|
|
43
43
|
function msToTime(duration) {
|
|
44
|
+
const milliseconds = Math.floor(duration % 1e3);
|
|
44
45
|
const seconds = Math.floor(duration / 1e3 % 60);
|
|
45
46
|
const minutes = Math.floor(duration / (1e3 * 60) % 60);
|
|
46
47
|
const hours = Math.floor(duration / (1e3 * 60 * 60) % 24);
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (seconds > 0 || parts.length === 0)
|
|
53
|
-
parts.push(seconds + "s");
|
|
54
|
-
return parts.join(" ");
|
|
48
|
+
const hoursStr = hours < 10 ? "0" + hours : hours;
|
|
49
|
+
const minutesStr = minutes < 10 ? "0" + minutes : minutes;
|
|
50
|
+
const secondsStr = seconds < 10 ? "0" + seconds : seconds;
|
|
51
|
+
const millisecondsStr = milliseconds < 100 ? "0" + milliseconds : milliseconds;
|
|
52
|
+
return `${hoursStr}:${minutesStr}:${secondsStr}.${millisecondsStr}`;
|
|
55
53
|
}
|
|
56
54
|
function normalizeFilePath(filePath) {
|
|
57
55
|
const normalizedPath = import_path.default.normalize(filePath);
|
|
58
56
|
return import_path.default.basename(normalizedPath);
|
|
59
57
|
}
|
|
58
|
+
function formatDate(date) {
|
|
59
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
60
|
+
const month = date.toLocaleString("default", { month: "short" });
|
|
61
|
+
const year = date.getFullYear();
|
|
62
|
+
const time = date.toLocaleTimeString();
|
|
63
|
+
return `${day}-${month}-${year} ${time}`;
|
|
64
|
+
}
|
|
60
65
|
|
|
61
66
|
// src/ortoni-report.ts
|
|
62
67
|
var OrtoniReport = class {
|
|
63
68
|
constructor(config = {}) {
|
|
64
69
|
this.results = [];
|
|
70
|
+
this._successRate = "";
|
|
65
71
|
this.config = config;
|
|
66
72
|
}
|
|
67
73
|
onBegin(config, suite) {
|
|
@@ -75,14 +81,19 @@ var OrtoniReport = class {
|
|
|
75
81
|
onTestBegin(test, result) {
|
|
76
82
|
}
|
|
77
83
|
onTestEnd(test, result) {
|
|
84
|
+
let status = result.status;
|
|
85
|
+
if (test.outcome() === "flaky") {
|
|
86
|
+
status = "flaky";
|
|
87
|
+
}
|
|
78
88
|
const testResult = {
|
|
89
|
+
isRetry: result.retry,
|
|
79
90
|
totalDuration: "",
|
|
80
91
|
projectName: test.titlePath()[1],
|
|
81
92
|
// Get the project name
|
|
82
93
|
suite: test.titlePath()[3],
|
|
83
94
|
// Adjust the index based on your suite hierarchy
|
|
84
95
|
title: test.title,
|
|
85
|
-
status
|
|
96
|
+
status,
|
|
86
97
|
flaky: test.outcome(),
|
|
87
98
|
duration: msToTime(result.duration),
|
|
88
99
|
errors: result.errors.map((e) => import_safe.default.strip(e.message || e.toString())),
|
|
@@ -112,6 +123,7 @@ var OrtoniReport = class {
|
|
|
112
123
|
this.results.push(testResult);
|
|
113
124
|
}
|
|
114
125
|
onEnd(result) {
|
|
126
|
+
this._successRate = (this.results.filter((r) => r.status === "passed").length / this.results.length * 100).toFixed(2);
|
|
115
127
|
this.results[0].totalDuration = msToTime(result.duration);
|
|
116
128
|
this.groupedResults = this.results.reduce((acc, result2, index) => {
|
|
117
129
|
const filePath = result2.filePath;
|
|
@@ -132,6 +144,22 @@ var OrtoniReport = class {
|
|
|
132
144
|
import_handlebars.default.registerHelper("json", function(context) {
|
|
133
145
|
return safeStringify(context);
|
|
134
146
|
});
|
|
147
|
+
import_handlebars.default.registerHelper("eq", function(actualStatus, expectedStatus) {
|
|
148
|
+
return actualStatus === expectedStatus;
|
|
149
|
+
});
|
|
150
|
+
import_handlebars.default.registerHelper("or", () => {
|
|
151
|
+
var args = Array.prototype.slice.call(arguments);
|
|
152
|
+
var options = args.pop();
|
|
153
|
+
for (var i = 0; i < args.length; i++) {
|
|
154
|
+
if (args[i]) {
|
|
155
|
+
return options.fn(this);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return options.inverse(this);
|
|
159
|
+
});
|
|
160
|
+
import_handlebars.default.registerHelper("gt", function(a, b) {
|
|
161
|
+
return a > b;
|
|
162
|
+
});
|
|
135
163
|
const html = this.generateHTML();
|
|
136
164
|
const outputPath = import_path2.default.resolve(process.cwd(), "ortoni-report.html");
|
|
137
165
|
import_fs.default.writeFileSync(outputPath, html);
|
|
@@ -151,11 +179,10 @@ var OrtoniReport = class {
|
|
|
151
179
|
totalCount: this.results.length,
|
|
152
180
|
groupedResults: this.groupedResults,
|
|
153
181
|
projectName: this.config.projectName,
|
|
154
|
-
// Include project name
|
|
155
182
|
authorName: this.config.authorName,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
183
|
+
testType: this.config.testType,
|
|
184
|
+
successRate: this._successRate,
|
|
185
|
+
lastRunDate: formatDate(/* @__PURE__ */ new Date())
|
|
159
186
|
};
|
|
160
187
|
return template(data);
|
|
161
188
|
}
|
package/dist/ortoni-report.mjs
CHANGED
|
@@ -4,30 +4,36 @@ import path2 from "path";
|
|
|
4
4
|
import Handlebars from "handlebars";
|
|
5
5
|
import colors from "colors/safe";
|
|
6
6
|
|
|
7
|
-
// src/utils/
|
|
7
|
+
// src/utils/utils.ts
|
|
8
8
|
import path from "path";
|
|
9
9
|
function msToTime(duration) {
|
|
10
|
+
const milliseconds = Math.floor(duration % 1e3);
|
|
10
11
|
const seconds = Math.floor(duration / 1e3 % 60);
|
|
11
12
|
const minutes = Math.floor(duration / (1e3 * 60) % 60);
|
|
12
13
|
const hours = Math.floor(duration / (1e3 * 60 * 60) % 24);
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (seconds > 0 || parts.length === 0)
|
|
19
|
-
parts.push(seconds + "s");
|
|
20
|
-
return parts.join(" ");
|
|
14
|
+
const hoursStr = hours < 10 ? "0" + hours : hours;
|
|
15
|
+
const minutesStr = minutes < 10 ? "0" + minutes : minutes;
|
|
16
|
+
const secondsStr = seconds < 10 ? "0" + seconds : seconds;
|
|
17
|
+
const millisecondsStr = milliseconds < 100 ? "0" + milliseconds : milliseconds;
|
|
18
|
+
return `${hoursStr}:${minutesStr}:${secondsStr}.${millisecondsStr}`;
|
|
21
19
|
}
|
|
22
20
|
function normalizeFilePath(filePath) {
|
|
23
21
|
const normalizedPath = path.normalize(filePath);
|
|
24
22
|
return path.basename(normalizedPath);
|
|
25
23
|
}
|
|
24
|
+
function formatDate(date) {
|
|
25
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
26
|
+
const month = date.toLocaleString("default", { month: "short" });
|
|
27
|
+
const year = date.getFullYear();
|
|
28
|
+
const time = date.toLocaleTimeString();
|
|
29
|
+
return `${day}-${month}-${year} ${time}`;
|
|
30
|
+
}
|
|
26
31
|
|
|
27
32
|
// src/ortoni-report.ts
|
|
28
33
|
var OrtoniReport = class {
|
|
29
34
|
constructor(config = {}) {
|
|
30
35
|
this.results = [];
|
|
36
|
+
this._successRate = "";
|
|
31
37
|
this.config = config;
|
|
32
38
|
}
|
|
33
39
|
onBegin(config, suite) {
|
|
@@ -41,14 +47,19 @@ var OrtoniReport = class {
|
|
|
41
47
|
onTestBegin(test, result) {
|
|
42
48
|
}
|
|
43
49
|
onTestEnd(test, result) {
|
|
50
|
+
let status = result.status;
|
|
51
|
+
if (test.outcome() === "flaky") {
|
|
52
|
+
status = "flaky";
|
|
53
|
+
}
|
|
44
54
|
const testResult = {
|
|
55
|
+
isRetry: result.retry,
|
|
45
56
|
totalDuration: "",
|
|
46
57
|
projectName: test.titlePath()[1],
|
|
47
58
|
// Get the project name
|
|
48
59
|
suite: test.titlePath()[3],
|
|
49
60
|
// Adjust the index based on your suite hierarchy
|
|
50
61
|
title: test.title,
|
|
51
|
-
status
|
|
62
|
+
status,
|
|
52
63
|
flaky: test.outcome(),
|
|
53
64
|
duration: msToTime(result.duration),
|
|
54
65
|
errors: result.errors.map((e) => colors.strip(e.message || e.toString())),
|
|
@@ -78,6 +89,7 @@ var OrtoniReport = class {
|
|
|
78
89
|
this.results.push(testResult);
|
|
79
90
|
}
|
|
80
91
|
onEnd(result) {
|
|
92
|
+
this._successRate = (this.results.filter((r) => r.status === "passed").length / this.results.length * 100).toFixed(2);
|
|
81
93
|
this.results[0].totalDuration = msToTime(result.duration);
|
|
82
94
|
this.groupedResults = this.results.reduce((acc, result2, index) => {
|
|
83
95
|
const filePath = result2.filePath;
|
|
@@ -98,6 +110,22 @@ var OrtoniReport = class {
|
|
|
98
110
|
Handlebars.registerHelper("json", function(context) {
|
|
99
111
|
return safeStringify(context);
|
|
100
112
|
});
|
|
113
|
+
Handlebars.registerHelper("eq", function(actualStatus, expectedStatus) {
|
|
114
|
+
return actualStatus === expectedStatus;
|
|
115
|
+
});
|
|
116
|
+
Handlebars.registerHelper("or", () => {
|
|
117
|
+
var args = Array.prototype.slice.call(arguments);
|
|
118
|
+
var options = args.pop();
|
|
119
|
+
for (var i = 0; i < args.length; i++) {
|
|
120
|
+
if (args[i]) {
|
|
121
|
+
return options.fn(this);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return options.inverse(this);
|
|
125
|
+
});
|
|
126
|
+
Handlebars.registerHelper("gt", function(a, b) {
|
|
127
|
+
return a > b;
|
|
128
|
+
});
|
|
101
129
|
const html = this.generateHTML();
|
|
102
130
|
const outputPath = path2.resolve(process.cwd(), "ortoni-report.html");
|
|
103
131
|
fs.writeFileSync(outputPath, html);
|
|
@@ -117,11 +145,10 @@ var OrtoniReport = class {
|
|
|
117
145
|
totalCount: this.results.length,
|
|
118
146
|
groupedResults: this.groupedResults,
|
|
119
147
|
projectName: this.config.projectName,
|
|
120
|
-
// Include project name
|
|
121
148
|
authorName: this.config.authorName,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
149
|
+
testType: this.config.testType,
|
|
150
|
+
successRate: this._successRate,
|
|
151
|
+
lastRunDate: formatDate(/* @__PURE__ */ new Date())
|
|
125
152
|
};
|
|
126
153
|
return template(data);
|
|
127
154
|
}
|