ortoni-report 2.0.2 → 2.0.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.
- package/changelog.md +17 -0
- package/dist/ortoni-report.d.ts +9 -2
- package/dist/ortoni-report.js +55 -35
- package/dist/ortoni-report.mjs +55 -35
- package/dist/style/main.css +86 -0
- package/dist/{report-template.hbs → views/main.hbs} +133 -373
- package/dist/views/navbar.hbs +46 -0
- package/dist/views/summaryCard.hbs +14 -0
- package/dist/views/testPanel.hbs +37 -0
- package/dist/views/testStatus.hbs +33 -0
- package/dist/views/userInfo.hbs +46 -0
- package/package.json +3 -8
- package/readme.md +15 -42
- package/dist/css/main.css +0 -22444
- package/dist/icon/32.png +0 -0
- package/dist/icon/fail.png +0 -0
- package/dist/icon/file.png +0 -0
- package/dist/icon/flaky.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/utils/chart.js +0 -11128
package/changelog.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Change Log:
|
|
2
2
|
|
|
3
|
+
## Version 2.0.3
|
|
4
|
+
|
|
5
|
+
#### 🚀 New Features
|
|
6
|
+
- **Add screenshot attachment as pagination**: Now supports adding screenshot attachments for easier navigation and pagination.
|
|
7
|
+
- **Bulma Inline CSS**: Integrated Bulma inline CSS for improved styling.
|
|
8
|
+
- **Show card if the count has value**: Cards will now appear only when a valid count is present.
|
|
9
|
+
- **Folder Path**: Introduced a new feature to store the result in the folder path.
|
|
10
|
+
|
|
11
|
+
#### ✨ Improvements
|
|
12
|
+
- **Chart JS as CDN**: Enhanced performance by switching Chart.js to be served via CDN.
|
|
13
|
+
- **Theme icon, navbar & summary icons**: Refined the design of theme icons, navbar, and summary icons for a better user experience.
|
|
14
|
+
- **User meta icons**: Updated and improved the appearance of user meta icons.
|
|
15
|
+
- **Show selected filter on nav-end**: Filters now appear on the nav-end when selected.
|
|
16
|
+
- **Filter logic**: Improved filter functionality by only displaying the filtered items, avoiding the use of the `includes` method.
|
|
17
|
+
- **Logo link to page**: Clicking on the logo now navigates to the corresponding page.
|
|
18
|
+
- **Minor tweaks**: Enhanced overall UI experience
|
|
19
|
+
|
|
3
20
|
## Version 2.0.2
|
|
4
21
|
|
|
5
22
|
#### 🚀 New Features
|
package/dist/ortoni-report.d.ts
CHANGED
|
@@ -53,6 +53,11 @@ interface OrtoniReportConfig {
|
|
|
53
53
|
* @example "index.html"
|
|
54
54
|
*/
|
|
55
55
|
filename?: string;
|
|
56
|
+
/**
|
|
57
|
+
* The folder name.
|
|
58
|
+
* @example "playwright-report"
|
|
59
|
+
*/
|
|
60
|
+
folderPath?: string;
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
interface Steps {
|
|
@@ -76,6 +81,7 @@ interface TestResultData {
|
|
|
76
81
|
steps: Steps[];
|
|
77
82
|
logs: string;
|
|
78
83
|
screenshotPath?: string | null | undefined;
|
|
84
|
+
screenshots?: string[];
|
|
79
85
|
filePath: string;
|
|
80
86
|
filters: Set<string>;
|
|
81
87
|
tracePath?: string;
|
|
@@ -90,15 +96,16 @@ declare class OrtoniReport implements Reporter {
|
|
|
90
96
|
private suiteName;
|
|
91
97
|
private config;
|
|
92
98
|
private projectSet;
|
|
93
|
-
private
|
|
99
|
+
private folderPath;
|
|
94
100
|
constructor(config?: OrtoniReportConfig);
|
|
95
101
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
96
102
|
onTestBegin(test: TestCase, result: TestResult): void;
|
|
97
103
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
98
104
|
private attachFiles;
|
|
99
105
|
onEnd(result: FullResult): void;
|
|
106
|
+
private registerPartial;
|
|
100
107
|
private groupResults;
|
|
101
|
-
generateHTML(filteredResults: TestResultData[], totalDuration: string): string;
|
|
108
|
+
generateHTML(filteredResults: TestResultData[], totalDuration: string, cssContent: string): string;
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
export { OrtoniReportConfig, OrtoniReport as default };
|
package/dist/ortoni-report.js
CHANGED
|
@@ -6623,12 +6623,15 @@ var OrtoniReport = class {
|
|
|
6623
6623
|
this.results = [];
|
|
6624
6624
|
this.groupedResults = {};
|
|
6625
6625
|
this.projectSet = /* @__PURE__ */ new Set();
|
|
6626
|
-
this.tagsSet = /* @__PURE__ */ new Set();
|
|
6627
6626
|
this.config = config;
|
|
6627
|
+
this.folderPath = config.folderPath || "playwright-report";
|
|
6628
6628
|
}
|
|
6629
6629
|
onBegin(config, suite) {
|
|
6630
6630
|
this.results = [];
|
|
6631
6631
|
this.projectRoot = config.rootDir;
|
|
6632
|
+
if (!import_fs.default.existsSync(this.folderPath)) {
|
|
6633
|
+
import_fs.default.mkdirSync(this.folderPath, { recursive: true });
|
|
6634
|
+
}
|
|
6632
6635
|
}
|
|
6633
6636
|
onTestBegin(test, result) {
|
|
6634
6637
|
}
|
|
@@ -6683,35 +6686,34 @@ var OrtoniReport = class {
|
|
|
6683
6686
|
attachFiles(result, testResult) {
|
|
6684
6687
|
if (result.attachments) {
|
|
6685
6688
|
const { base64Image } = this.config;
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6689
|
+
testResult.screenshots = [];
|
|
6690
|
+
result.attachments.forEach((attachment) => {
|
|
6691
|
+
if (attachment.contentType === "image/png") {
|
|
6692
|
+
let screenshotPath = "";
|
|
6693
|
+
if (attachment.path) {
|
|
6694
|
+
try {
|
|
6695
|
+
const screenshotContent = import_fs.default.readFileSync(
|
|
6696
|
+
attachment.path,
|
|
6697
|
+
base64Image ? "base64" : void 0
|
|
6698
|
+
);
|
|
6699
|
+
screenshotPath = base64Image ? `data:image/png;base64,${screenshotContent}` : import_path2.default.resolve(attachment.path);
|
|
6700
|
+
} catch (error) {
|
|
6701
|
+
console.error(
|
|
6702
|
+
`OrtoniReport: Failed to read screenshot file: ${attachment.path}`,
|
|
6703
|
+
error
|
|
6704
|
+
);
|
|
6705
|
+
}
|
|
6706
|
+
} else if (attachment.body) {
|
|
6707
|
+
screenshotPath = `data:image/png;base64,${attachment.body.toString("base64")}`;
|
|
6708
|
+
}
|
|
6709
|
+
if (screenshotPath) {
|
|
6710
|
+
testResult.screenshots?.push(screenshotPath);
|
|
6711
|
+
}
|
|
6701
6712
|
}
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
);
|
|
6706
|
-
if (tracePath?.path) {
|
|
6707
|
-
testResult.tracePath = import_path2.default.resolve(__dirname, tracePath.path);
|
|
6708
|
-
}
|
|
6709
|
-
const videoPath = result.attachments.find(
|
|
6710
|
-
(attachment) => attachment.name === "video"
|
|
6711
|
-
);
|
|
6712
|
-
if (videoPath?.path) {
|
|
6713
|
-
testResult.videoPath = import_path2.default.resolve(__dirname, videoPath.path);
|
|
6714
|
-
}
|
|
6713
|
+
if (attachment.name === "video" && attachment.path) {
|
|
6714
|
+
testResult.videoPath = import_path2.default.resolve(__dirname, attachment.path);
|
|
6715
|
+
}
|
|
6716
|
+
});
|
|
6715
6717
|
}
|
|
6716
6718
|
}
|
|
6717
6719
|
onEnd(result) {
|
|
@@ -6727,17 +6729,36 @@ var OrtoniReport = class {
|
|
|
6727
6729
|
"eq",
|
|
6728
6730
|
(actualStatus, expectedStatus) => actualStatus === expectedStatus
|
|
6729
6731
|
);
|
|
6732
|
+
import_handlebars.default.registerHelper("gr", (count) => count > 0);
|
|
6733
|
+
const cssContent = import_fs.default.readFileSync(
|
|
6734
|
+
import_path2.default.resolve(__dirname, "style", "main.css"),
|
|
6735
|
+
"utf-8"
|
|
6736
|
+
);
|
|
6737
|
+
this.registerPartial("navbar");
|
|
6738
|
+
this.registerPartial("testStatus");
|
|
6739
|
+
this.registerPartial("testPanel");
|
|
6740
|
+
this.registerPartial("summaryCard");
|
|
6741
|
+
this.registerPartial("userInfo");
|
|
6730
6742
|
const outputFilename = ensureHtmlExtension(
|
|
6731
6743
|
this.config.filename || "ortoni-report.html"
|
|
6732
6744
|
);
|
|
6733
|
-
|
|
6734
|
-
|
|
6745
|
+
if (!import_fs.default.existsSync(this.folderPath)) {
|
|
6746
|
+
import_fs.default.mkdirSync(this.folderPath, { recursive: true });
|
|
6747
|
+
}
|
|
6748
|
+
const html = this.generateHTML(filteredResults, totalDuration, cssContent);
|
|
6749
|
+
const outputPath = import_path2.default.join(process.cwd(), this.folderPath, outputFilename);
|
|
6735
6750
|
import_fs.default.writeFileSync(outputPath, html);
|
|
6736
6751
|
console.log(`Ortoni HTML report generated at ${outputPath}`);
|
|
6737
6752
|
} catch (error) {
|
|
6738
6753
|
console.error("OrtoniReport: Error generating report:", error);
|
|
6739
6754
|
}
|
|
6740
6755
|
}
|
|
6756
|
+
registerPartial(name) {
|
|
6757
|
+
import_handlebars.default.registerPartial(name, import_fs.default.readFileSync(
|
|
6758
|
+
import_path2.default.resolve(__dirname, "views", name + ".hbs"),
|
|
6759
|
+
"utf-8"
|
|
6760
|
+
));
|
|
6761
|
+
}
|
|
6741
6762
|
groupResults() {
|
|
6742
6763
|
if (this.config.showProject) {
|
|
6743
6764
|
this.groupedResults = this.results.reduce((acc, result, index) => {
|
|
@@ -6758,7 +6779,7 @@ var OrtoniReport = class {
|
|
|
6758
6779
|
}, {});
|
|
6759
6780
|
}
|
|
6760
6781
|
}
|
|
6761
|
-
generateHTML(filteredResults, totalDuration) {
|
|
6782
|
+
generateHTML(filteredResults, totalDuration, cssContent) {
|
|
6762
6783
|
try {
|
|
6763
6784
|
const totalTests = filteredResults.length;
|
|
6764
6785
|
const passedTests = this.results.filter(
|
|
@@ -6770,14 +6791,13 @@ var OrtoniReport = class {
|
|
|
6770
6791
|
).length;
|
|
6771
6792
|
const successRate = ((passedTests + flakyTests) / totalTests * 100).toFixed(2);
|
|
6772
6793
|
const templateSource = import_fs.default.readFileSync(
|
|
6773
|
-
import_path2.default.resolve(__dirname, "
|
|
6794
|
+
import_path2.default.resolve(__dirname, "views", "main.hbs"),
|
|
6774
6795
|
"utf-8"
|
|
6775
6796
|
);
|
|
6776
6797
|
const template = import_handlebars.default.compile(templateSource);
|
|
6777
6798
|
const logo = this.config.logo ? import_path2.default.resolve(this.config.logo) : void 0;
|
|
6778
6799
|
const allTags = /* @__PURE__ */ new Set();
|
|
6779
6800
|
this.results.forEach((result) => {
|
|
6780
|
-
result.suiteTags.forEach((tag) => allTags.add(tag));
|
|
6781
6801
|
result.testTags.forEach((tag) => allTags.add(tag));
|
|
6782
6802
|
});
|
|
6783
6803
|
const data = {
|
|
@@ -6803,7 +6823,7 @@ var OrtoniReport = class {
|
|
|
6803
6823
|
showProject: this.config.showProject || false,
|
|
6804
6824
|
title: this.config.title || "Ortoni Playwright Test Report"
|
|
6805
6825
|
};
|
|
6806
|
-
return template(data);
|
|
6826
|
+
return template({ ...data, inlineCss: cssContent });
|
|
6807
6827
|
} catch (error) {
|
|
6808
6828
|
console.error("OrtoniReport: Error generating HTML:", error);
|
|
6809
6829
|
return `<html><body><h1>Report generation failed</h1><pre>${error.stack}</pre></body></html>`;
|
package/dist/ortoni-report.mjs
CHANGED
|
@@ -6619,12 +6619,15 @@ var OrtoniReport = class {
|
|
|
6619
6619
|
this.results = [];
|
|
6620
6620
|
this.groupedResults = {};
|
|
6621
6621
|
this.projectSet = /* @__PURE__ */ new Set();
|
|
6622
|
-
this.tagsSet = /* @__PURE__ */ new Set();
|
|
6623
6622
|
this.config = config;
|
|
6623
|
+
this.folderPath = config.folderPath || "playwright-report";
|
|
6624
6624
|
}
|
|
6625
6625
|
onBegin(config, suite) {
|
|
6626
6626
|
this.results = [];
|
|
6627
6627
|
this.projectRoot = config.rootDir;
|
|
6628
|
+
if (!fs.existsSync(this.folderPath)) {
|
|
6629
|
+
fs.mkdirSync(this.folderPath, { recursive: true });
|
|
6630
|
+
}
|
|
6628
6631
|
}
|
|
6629
6632
|
onTestBegin(test, result) {
|
|
6630
6633
|
}
|
|
@@ -6679,35 +6682,34 @@ var OrtoniReport = class {
|
|
|
6679
6682
|
attachFiles(result, testResult) {
|
|
6680
6683
|
if (result.attachments) {
|
|
6681
6684
|
const { base64Image } = this.config;
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6685
|
+
testResult.screenshots = [];
|
|
6686
|
+
result.attachments.forEach((attachment) => {
|
|
6687
|
+
if (attachment.contentType === "image/png") {
|
|
6688
|
+
let screenshotPath = "";
|
|
6689
|
+
if (attachment.path) {
|
|
6690
|
+
try {
|
|
6691
|
+
const screenshotContent = fs.readFileSync(
|
|
6692
|
+
attachment.path,
|
|
6693
|
+
base64Image ? "base64" : void 0
|
|
6694
|
+
);
|
|
6695
|
+
screenshotPath = base64Image ? `data:image/png;base64,${screenshotContent}` : path2.resolve(attachment.path);
|
|
6696
|
+
} catch (error) {
|
|
6697
|
+
console.error(
|
|
6698
|
+
`OrtoniReport: Failed to read screenshot file: ${attachment.path}`,
|
|
6699
|
+
error
|
|
6700
|
+
);
|
|
6701
|
+
}
|
|
6702
|
+
} else if (attachment.body) {
|
|
6703
|
+
screenshotPath = `data:image/png;base64,${attachment.body.toString("base64")}`;
|
|
6704
|
+
}
|
|
6705
|
+
if (screenshotPath) {
|
|
6706
|
+
testResult.screenshots?.push(screenshotPath);
|
|
6707
|
+
}
|
|
6697
6708
|
}
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
);
|
|
6702
|
-
if (tracePath?.path) {
|
|
6703
|
-
testResult.tracePath = path2.resolve(__dirname, tracePath.path);
|
|
6704
|
-
}
|
|
6705
|
-
const videoPath = result.attachments.find(
|
|
6706
|
-
(attachment) => attachment.name === "video"
|
|
6707
|
-
);
|
|
6708
|
-
if (videoPath?.path) {
|
|
6709
|
-
testResult.videoPath = path2.resolve(__dirname, videoPath.path);
|
|
6710
|
-
}
|
|
6709
|
+
if (attachment.name === "video" && attachment.path) {
|
|
6710
|
+
testResult.videoPath = path2.resolve(__dirname, attachment.path);
|
|
6711
|
+
}
|
|
6712
|
+
});
|
|
6711
6713
|
}
|
|
6712
6714
|
}
|
|
6713
6715
|
onEnd(result) {
|
|
@@ -6723,17 +6725,36 @@ var OrtoniReport = class {
|
|
|
6723
6725
|
"eq",
|
|
6724
6726
|
(actualStatus, expectedStatus) => actualStatus === expectedStatus
|
|
6725
6727
|
);
|
|
6728
|
+
import_handlebars.default.registerHelper("gr", (count) => count > 0);
|
|
6729
|
+
const cssContent = fs.readFileSync(
|
|
6730
|
+
path2.resolve(__dirname, "style", "main.css"),
|
|
6731
|
+
"utf-8"
|
|
6732
|
+
);
|
|
6733
|
+
this.registerPartial("navbar");
|
|
6734
|
+
this.registerPartial("testStatus");
|
|
6735
|
+
this.registerPartial("testPanel");
|
|
6736
|
+
this.registerPartial("summaryCard");
|
|
6737
|
+
this.registerPartial("userInfo");
|
|
6726
6738
|
const outputFilename = ensureHtmlExtension(
|
|
6727
6739
|
this.config.filename || "ortoni-report.html"
|
|
6728
6740
|
);
|
|
6729
|
-
|
|
6730
|
-
|
|
6741
|
+
if (!fs.existsSync(this.folderPath)) {
|
|
6742
|
+
fs.mkdirSync(this.folderPath, { recursive: true });
|
|
6743
|
+
}
|
|
6744
|
+
const html = this.generateHTML(filteredResults, totalDuration, cssContent);
|
|
6745
|
+
const outputPath = path2.join(process.cwd(), this.folderPath, outputFilename);
|
|
6731
6746
|
fs.writeFileSync(outputPath, html);
|
|
6732
6747
|
console.log(`Ortoni HTML report generated at ${outputPath}`);
|
|
6733
6748
|
} catch (error) {
|
|
6734
6749
|
console.error("OrtoniReport: Error generating report:", error);
|
|
6735
6750
|
}
|
|
6736
6751
|
}
|
|
6752
|
+
registerPartial(name) {
|
|
6753
|
+
import_handlebars.default.registerPartial(name, fs.readFileSync(
|
|
6754
|
+
path2.resolve(__dirname, "views", name + ".hbs"),
|
|
6755
|
+
"utf-8"
|
|
6756
|
+
));
|
|
6757
|
+
}
|
|
6737
6758
|
groupResults() {
|
|
6738
6759
|
if (this.config.showProject) {
|
|
6739
6760
|
this.groupedResults = this.results.reduce((acc, result, index) => {
|
|
@@ -6754,7 +6775,7 @@ var OrtoniReport = class {
|
|
|
6754
6775
|
}, {});
|
|
6755
6776
|
}
|
|
6756
6777
|
}
|
|
6757
|
-
generateHTML(filteredResults, totalDuration) {
|
|
6778
|
+
generateHTML(filteredResults, totalDuration, cssContent) {
|
|
6758
6779
|
try {
|
|
6759
6780
|
const totalTests = filteredResults.length;
|
|
6760
6781
|
const passedTests = this.results.filter(
|
|
@@ -6766,14 +6787,13 @@ var OrtoniReport = class {
|
|
|
6766
6787
|
).length;
|
|
6767
6788
|
const successRate = ((passedTests + flakyTests) / totalTests * 100).toFixed(2);
|
|
6768
6789
|
const templateSource = fs.readFileSync(
|
|
6769
|
-
path2.resolve(__dirname, "
|
|
6790
|
+
path2.resolve(__dirname, "views", "main.hbs"),
|
|
6770
6791
|
"utf-8"
|
|
6771
6792
|
);
|
|
6772
6793
|
const template = import_handlebars.default.compile(templateSource);
|
|
6773
6794
|
const logo = this.config.logo ? path2.resolve(this.config.logo) : void 0;
|
|
6774
6795
|
const allTags = /* @__PURE__ */ new Set();
|
|
6775
6796
|
this.results.forEach((result) => {
|
|
6776
|
-
result.suiteTags.forEach((tag) => allTags.add(tag));
|
|
6777
6797
|
result.testTags.forEach((tag) => allTags.add(tag));
|
|
6778
6798
|
});
|
|
6779
6799
|
const data = {
|
|
@@ -6799,7 +6819,7 @@ var OrtoniReport = class {
|
|
|
6799
6819
|
showProject: this.config.showProject || false,
|
|
6800
6820
|
title: this.config.title || "Ortoni Playwright Test Report"
|
|
6801
6821
|
};
|
|
6802
|
-
return template(data);
|
|
6822
|
+
return template({ ...data, inlineCss: cssContent });
|
|
6803
6823
|
} catch (error) {
|
|
6804
6824
|
console.error("OrtoniReport: Error generating HTML:", error);
|
|
6805
6825
|
return `<html><body><h1>Report generation failed</h1><pre>${error.stack}</pre></body></html>`;
|