ortoni-report 1.1.8 → 2.0.0

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.
@@ -188,9 +188,6 @@
188
188
  alt="flaky"></span>
189
189
  {{/if}}
190
190
  <span>{{title}}</span>
191
- {{#if retryCount}}
192
- <p>Retry Count: {{retryCount}}</p>
193
- {{/if}}
194
191
  </div>
195
192
  </li>
196
193
  {{/each}}
@@ -316,6 +313,8 @@
316
313
  </section>
317
314
  <script src="node_modules/ortoni-report/dist/utils/chart.js"></script>
318
315
  <script>
316
+
317
+
319
318
  function escapeHtml(unsafe) {
320
319
  return unsafe.replace(/[&<"']/g, function (match) {
321
320
  const escapeMap = {
@@ -508,7 +507,31 @@
508
507
  });
509
508
  return stepsList;
510
509
  }
511
-
510
+ function openModal() {
511
+ let modal = document.querySelector("#testImage");
512
+ modal.classList.add("is-active");
513
+ }
514
+ function openVideo(){
515
+ let modal = document.querySelector("#testVideo");
516
+ modal.classList.add("is-active");
517
+ }
518
+ function closeVideo(){
519
+ let modal = document.querySelector("#testVideo");
520
+ modal.classList.remove("is-active");
521
+ }
522
+ function closeModal() {
523
+ let modal = document.querySelector("#testImage");
524
+ modal.classList.remove("is-active");
525
+ }
526
+ window.openModal = openModal;
527
+ window.openVideo = openVideo;
528
+ window.closeVideo = closeVideo;
529
+ window.closeModal = closeModal;
530
+
531
+ document.addEventListener('keydown', (event) => {
532
+ if (event.key === "Escape") {
533
+ closeModal();
534
+ }});
512
535
 
513
536
  function attachEventListeners() {
514
537
  const testItems = document.querySelectorAll('[data-test-id]');
@@ -647,6 +670,5 @@
647
670
  });
648
671
 
649
672
  </script>
650
- <script src="node_modules/ortoni-report/dist/utils/modal.js"></script>
651
673
  </body>
652
674
  </html>
@@ -3,25 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.formatDate = exports.normalizeFilePath = exports.msToTime = void 0;
6
+ exports.ensureHtmlExtension = exports.safeStringify = exports.formatDate = exports.normalizeFilePath = exports.msToTime = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  function msToTime(duration) {
9
- const milliseconds = Math.floor((duration % 1000));
9
+ const milliseconds = Math.floor(duration % 1000);
10
10
  const seconds = Math.floor((duration / 1000) % 60);
11
11
  const minutes = Math.floor((duration / (1000 * 60)) % 60);
12
12
  const hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
13
13
  let result = '';
14
14
  if (hours > 0) {
15
- result += (hours < 10 ? "0" + hours : hours) + "h:";
15
+ result += `${hours}h:`;
16
16
  }
17
- if (minutes > 0 || hours > 0) { // Include minutes if hours are included
18
- result += (minutes < 10 ? "0" + minutes : minutes) + "m:";
17
+ if (minutes > 0 || hours > 0) {
18
+ result += `${minutes < 10 ? '0' + minutes : minutes}m:`;
19
19
  }
20
- if (seconds > 0 || minutes > 0 || hours > 0) { // Include seconds if minutes or hours are included
21
- result += (seconds < 10 ? "0" + seconds : seconds) + "s";
20
+ if (seconds > 0 || minutes > 0 || hours > 0) {
21
+ result += `${seconds < 10 ? '0' + seconds : seconds}s`;
22
22
  }
23
- if (milliseconds > 0) {
24
- result += ":" + (milliseconds < 100 ? "0" + milliseconds : milliseconds) + "ms";
23
+ if (milliseconds > 0 && !(seconds > 0 || minutes > 0 || hours > 0)) {
24
+ result += `${milliseconds}ms`;
25
+ }
26
+ else if (milliseconds > 0) {
27
+ result += `:${milliseconds < 100 ? '0' + milliseconds : milliseconds}ms`;
25
28
  }
26
29
  return result;
27
30
  }
@@ -42,3 +45,27 @@ function formatDate(date) {
42
45
  }
43
46
  exports.formatDate = formatDate;
44
47
  ;
48
+ function safeStringify(obj, indent = 2) {
49
+ const cache = new Set();
50
+ const json = JSON.stringify(obj, (key, value) => {
51
+ if (typeof value === 'object' && value !== null) {
52
+ if (cache.has(value)) {
53
+ return;
54
+ }
55
+ cache.add(value);
56
+ }
57
+ return value;
58
+ }, indent);
59
+ cache.clear();
60
+ return json;
61
+ }
62
+ exports.safeStringify = safeStringify;
63
+ function ensureHtmlExtension(filename) {
64
+ const ext = path_1.default.extname(filename);
65
+ if (ext && ext.toLowerCase() === '.html') {
66
+ return filename;
67
+ }
68
+ return `${filename}.html`;
69
+ }
70
+ exports.ensureHtmlExtension = ensureHtmlExtension;
71
+ ;
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "ortoni-report",
3
- "version": "1.1.8",
3
+ "version": "2.0.0",
4
4
  "description": "Playwright Report By LetCode with Koushik",
5
+ "bin": {
6
+ "ortoni-report": "./dist/cli/cli.js"
7
+ },
5
8
  "scripts": {
9
+ "buildparcel": "parcel build",
10
+ "tsc": "tsc",
6
11
  "test": "npx playwright test",
7
12
  "build": "tsup",
8
13
  "release": "npm publish",
@@ -31,18 +36,19 @@
31
36
  "url": "https://github.com/ortoniKC/ortoni-report/issues"
32
37
  },
33
38
  "homepage": "https://github.com/ortoniKC/ortoni-report#readme",
34
- "dependencies": {
35
- "colors": "^1.4.0",
36
- "handlebars": "^4.7.8",
37
- "ws": "^8.18.0"
38
- },
39
39
  "devDependencies": {
40
40
  "@playwright/test": "^1.44.1",
41
- "@types/node": "^20.14.2",
41
+ "@types/node": "^22.0.2",
42
+ "colors": "^1.4.0",
43
+ "handlebars": "^4.7.8",
42
44
  "tsup": "^6.5.0",
43
- "typescript": "^4.9.4"
45
+ "typescript": "^4.9.4",
46
+ "commander": "^12.1.0"
47
+ },
48
+ "dependencies": {
49
+ "parcel": "^2.12.0"
44
50
  },
45
51
  "main": "dist/ortoni-report.js",
46
52
  "module": "dist/ortoni-report.mjs",
47
53
  "types": "dist/ortoni-report.d.ts"
48
- }
54
+ }
package/readme.md CHANGED
@@ -1,12 +1,12 @@
1
- ## Playwright Report by Koushik
1
+ # Playwright Report by Koushik
2
2
 
3
- Welcome to OrtoniReport (Playwright report - unofficial), a robust HTML report generator tailored for Playwright tests. This release introduces powerful features to enhance test reporting, making it easier to visualize and manage test results.
3
+ Welcome to Ortoni Report (Playwright report - unofficial), a robust HTML report generator tailored for Playwright tests. Ortoni Report introduces powerful features to enhance test reporting, making it easier to visualize and manage test results.
4
4
 
5
5
  Explore the live demo: [OrtoniReport Demo](https://ortoni.netlify.app/)
6
6
 
7
- ![OrtoniReport](https://github.com/ortoniKC/ortoni-report/assets/58769833/e88f33d4-eb5c-41c7-b90a-f8a283af0058)
7
+ ![alt text](Ortoni-Report.png)
8
8
 
9
- ### Key Features
9
+ ## Key Features
10
10
 
11
11
  1. **Hierarchical Grouping**
12
12
  - Tests are grouped hierarchically by file name, suite, and project, offering a structured view of test execution.
@@ -32,6 +32,7 @@ Explore the live demo: [OrtoniReport Demo](https://ortoni.netlify.app/)
32
32
  7. **Customization and Themes**
33
33
  - Customize project details, author name, test types, and toggle between dark/light themes.
34
34
  - Option to choose between Base64 images or file path for screenshots.
35
+ - User can set the report file name
35
36
 
36
37
  8. **Responsive Design**
37
38
  - Optimized layout that adapts seamlessly to different screen sizes for accessibility.
@@ -39,9 +40,36 @@ Explore the live demo: [OrtoniReport Demo](https://ortoni.netlify.app/)
39
40
  9. **Integration and Configuration**
40
41
  - Easily integrate with Playwright configurations using TypeScript/JavaScript.
41
42
  - Configure reporting preferences within your Playwright setup.
42
-
43
+
43
44
  10. **Add logo to the report**
44
- - Add relative or absolute path of the image to the config
45
+ - Add relative or absolute path of the image to the config.
46
+
47
+ 11. **Share report**
48
+ - Generat the report and zip the folder and share.
49
+
50
+
51
+ ### How to Use ortoni-report
52
+
53
+ ### Installation
54
+
55
+ 1. **Install the ortoni-report package**:
56
+
57
+ ```sh
58
+ npm install -g ortoni-report
59
+ ```
60
+
61
+ ### Generate and Bundle HTML Report
62
+
63
+ 2. **Generate and bundle the report** (Optional):
64
+
65
+ ```sh
66
+ npx ortoni-report gr -f ortoni-report.html
67
+ ```
68
+
69
+ ### Command Overview
70
+
71
+ - `npx ortoni-report gr -f <filename>`: Bundle the specified report file.
72
+ - `-f, --filename <filename>`: Specify the filename for the generated report (default: `ortoni-report.html`).
45
73
 
46
74
  ### Configurable Report Generation
47
75
 
@@ -52,6 +80,7 @@ import { defineConfig } from '@playwright/test';
52
80
  import { OrtoniReportConfig } from 'ortoni-report';
53
81
 
54
82
  const reportConfig: OrtoniReportConfig = {
83
+ filename:"myawesomereport.html",
55
84
  logo: "path/logo.png",
56
85
  authorName: "LetCode Koushik",
57
86
  base64Image: false,
@@ -66,9 +95,19 @@ export default defineConfig({
66
95
  });
67
96
  ```
68
97
 
98
+ ### Common Issue
99
+ ```
100
+ Error: Command failed:
101
+ @parcel/namer-default: Target "main" declares an
102
+ output file path of "index.js" which does not match
103
+ the compiled bundle type "html".
104
+ ```
105
+ Solution:
106
+ Remove "main" in the ```package.json``` file
107
+
69
108
  ### Comprehensive Test Details
70
109
 
71
- - **Rich Test Information:** Each test includes details like title, status, duration, tags, errors, steps, logs, video, and screenshot paths.
110
+ - **Rich Test Information:** Each test includes details like title, status, duration, tags, errors, steps, logs, video, and screenshot.
72
111
  - **Color-coded Status:** Status indicators (green for passed, red for failed, yellow for skipped) for quick identification.
73
112
 
74
113
  ### Handlebars Template Integration
@@ -1,23 +0,0 @@
1
- // Functions to open and close a modal
2
- function openModal() {
3
- let modal = document.querySelector("#testImage");
4
- modal.classList.add("is-active")
5
- }
6
- function openVideo(){
7
- let modal = document.querySelector("#testVideo");;
8
- modal.classList.add("is-active")
9
- }
10
- function closeVideo(){
11
- let modal = document.querySelector("#testVideo");;
12
- modal.classList.remove("is-active")
13
- }
14
- function closeModal() {
15
- let modal = document.querySelector("#testImage");;
16
- modal.classList.remove("is-active")
17
- }
18
- // Add a keyboard event to close all modals
19
- document.addEventListener('keydown', (event) => {
20
- if (event.key === "Escape") {
21
- closeModal();
22
- }
23
- });