ortoni-report 2.0.1 → 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 +54 -0
- package/dist/cli/cli.js +1 -1
- package/dist/ortoni-report.d.ts +20 -3
- package/dist/ortoni-report.js +86 -45
- package/dist/ortoni-report.mjs +86 -45
- package/dist/style/main.css +86 -0
- package/dist/utils/utils.js +0 -2
- package/dist/views/main.hbs +583 -0
- 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 +42 -57
- package/dist/css/main.css +0 -22445
- 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/report-template.hbs +0 -674
- package/dist/utils/chart.js +0 -11128
package/changelog.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
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
|
+
|
|
20
|
+
## Version 2.0.2
|
|
21
|
+
|
|
22
|
+
#### 🚀 New Features
|
|
23
|
+
|
|
24
|
+
- **Show or Hide Projects in Test List**
|
|
25
|
+
- You can now show or hide specific projects in the test list.
|
|
26
|
+
- ```showProject: true``` from config
|
|
27
|
+
|
|
28
|
+
- **Document Title from Config**
|
|
29
|
+
- The document title is now configurable via the configuration file, allowing you to customize it to your preference.
|
|
30
|
+
|
|
31
|
+
- **Display Tags in Test Section**
|
|
32
|
+
- Tags associated with tests are now displayed within the test section, giving you a clearer overview of test categories.
|
|
33
|
+
|
|
34
|
+
- **Project and Tags Added to Filter**
|
|
35
|
+
- We've added the ability to filter tests by both project and tags, enhancing the granularity of your test views.
|
|
36
|
+
|
|
37
|
+
- **Display Selected Status on UI**
|
|
38
|
+
- The selected status filter is now visible on the UI, making it easier to track the current filter settings.
|
|
39
|
+
|
|
40
|
+
#### 🛠 Fixes
|
|
41
|
+
|
|
42
|
+
- **Project Drop-down Z-Index on Screenshot**
|
|
43
|
+
- Resolved an issue where the project drop-down menu was being overlapped by screenshots. The z-index has been adjusted for proper layering.
|
|
44
|
+
|
|
45
|
+
- **Project Filter Hide Test Steps**
|
|
46
|
+
- Fixed a bug where applying the project filter would inadvertently hide test steps. Test steps are now correctly displayed based on the filter.
|
|
47
|
+
|
|
48
|
+
#### ✨ Improvements
|
|
49
|
+
|
|
50
|
+
- **Hide Skipped Tests on All Tests Filter**
|
|
51
|
+
- Skipped tests are now hidden by default when using the "All Tests" filter, providing a cleaner and more focused view of relevant tests.
|
|
52
|
+
|
|
53
|
+
- **Colorful Dashboard**
|
|
54
|
+
- We've enhanced the visual appeal of the dashboard with more vibrant and intuitive colors, making it easier to navigate and interpret results.
|
|
55
|
+
|
|
56
|
+
|
|
3
57
|
## Version 2.0.1
|
|
4
58
|
- Fixed local and root path issue of Parcel bundler.
|
|
5
59
|
- Local config issue
|
package/dist/cli/cli.js
CHANGED
package/dist/ortoni-report.d.ts
CHANGED
|
@@ -4,6 +4,16 @@ import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@
|
|
|
4
4
|
* Configuration options for OrtoniReport.
|
|
5
5
|
*/
|
|
6
6
|
interface OrtoniReportConfig {
|
|
7
|
+
/**
|
|
8
|
+
* The title of the HTML report.
|
|
9
|
+
* @example "Ortoni Playwright Test Report"
|
|
10
|
+
*/
|
|
11
|
+
title?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Add project on the list of the tests? (Filtering projects still works if hidden)
|
|
14
|
+
* @example true to display, false to hide.
|
|
15
|
+
*/
|
|
16
|
+
showProject?: boolean;
|
|
7
17
|
/**
|
|
8
18
|
* The name of the project.
|
|
9
19
|
* @example "Ortoni Project"
|
|
@@ -43,6 +53,11 @@ interface OrtoniReportConfig {
|
|
|
43
53
|
* @example "index.html"
|
|
44
54
|
*/
|
|
45
55
|
filename?: string;
|
|
56
|
+
/**
|
|
57
|
+
* The folder name.
|
|
58
|
+
* @example "playwright-report"
|
|
59
|
+
*/
|
|
60
|
+
folderPath?: string;
|
|
46
61
|
}
|
|
47
62
|
|
|
48
63
|
interface Steps {
|
|
@@ -66,8 +81,9 @@ interface TestResultData {
|
|
|
66
81
|
steps: Steps[];
|
|
67
82
|
logs: string;
|
|
68
83
|
screenshotPath?: string | null | undefined;
|
|
84
|
+
screenshots?: string[];
|
|
69
85
|
filePath: string;
|
|
70
|
-
|
|
86
|
+
filters: Set<string>;
|
|
71
87
|
tracePath?: string;
|
|
72
88
|
videoPath?: string;
|
|
73
89
|
base64Image: boolean | undefined;
|
|
@@ -80,15 +96,16 @@ declare class OrtoniReport implements Reporter {
|
|
|
80
96
|
private suiteName;
|
|
81
97
|
private config;
|
|
82
98
|
private projectSet;
|
|
83
|
-
private
|
|
99
|
+
private folderPath;
|
|
84
100
|
constructor(config?: OrtoniReportConfig);
|
|
85
101
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
86
102
|
onTestBegin(test: TestCase, result: TestResult): void;
|
|
87
103
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
88
104
|
private attachFiles;
|
|
89
105
|
onEnd(result: FullResult): void;
|
|
106
|
+
private registerPartial;
|
|
90
107
|
private groupResults;
|
|
91
|
-
generateHTML(filteredResults: TestResultData[], totalDuration: string): string;
|
|
108
|
+
generateHTML(filteredResults: TestResultData[], totalDuration: string, cssContent: string): string;
|
|
92
109
|
}
|
|
93
110
|
|
|
94
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
|
}
|
|
@@ -6671,7 +6674,7 @@ var OrtoniReport = class {
|
|
|
6671
6674
|
result.stdout.concat(result.stderr).map((log) => log).join("\n")
|
|
6672
6675
|
),
|
|
6673
6676
|
filePath,
|
|
6674
|
-
|
|
6677
|
+
filters: this.projectSet,
|
|
6675
6678
|
base64Image: this.config.base64Image
|
|
6676
6679
|
};
|
|
6677
6680
|
this.attachFiles(result, testResult);
|
|
@@ -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) {
|
|
@@ -6721,31 +6723,63 @@ var OrtoniReport = class {
|
|
|
6721
6723
|
);
|
|
6722
6724
|
const totalDuration = msToTime(result.duration);
|
|
6723
6725
|
this.groupResults();
|
|
6726
|
+
import_handlebars.default.registerHelper("joinWithSpace", (array) => array.join(" "));
|
|
6724
6727
|
import_handlebars.default.registerHelper("json", (context) => safeStringify(context));
|
|
6725
6728
|
import_handlebars.default.registerHelper(
|
|
6726
6729
|
"eq",
|
|
6727
6730
|
(actualStatus, expectedStatus) => actualStatus === expectedStatus
|
|
6728
6731
|
);
|
|
6729
|
-
|
|
6730
|
-
const
|
|
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");
|
|
6742
|
+
const outputFilename = ensureHtmlExtension(
|
|
6743
|
+
this.config.filename || "ortoni-report.html"
|
|
6744
|
+
);
|
|
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);
|
|
6732
6750
|
import_fs.default.writeFileSync(outputPath, html);
|
|
6733
6751
|
console.log(`Ortoni HTML report generated at ${outputPath}`);
|
|
6734
6752
|
} catch (error) {
|
|
6735
6753
|
console.error("OrtoniReport: Error generating report:", error);
|
|
6736
6754
|
}
|
|
6737
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
|
+
}
|
|
6738
6762
|
groupResults() {
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6763
|
+
if (this.config.showProject) {
|
|
6764
|
+
this.groupedResults = this.results.reduce((acc, result, index) => {
|
|
6765
|
+
const { filePath, suite, projectName } = result;
|
|
6766
|
+
acc[filePath] = acc[filePath] || {};
|
|
6767
|
+
acc[filePath][suite] = acc[filePath][suite] || {};
|
|
6768
|
+
acc[filePath][suite][projectName] = acc[filePath][suite][projectName] || [];
|
|
6769
|
+
acc[filePath][suite][projectName].push({ ...result, index });
|
|
6770
|
+
return acc;
|
|
6771
|
+
}, {});
|
|
6772
|
+
} else {
|
|
6773
|
+
this.groupedResults = this.results.reduce((acc, result, index) => {
|
|
6774
|
+
const { filePath, suite } = result;
|
|
6775
|
+
acc[filePath] = acc[filePath] || {};
|
|
6776
|
+
acc[filePath][suite] = acc[filePath][suite] || [];
|
|
6777
|
+
acc[filePath][suite].push({ ...result, index });
|
|
6778
|
+
return acc;
|
|
6779
|
+
}, {});
|
|
6780
|
+
}
|
|
6747
6781
|
}
|
|
6748
|
-
generateHTML(filteredResults, totalDuration) {
|
|
6782
|
+
generateHTML(filteredResults, totalDuration, cssContent) {
|
|
6749
6783
|
try {
|
|
6750
6784
|
const totalTests = filteredResults.length;
|
|
6751
6785
|
const passedTests = this.results.filter(
|
|
@@ -6757,11 +6791,15 @@ var OrtoniReport = class {
|
|
|
6757
6791
|
).length;
|
|
6758
6792
|
const successRate = ((passedTests + flakyTests) / totalTests * 100).toFixed(2);
|
|
6759
6793
|
const templateSource = import_fs.default.readFileSync(
|
|
6760
|
-
import_path2.default.resolve(__dirname, "
|
|
6794
|
+
import_path2.default.resolve(__dirname, "views", "main.hbs"),
|
|
6761
6795
|
"utf-8"
|
|
6762
6796
|
);
|
|
6763
6797
|
const template = import_handlebars.default.compile(templateSource);
|
|
6764
6798
|
const logo = this.config.logo ? import_path2.default.resolve(this.config.logo) : void 0;
|
|
6799
|
+
const allTags = /* @__PURE__ */ new Set();
|
|
6800
|
+
this.results.forEach((result) => {
|
|
6801
|
+
result.testTags.forEach((tag) => allTags.add(tag));
|
|
6802
|
+
});
|
|
6765
6803
|
const data = {
|
|
6766
6804
|
logo,
|
|
6767
6805
|
totalDuration,
|
|
@@ -6780,9 +6818,12 @@ var OrtoniReport = class {
|
|
|
6780
6818
|
preferredTheme: this.config.preferredTheme,
|
|
6781
6819
|
successRate,
|
|
6782
6820
|
lastRunDate: formatDate(/* @__PURE__ */ new Date()),
|
|
6783
|
-
projects: this.projectSet
|
|
6821
|
+
projects: this.projectSet,
|
|
6822
|
+
allTags: Array.from(allTags),
|
|
6823
|
+
showProject: this.config.showProject || false,
|
|
6824
|
+
title: this.config.title || "Ortoni Playwright Test Report"
|
|
6784
6825
|
};
|
|
6785
|
-
return template(data);
|
|
6826
|
+
return template({ ...data, inlineCss: cssContent });
|
|
6786
6827
|
} catch (error) {
|
|
6787
6828
|
console.error("OrtoniReport: Error generating HTML:", error);
|
|
6788
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
|
}
|
|
@@ -6667,7 +6670,7 @@ var OrtoniReport = class {
|
|
|
6667
6670
|
result.stdout.concat(result.stderr).map((log) => log).join("\n")
|
|
6668
6671
|
),
|
|
6669
6672
|
filePath,
|
|
6670
|
-
|
|
6673
|
+
filters: this.projectSet,
|
|
6671
6674
|
base64Image: this.config.base64Image
|
|
6672
6675
|
};
|
|
6673
6676
|
this.attachFiles(result, testResult);
|
|
@@ -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) {
|
|
@@ -6717,31 +6719,63 @@ var OrtoniReport = class {
|
|
|
6717
6719
|
);
|
|
6718
6720
|
const totalDuration = msToTime(result.duration);
|
|
6719
6721
|
this.groupResults();
|
|
6722
|
+
import_handlebars.default.registerHelper("joinWithSpace", (array) => array.join(" "));
|
|
6720
6723
|
import_handlebars.default.registerHelper("json", (context) => safeStringify(context));
|
|
6721
6724
|
import_handlebars.default.registerHelper(
|
|
6722
6725
|
"eq",
|
|
6723
6726
|
(actualStatus, expectedStatus) => actualStatus === expectedStatus
|
|
6724
6727
|
);
|
|
6725
|
-
|
|
6726
|
-
const
|
|
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");
|
|
6738
|
+
const outputFilename = ensureHtmlExtension(
|
|
6739
|
+
this.config.filename || "ortoni-report.html"
|
|
6740
|
+
);
|
|
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);
|
|
6728
6746
|
fs.writeFileSync(outputPath, html);
|
|
6729
6747
|
console.log(`Ortoni HTML report generated at ${outputPath}`);
|
|
6730
6748
|
} catch (error) {
|
|
6731
6749
|
console.error("OrtoniReport: Error generating report:", error);
|
|
6732
6750
|
}
|
|
6733
6751
|
}
|
|
6752
|
+
registerPartial(name) {
|
|
6753
|
+
import_handlebars.default.registerPartial(name, fs.readFileSync(
|
|
6754
|
+
path2.resolve(__dirname, "views", name + ".hbs"),
|
|
6755
|
+
"utf-8"
|
|
6756
|
+
));
|
|
6757
|
+
}
|
|
6734
6758
|
groupResults() {
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6759
|
+
if (this.config.showProject) {
|
|
6760
|
+
this.groupedResults = this.results.reduce((acc, result, index) => {
|
|
6761
|
+
const { filePath, suite, projectName } = result;
|
|
6762
|
+
acc[filePath] = acc[filePath] || {};
|
|
6763
|
+
acc[filePath][suite] = acc[filePath][suite] || {};
|
|
6764
|
+
acc[filePath][suite][projectName] = acc[filePath][suite][projectName] || [];
|
|
6765
|
+
acc[filePath][suite][projectName].push({ ...result, index });
|
|
6766
|
+
return acc;
|
|
6767
|
+
}, {});
|
|
6768
|
+
} else {
|
|
6769
|
+
this.groupedResults = this.results.reduce((acc, result, index) => {
|
|
6770
|
+
const { filePath, suite } = result;
|
|
6771
|
+
acc[filePath] = acc[filePath] || {};
|
|
6772
|
+
acc[filePath][suite] = acc[filePath][suite] || [];
|
|
6773
|
+
acc[filePath][suite].push({ ...result, index });
|
|
6774
|
+
return acc;
|
|
6775
|
+
}, {});
|
|
6776
|
+
}
|
|
6743
6777
|
}
|
|
6744
|
-
generateHTML(filteredResults, totalDuration) {
|
|
6778
|
+
generateHTML(filteredResults, totalDuration, cssContent) {
|
|
6745
6779
|
try {
|
|
6746
6780
|
const totalTests = filteredResults.length;
|
|
6747
6781
|
const passedTests = this.results.filter(
|
|
@@ -6753,11 +6787,15 @@ var OrtoniReport = class {
|
|
|
6753
6787
|
).length;
|
|
6754
6788
|
const successRate = ((passedTests + flakyTests) / totalTests * 100).toFixed(2);
|
|
6755
6789
|
const templateSource = fs.readFileSync(
|
|
6756
|
-
path2.resolve(__dirname, "
|
|
6790
|
+
path2.resolve(__dirname, "views", "main.hbs"),
|
|
6757
6791
|
"utf-8"
|
|
6758
6792
|
);
|
|
6759
6793
|
const template = import_handlebars.default.compile(templateSource);
|
|
6760
6794
|
const logo = this.config.logo ? path2.resolve(this.config.logo) : void 0;
|
|
6795
|
+
const allTags = /* @__PURE__ */ new Set();
|
|
6796
|
+
this.results.forEach((result) => {
|
|
6797
|
+
result.testTags.forEach((tag) => allTags.add(tag));
|
|
6798
|
+
});
|
|
6761
6799
|
const data = {
|
|
6762
6800
|
logo,
|
|
6763
6801
|
totalDuration,
|
|
@@ -6776,9 +6814,12 @@ var OrtoniReport = class {
|
|
|
6776
6814
|
preferredTheme: this.config.preferredTheme,
|
|
6777
6815
|
successRate,
|
|
6778
6816
|
lastRunDate: formatDate(/* @__PURE__ */ new Date()),
|
|
6779
|
-
projects: this.projectSet
|
|
6817
|
+
projects: this.projectSet,
|
|
6818
|
+
allTags: Array.from(allTags),
|
|
6819
|
+
showProject: this.config.showProject || false,
|
|
6820
|
+
title: this.config.title || "Ortoni Playwright Test Report"
|
|
6780
6821
|
};
|
|
6781
|
-
return template(data);
|
|
6822
|
+
return template({ ...data, inlineCss: cssContent });
|
|
6782
6823
|
} catch (error) {
|
|
6783
6824
|
console.error("OrtoniReport: Error generating HTML:", error);
|
|
6784
6825
|
return `<html><body><h1>Report generation failed</h1><pre>${error.stack}</pre></body></html>`;
|