@testream/playwright-reporter 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,31 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2025 Jira Test Manager Team. All rights reserved.
4
+
5
+ This software and associated documentation files (the "Software") are licensed,
6
+ not sold, to you for use only under the terms of this license.
7
+
8
+ GRANT OF LICENSE:
9
+ You are granted a non-exclusive, non-transferable license to use the Software
10
+ solely for the purpose of integrating test result reporting with the Jira Test
11
+ Manager service.
12
+
13
+ RESTRICTIONS:
14
+ - You may not modify, adapt, or create derivative works of the Software
15
+ - You may not distribute, sublicense, lease, or rent the Software
16
+ - You may not reverse engineer, decompile, or disassemble the Software
17
+ - The Software may only be used in conjunction with the Jira Test Manager service
18
+
19
+ OWNERSHIP:
20
+ The Software is licensed, not sold. This license does not grant you any rights
21
+ to trademarks or service marks.
22
+
23
+ TERMINATION:
24
+ This license is effective until terminated. Your rights under this license will
25
+ terminate automatically without notice if you fail to comply with any term of
26
+ this license.
27
+
28
+ DISCLAIMER:
29
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
package/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # @testream/playwright-reporter
2
+
3
+ Playwright reporter that generates [CTRF](https://ctrf.io/) (Common Test Report Format) test reports and automatically uploads them with artifacts to your Jira Test Manager backend.
4
+
5
+ ## Features
6
+
7
+ - 🎭 **Playwright Integration** - Works seamlessly with Playwright Test
8
+ - 📊 **CTRF Format** - Generates standardized JSON test reports using `playwright-ctrf-json-reporter`
9
+ - ☁️ **Automatic Upload** - Uploads test results and artifacts to your backend API
10
+ - 📎 **Artifact Support** - Automatically uploads screenshots, videos, and traces
11
+ - 🔄 **CI/CD Ready** - Auto-detects git context from GitHub Actions, GitLab CI, CircleCI, Jenkins
12
+ - ⚙️ **Configurable** - Full control over report generation and upload behavior
13
+ - 🛡️ **Error Handling** - Graceful failure modes with optional strict mode
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install --save-dev @testream/playwright-reporter
19
+ ```
20
+
21
+ ## Configuration
22
+
23
+ Add the reporter to your `playwright.config.ts`:
24
+
25
+ ```typescript
26
+ import { defineConfig } from '@playwright/test';
27
+
28
+ export default defineConfig({
29
+ reporter: [
30
+ ['list'], // Keep the default list reporter
31
+ [
32
+ '@testream/playwright-reporter',
33
+ {
34
+ // Required: Backend API configuration
35
+ apiUrl: 'https://your-backend.fly.dev',
36
+ apiKey: process.env.TEST_MANAGER_API_KEY,
37
+ projectKey: 'PROJECT-1',
38
+
39
+ // Optional: Git context (auto-detected in CI environments)
40
+ branch: process.env.BRANCH_NAME,
41
+ commitSha: process.env.COMMIT_SHA,
42
+
43
+ // Optional: Upload behavior
44
+ uploadEnabled: true,
45
+ failOnUploadError: false,
46
+
47
+ // Optional: CTRF report options
48
+ outputFile: 'ctrf-report.json',
49
+ outputDir: 'ctrf',
50
+ screenshot: true,
51
+ annotations: false,
52
+ testType: 'e2e',
53
+
54
+ // Optional: Environment metadata
55
+ appName: 'My App',
56
+ appVersion: '1.0.0',
57
+ buildName: 'Build #123',
58
+ buildNumber: '123',
59
+ buildUrl: 'https://ci.example.com/build/123',
60
+ testEnvironment: 'staging',
61
+ },
62
+ ],
63
+ ],
64
+ // ... other config
65
+ });
66
+ ```
67
+
68
+ ## Configuration Options
69
+
70
+ ### Required Options
71
+
72
+ | Option | Type | Description |
73
+ |--------|------|-------------|
74
+ | `apiUrl` | `string` | Backend API URL (e.g., `https://test-manager-backend.fly.dev`) |
75
+ | `apiKey` | `string` | API key for authentication (store in environment variables) |
76
+ | `projectKey` | `string` | Project key to associate test results with |
77
+
78
+ ### Optional Options
79
+
80
+ | Option | Type | Default | Description |
81
+ |--------|------|---------|-------------|
82
+ | `uploadEnabled` | `boolean` | `true` | Enable/disable automatic upload to backend |
83
+ | `failOnUploadError` | `boolean` | `false` | Fail the test run if upload fails |
84
+ | `branch` | `string` | Auto-detected | Git branch name |
85
+ | `commitSha` | `string` | Auto-detected | Git commit SHA |
86
+ | `outputFile` | `string` | `'ctrf-report.json'` | Local CTRF report filename |
87
+ | `outputDir` | `string` | `'ctrf'` | Local CTRF report directory |
88
+ | `screenshot` | `boolean` | `true` | Include screenshots in the report |
89
+ | `annotations` | `boolean` | `false` | Include Playwright annotations |
90
+ | `testType` | `string` | `'e2e'` | Test type (e.g., 'api', 'e2e', 'unit') |
91
+ | `appName` | `string` | - | Application name under test |
92
+ | `appVersion` | `string` | - | Application version under test |
93
+ | `buildName` | `string` | - | Build name |
94
+ | `buildNumber` | `string` | - | Build number |
95
+ | `buildUrl` | `string` | - | Build URL |
96
+ | `testEnvironment` | `string` | - | Test environment (e.g., 'staging', 'production') |
97
+
98
+ ## Usage
99
+
100
+ ### Basic Usage
101
+
102
+ Once configured, the reporter automatically:
103
+ 1. Generates a CTRF report during test execution
104
+ 2. Uploads the report to your backend after tests complete
105
+ 3. Uploads any test artifacts (screenshots, videos, traces)
106
+
107
+ ```bash
108
+ npx playwright test
109
+ ```
110
+
111
+ ### Capturing Screenshots
112
+
113
+ To include screenshots in your reports, attach them in your tests:
114
+
115
+ ```typescript
116
+ import { test, expect } from '@playwright/test';
117
+
118
+ test('example test', async ({ page }, testInfo) => {
119
+ await page.goto('https://playwright.dev');
120
+
121
+ // Capture screenshot
122
+ const screenshot = await page.screenshot({
123
+ quality: 50,
124
+ type: 'jpeg'
125
+ });
126
+
127
+ await testInfo.attach('screenshot', {
128
+ body: screenshot,
129
+ contentType: 'image/jpeg',
130
+ });
131
+ });
132
+ ```
133
+
134
+ ### Disable Upload for Local Development
135
+
136
+ ```typescript
137
+ // playwright.config.ts
138
+ export default defineConfig({
139
+ reporter: [
140
+ [
141
+ '@testream/playwright-reporter',
142
+ {
143
+ apiUrl: 'https://your-backend.fly.dev',
144
+ apiKey: process.env.TEST_MANAGER_API_KEY,
145
+ projectKey: 'PROJECT-1',
146
+ uploadEnabled: process.env.CI === 'true', // Only upload in CI
147
+ },
148
+ ],
149
+ ],
150
+ });
151
+ ```
152
+
153
+ ### Environment Variables
154
+
155
+ It's recommended to store sensitive configuration in environment variables:
156
+
157
+ ```bash
158
+ # .env
159
+ TEST_MANAGER_API_KEY=your-api-key-here
160
+ TEST_MANAGER_API_URL=https://your-backend.fly.dev
161
+ TEST_MANAGER_PROJECT_KEY=PROJECT-1
162
+ ```
163
+
164
+ Then load them in your config:
165
+
166
+ ```typescript
167
+ import { defineConfig } from '@playwright/test';
168
+ import * as dotenv from 'dotenv';
169
+
170
+ dotenv.config();
171
+
172
+ export default defineConfig({
173
+ reporter: [
174
+ [
175
+ '@testream/playwright-reporter',
176
+ {
177
+ apiUrl: process.env.TEST_MANAGER_API_URL,
178
+ apiKey: process.env.TEST_MANAGER_API_KEY,
179
+ projectKey: process.env.TEST_MANAGER_PROJECT_KEY,
180
+ },
181
+ ],
182
+ ],
183
+ });
184
+ ```
185
+
186
+ ## CI/CD Integration
187
+
188
+ ### GitHub Actions
189
+
190
+ The reporter automatically detects GitHub Actions environment variables:
191
+
192
+ ```yaml
193
+ name: Playwright Tests
194
+ on: [push, pull_request]
195
+
196
+ jobs:
197
+ test:
198
+ runs-on: ubuntu-latest
199
+ steps:
200
+ - uses: actions/checkout@v4
201
+
202
+ - name: Setup Node.js
203
+ uses: actions/setup-node@v4
204
+ with:
205
+ node-version: '20'
206
+
207
+ - name: Install dependencies
208
+ run: npm ci
209
+
210
+ - name: Install Playwright Browsers
211
+ run: npx playwright install --with-deps
212
+
213
+ - name: Run tests
214
+ run: npx playwright test
215
+ env:
216
+ TEST_MANAGER_API_KEY: ${{ secrets.TEST_MANAGER_API_KEY }}
217
+ TEST_MANAGER_API_URL: ${{ secrets.TEST_MANAGER_API_URL }}
218
+ TEST_MANAGER_PROJECT_KEY: 'PROJECT-1'
219
+ ```
220
+
221
+ ### GitLab CI
222
+
223
+ ```yaml
224
+ test:
225
+ image: mcr.microsoft.com/playwright:latest
226
+ script:
227
+ - npm ci
228
+ - npx playwright test
229
+ variables:
230
+ TEST_MANAGER_API_KEY: $TEST_MANAGER_API_KEY
231
+ TEST_MANAGER_API_URL: $TEST_MANAGER_API_URL
232
+ TEST_MANAGER_PROJECT_KEY: "PROJECT-1"
233
+ ```
234
+
235
+ ### CircleCI
236
+
237
+ ```yaml
238
+ version: 2.1
239
+ jobs:
240
+ test:
241
+ docker:
242
+ - image: mcr.microsoft.com/playwright:latest
243
+ steps:
244
+ - checkout
245
+ - run: npm ci
246
+ - run: npx playwright test
247
+ environment:
248
+ TEST_MANAGER_API_KEY: $TEST_MANAGER_API_KEY
249
+ TEST_MANAGER_API_URL: $TEST_MANAGER_API_URL
250
+ TEST_MANAGER_PROJECT_KEY: "PROJECT-1"
251
+ ```
252
+
253
+ ## Troubleshooting
254
+
255
+ ### Upload Failures
256
+
257
+ If uploads fail, the reporter logs detailed error messages but doesn't fail your tests by default:
258
+
259
+ ```
260
+ ❌ Failed to upload report: API ingest failed: HTTP 401: Unauthorized
261
+ ```
262
+
263
+ To make upload failures fail the test run:
264
+
265
+ ```typescript
266
+ {
267
+ failOnUploadError: true
268
+ }
269
+ ```
270
+
271
+ ### Missing Artifacts
272
+
273
+ Ensure artifacts are properly attached in tests and that file paths are accessible when the reporter runs.
274
+
275
+ ### Git Context Not Detected
276
+
277
+ Manually specify branch and commit in configuration:
278
+
279
+ ```typescript
280
+ {
281
+ branch: process.env.GIT_BRANCH || 'main',
282
+ commitSha: process.env.GIT_COMMIT || 'unknown',
283
+ }
284
+ ```
285
+
286
+ ## How It Works
287
+
288
+ 1. **Test Execution**: Playwright runs your tests
289
+ 2. **CTRF Generation**: `playwright-ctrf-json-reporter` generates a CTRF-format JSON report
290
+ 3. **Report Upload**: Report is POSTed to `/api/v1/ingest` endpoint
291
+ 4. **Artifact Upload**: Each test attachment is uploaded to `/api/v1/artifacts/:reportId`
292
+ 5. **Linking**: Artifacts are linked to test results via test names
293
+
294
+ ## Related Packages
295
+
296
+ - [playwright-ctrf-json-reporter](https://www.npmjs.com/package/playwright-ctrf-json-reporter) - Underlying CTRF reporter
297
+ - [@testream/upload-action](https://www.npmjs.com/package/@testream/upload-action) - CLI and GitHub Action for uploading CTRF reports
298
+
299
+ ## License
300
+
301
+ Proprietary - See LICENSE file
302
+
303
+ ## Support
304
+
305
+ For issues and questions, contact your Jira Test Manager administrator.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @jira-test-manager/playwright-reporter
3
+ *
4
+ * Playwright reporter that generates CTRF-format test reports and
5
+ * automatically uploads them with artifacts to the Test Manager backend.
6
+ */
7
+ export { PlaywrightCTRFReporterWithUpload as default } from './reporter';
8
+ export { PlaywrightCTRFReporterWithUpload } from './reporter';
9
+ export type { PlaywrightCTRFReporterConfig } from './types';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gCAAgC,IAAI,OAAO,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAC;AAC9D,YAAY,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * @jira-test-manager/playwright-reporter
4
+ *
5
+ * Playwright reporter that generates CTRF-format test reports and
6
+ * automatically uploads them with artifacts to the Test Manager backend.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PlaywrightCTRFReporterWithUpload = exports.default = void 0;
10
+ var reporter_1 = require("./reporter");
11
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return reporter_1.PlaywrightCTRFReporterWithUpload; } });
12
+ var reporter_2 = require("./reporter");
13
+ Object.defineProperty(exports, "PlaywrightCTRFReporterWithUpload", { enumerable: true, get: function () { return reporter_2.PlaywrightCTRFReporterWithUpload; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,uCAAyE;AAAhE,mGAAA,gCAAgC,OAAW;AACpD,uCAA8D;AAArD,4HAAA,gCAAgC,OAAA"}
@@ -0,0 +1,42 @@
1
+ import type { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
2
+ import { PlaywrightCTRFReporterConfig } from './types';
3
+ /**
4
+ * Playwright Reporter that generates CTRF reports and uploads them to a backend API
5
+ */
6
+ export declare class PlaywrightCTRFReporterWithUpload implements Reporter {
7
+ private config;
8
+ private ctrfReporter;
9
+ private uploader;
10
+ private reportPath;
11
+ constructor(config: PlaywrightCTRFReporterConfig);
12
+ /**
13
+ * Called once before running tests
14
+ */
15
+ onBegin(config: FullConfig, suite: Suite): void;
16
+ /**
17
+ * Called after a test has been started
18
+ */
19
+ onTestBegin?(test: TestCase, result: TestResult): void;
20
+ /**
21
+ * Called after a test has been finished
22
+ */
23
+ onTestEnd?(test: TestCase, result: TestResult): void;
24
+ /**
25
+ * Called on some global error
26
+ */
27
+ onError?(error: Error): void;
28
+ /**
29
+ * Called after a step has been started
30
+ */
31
+ onStepBegin?(test: TestCase, result: TestResult, step: any): void;
32
+ /**
33
+ * Called after a step has been finished
34
+ */
35
+ onStepEnd?(test: TestCase, result: TestResult, step: any): void;
36
+ /**
37
+ * Called after all tests have been run
38
+ */
39
+ onEnd(result: FullResult): Promise<void>;
40
+ }
41
+ export default PlaywrightCTRFReporterWithUpload;
42
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,KAAK,EACL,QAAQ,EACR,UAAU,EACV,UAAU,EACX,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,4BAA4B,EAAc,MAAM,SAAS,CAAC;AAMnE;;GAEG;AACH,qBAAa,gCAAiC,YAAW,QAAQ;IAC/D,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,4BAA4B;IA4DhD;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAqB/C;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAMtD;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAMpD;;OAEG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAM5B;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAMjE;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAM/D;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CA6D/C;AAED,eAAe,gCAAgC,CAAC"}
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.PlaywrightCTRFReporterWithUpload = void 0;
40
+ const fs = __importStar(require("fs/promises"));
41
+ const path = __importStar(require("path"));
42
+ const uploader_1 = require("./uploader");
43
+ // Import the underlying CTRF reporter
44
+ const playwright_ctrf_json_reporter_1 = __importDefault(require("playwright-ctrf-json-reporter"));
45
+ /**
46
+ * Playwright Reporter that generates CTRF reports and uploads them to a backend API
47
+ */
48
+ class PlaywrightCTRFReporterWithUpload {
49
+ constructor(config) {
50
+ this.uploader = null;
51
+ // Validate required configuration (apiUrl is now internal)
52
+ if (!config.apiKey) {
53
+ throw new Error('PlaywrightCTRFReporter: apiKey is required');
54
+ }
55
+ if (!config.projectKey) {
56
+ throw new Error('PlaywrightCTRFReporter: projectKey is required');
57
+ }
58
+ // Set defaults and inject internalApiUrl
59
+ this.config = {
60
+ uploadEnabled: true,
61
+ outputFile: 'ctrf-report.json',
62
+ outputDir: 'ctrf',
63
+ failOnUploadError: false,
64
+ screenshot: true,
65
+ annotations: false,
66
+ testType: 'e2e',
67
+ ...config
68
+ };
69
+ // Auto-detect git context if not provided
70
+ const gitContext = (0, uploader_1.detectGitContext)();
71
+ if (!this.config.branch && gitContext.branch) {
72
+ this.config.branch = gitContext.branch;
73
+ }
74
+ if (!this.config.commitSha && gitContext.commitSha) {
75
+ this.config.commitSha = gitContext.commitSha;
76
+ }
77
+ // Calculate full report path
78
+ this.reportPath = path.join(this.config.outputDir, this.config.outputFile);
79
+ // Initialize the underlying CTRF reporter
80
+ const ctrfConfig = {
81
+ outputFile: this.config.outputFile,
82
+ outputDir: this.config.outputDir,
83
+ screenshot: this.config.screenshot,
84
+ annotations: this.config.annotations,
85
+ testType: this.config.testType,
86
+ };
87
+ // Add optional environment configuration
88
+ if (this.config.appName)
89
+ ctrfConfig.appName = this.config.appName;
90
+ if (this.config.appVersion)
91
+ ctrfConfig.appVersion = this.config.appVersion;
92
+ if (this.config.buildName)
93
+ ctrfConfig.buildName = this.config.buildName;
94
+ if (this.config.buildNumber)
95
+ ctrfConfig.buildNumber = this.config.buildNumber;
96
+ if (this.config.buildUrl)
97
+ ctrfConfig.buildUrl = this.config.buildUrl;
98
+ if (this.config.testEnvironment)
99
+ ctrfConfig.testEnvironment = this.config.testEnvironment;
100
+ if (this.config.branch)
101
+ ctrfConfig.branchName = this.config.branch;
102
+ if (this.config.commitSha)
103
+ ctrfConfig.commit = this.config.commitSha;
104
+ this.ctrfReporter = new playwright_ctrf_json_reporter_1.default(ctrfConfig);
105
+ // Initialize uploader if upload is enabled
106
+ if (this.config.uploadEnabled) {
107
+ this.uploader = new uploader_1.ReportUploader(this.config);
108
+ }
109
+ }
110
+ /**
111
+ * Called once before running tests
112
+ */
113
+ onBegin(config, suite) {
114
+ if (this.ctrfReporter.onBegin) {
115
+ this.ctrfReporter.onBegin(config, suite);
116
+ }
117
+ console.log('');
118
+ console.log('='.repeat(60));
119
+ console.log('🎭 Playwright Test Manager Reporter');
120
+ console.log('='.repeat(60));
121
+ if (this.config.uploadEnabled) {
122
+ console.log(`Project: ${this.config.projectKey}`);
123
+ if (this.config.branch)
124
+ console.log(`Branch: ${this.config.branch}`);
125
+ if (this.config.commitSha)
126
+ console.log(`Commit: ${this.config.commitSha.substring(0, 7)}`);
127
+ }
128
+ else {
129
+ console.log('Upload: Disabled');
130
+ }
131
+ console.log(`Report: ${this.reportPath}`);
132
+ console.log('='.repeat(60));
133
+ console.log('');
134
+ }
135
+ /**
136
+ * Called after a test has been started
137
+ */
138
+ onTestBegin(test, result) {
139
+ if (this.ctrfReporter.onTestBegin) {
140
+ this.ctrfReporter.onTestBegin(test, result);
141
+ }
142
+ }
143
+ /**
144
+ * Called after a test has been finished
145
+ */
146
+ onTestEnd(test, result) {
147
+ if (this.ctrfReporter.onTestEnd) {
148
+ this.ctrfReporter.onTestEnd(test, result);
149
+ }
150
+ }
151
+ /**
152
+ * Called on some global error
153
+ */
154
+ onError(error) {
155
+ if (this.ctrfReporter.onError) {
156
+ this.ctrfReporter.onError(error);
157
+ }
158
+ }
159
+ /**
160
+ * Called after a step has been started
161
+ */
162
+ onStepBegin(test, result, step) {
163
+ if (this.ctrfReporter.onStepBegin) {
164
+ this.ctrfReporter.onStepBegin(test, result, step);
165
+ }
166
+ }
167
+ /**
168
+ * Called after a step has been finished
169
+ */
170
+ onStepEnd(test, result, step) {
171
+ if (this.ctrfReporter.onStepEnd) {
172
+ this.ctrfReporter.onStepEnd(test, result, step);
173
+ }
174
+ }
175
+ /**
176
+ * Called after all tests have been run
177
+ */
178
+ async onEnd(result) {
179
+ // Let the underlying CTRF reporter finish writing the report
180
+ if (this.ctrfReporter.onEnd) {
181
+ await this.ctrfReporter.onEnd(result);
182
+ }
183
+ // If upload is disabled, we're done
184
+ if (!this.config.uploadEnabled || !this.uploader) {
185
+ console.log('');
186
+ console.log('✅ CTRF report generated');
187
+ console.log(` ${this.reportPath}`);
188
+ return;
189
+ }
190
+ console.log('');
191
+ console.log('='.repeat(60));
192
+ console.log('📤 Uploading Test Results');
193
+ console.log('='.repeat(60));
194
+ try {
195
+ // Read the generated CTRF report
196
+ const reportContent = await fs.readFile(this.reportPath, 'utf-8');
197
+ const report = JSON.parse(reportContent);
198
+ // Add git context to report if not already present
199
+ if (!report.extra) {
200
+ report.extra = {};
201
+ }
202
+ if (this.config.branch && !report.extra.branch) {
203
+ report.extra.branch = this.config.branch;
204
+ }
205
+ if (this.config.commitSha && !report.extra.commitSha) {
206
+ report.extra.commitSha = this.config.commitSha;
207
+ }
208
+ // Upload report
209
+ const ingestResponse = await this.uploader.uploadReport(report);
210
+ // If report was successfully uploaded (and not a duplicate), upload artifacts
211
+ if (ingestResponse) {
212
+ await this.uploader.uploadArtifacts(report, ingestResponse);
213
+ }
214
+ console.log('='.repeat(60));
215
+ console.log('✅ Upload Complete');
216
+ console.log('='.repeat(60));
217
+ console.log('');
218
+ }
219
+ catch (error) {
220
+ const errorMessage = error instanceof Error ? error.message : String(error);
221
+ console.error('');
222
+ console.error('='.repeat(60));
223
+ console.error('❌ Upload Failed');
224
+ console.error('='.repeat(60));
225
+ console.error(`Error: ${errorMessage}`);
226
+ console.error('');
227
+ if (this.config.failOnUploadError) {
228
+ throw error;
229
+ }
230
+ }
231
+ }
232
+ }
233
+ exports.PlaywrightCTRFReporterWithUpload = PlaywrightCTRFReporterWithUpload;
234
+ exports.default = PlaywrightCTRFReporterWithUpload;
235
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Configuration options for the Playwright CTRF Reporter with Backend Upload
3
+ */
4
+ export interface PlaywrightCTRFReporterConfig {
5
+ /**
6
+ * API key for authentication
7
+ * @required
8
+ */
9
+ apiKey: string;
10
+ /**
11
+ * Project key to associate test results with
12
+ * @required
13
+ */
14
+ projectKey: string;
15
+ /**
16
+ * Git branch name (auto-detected from environment if not provided)
17
+ */
18
+ branch?: string;
19
+ /**
20
+ * Git commit SHA (auto-detected from environment if not provided)
21
+ */
22
+ commitSha?: string;
23
+ /**
24
+ * Enable/disable automatic upload to backend
25
+ * @default true
26
+ */
27
+ uploadEnabled?: boolean;
28
+ /**
29
+ * Local file output path for the CTRF report
30
+ * @default 'ctrf/ctrf-report.json'
31
+ */
32
+ outputFile?: string;
33
+ /**
34
+ * Output directory for the CTRF report
35
+ * @default 'ctrf'
36
+ */
37
+ outputDir?: string;
38
+ /**
39
+ * Fail the test run if upload fails
40
+ * @default false
41
+ */
42
+ failOnUploadError?: boolean;
43
+ /**
44
+ * Include screenshots in the report
45
+ * @default true
46
+ */
47
+ screenshot?: boolean;
48
+ /**
49
+ * Include annotations in the report
50
+ * @default false
51
+ */
52
+ annotations?: boolean;
53
+ /**
54
+ * Specify the test type (e.g., 'api', 'e2e', 'unit')
55
+ * @default 'e2e'
56
+ */
57
+ testType?: string;
58
+ /**
59
+ * Application name under test
60
+ */
61
+ appName?: string;
62
+ /**
63
+ * Application version under test
64
+ */
65
+ appVersion?: string;
66
+ /**
67
+ * Build name
68
+ */
69
+ buildName?: string;
70
+ /**
71
+ * Build number
72
+ */
73
+ buildNumber?: string;
74
+ /**
75
+ * Build URL
76
+ */
77
+ buildUrl?: string;
78
+ /**
79
+ * Test environment (e.g., 'staging', 'production')
80
+ */
81
+ testEnvironment?: string;
82
+ }
83
+ /**
84
+ * Attachment from CTRF report
85
+ */
86
+ export interface CTRFAttachment {
87
+ name: string;
88
+ contentType: string;
89
+ path: string;
90
+ }
91
+ /**
92
+ * CTRF Test result
93
+ */
94
+ export interface CTRFTest {
95
+ name: string;
96
+ status: 'passed' | 'failed' | 'skipped' | 'pending';
97
+ duration: number;
98
+ attachments?: CTRFAttachment[];
99
+ [key: string]: any;
100
+ }
101
+ /**
102
+ * CTRF Report structure
103
+ */
104
+ export interface CTRFReport {
105
+ reportId: string;
106
+ timestamp: string;
107
+ results: {
108
+ tool: {
109
+ name: string;
110
+ version: string;
111
+ };
112
+ summary: {
113
+ tests: number;
114
+ passed: number;
115
+ failed: number;
116
+ skipped: number;
117
+ pending: number;
118
+ other: number;
119
+ start: number;
120
+ stop: number;
121
+ suites: number;
122
+ };
123
+ tests: CTRFTest[];
124
+ };
125
+ extra?: {
126
+ branch?: string;
127
+ commitSha?: string;
128
+ };
129
+ [key: string]: any;
130
+ }
131
+ /**
132
+ * Response from the ingest API endpoint
133
+ */
134
+ export interface IngestResponse {
135
+ reportId: string;
136
+ testRunId: string;
137
+ summary: {
138
+ passed: number;
139
+ failed: number;
140
+ skipped: number;
141
+ total: number;
142
+ };
143
+ testResults: Array<{
144
+ id: string;
145
+ name: string;
146
+ attachments: Array<{
147
+ id: string;
148
+ name: string;
149
+ path: string;
150
+ }>;
151
+ }>;
152
+ }
153
+ /**
154
+ * Response from artifact upload endpoint
155
+ */
156
+ export interface ArtifactUploadResponse {
157
+ artifactId: string;
158
+ storageUrl: string;
159
+ linkedToAttachment: boolean;
160
+ }
161
+ /**
162
+ * API error response
163
+ */
164
+ export interface ApiErrorResponse {
165
+ error: string;
166
+ details?: string;
167
+ reportId?: string;
168
+ }
169
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { CTRFReport, IngestResponse, PlaywrightCTRFReporterConfig } from './types';
2
+ /**
3
+ * Upload CTRF report and artifacts to the backend API
4
+ */
5
+ export declare class ReportUploader {
6
+ private config;
7
+ private apiUrl;
8
+ constructor(config: PlaywrightCTRFReporterConfig);
9
+ /**
10
+ * Upload CTRF report to the backend
11
+ */
12
+ uploadReport(report: CTRFReport): Promise<IngestResponse | null>;
13
+ /**
14
+ * Upload all artifacts from the CTRF report
15
+ */
16
+ uploadArtifacts(report: CTRFReport, ingestResponse: IngestResponse): Promise<number>;
17
+ /**
18
+ * Upload a single artifact file
19
+ */
20
+ private uploadSingleArtifact;
21
+ }
22
+ /**
23
+ * Detect git context from environment variables
24
+ */
25
+ export declare function detectGitContext(): {
26
+ branch?: string;
27
+ commitSha?: string;
28
+ };
29
+ //# sourceMappingURL=uploader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EAEV,cAAc,EAEd,4BAA4B,EAC7B,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAG+C;IAE7D,OAAO,CAAC,MAAM,CAAkD;gBAEpD,MAAM,EAAE,4BAA4B;IAUhD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA8DtE;;OAEG;IACG,eAAe,CACnB,MAAM,EAAE,UAAU,EAClB,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,MAAM,CAAC;IAsElB;;OAEG;YACW,oBAAoB;CAoDnC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAoC1E"}
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ReportUploader = void 0;
37
+ exports.detectGitContext = detectGitContext;
38
+ const fs = __importStar(require("fs/promises"));
39
+ const path = __importStar(require("path"));
40
+ /**
41
+ * Upload CTRF report and artifacts to the backend API
42
+ */
43
+ class ReportUploader {
44
+ constructor(config) {
45
+ this.apiUrl = 'https://test-manager-backend.fly.dev';
46
+ this.config = {
47
+ apiKey: config.apiKey,
48
+ projectKey: config.projectKey,
49
+ branch: config.branch,
50
+ commitSha: config.commitSha,
51
+ failOnUploadError: config.failOnUploadError ?? false,
52
+ };
53
+ }
54
+ /**
55
+ * Upload CTRF report to the backend
56
+ */
57
+ async uploadReport(report) {
58
+ try {
59
+ console.log('📤 Uploading test results to backend...');
60
+ const ingestPayload = {
61
+ reportId: report.reportId,
62
+ report,
63
+ commitSha: this.config.commitSha,
64
+ branch: this.config.branch,
65
+ };
66
+ const response = await fetch(`${this.apiUrl}/api/v1/ingest`, {
67
+ method: 'POST',
68
+ headers: {
69
+ 'X-API-KEY': this.config.apiKey,
70
+ 'Content-Type': 'application/json',
71
+ },
72
+ body: JSON.stringify(ingestPayload),
73
+ });
74
+ // Handle idempotent duplicate reports
75
+ if (response.status === 409) {
76
+ const errorData = (await response.json());
77
+ console.warn(`⚠️ Report already exists: ${errorData.reportId}`);
78
+ return null;
79
+ }
80
+ if (!response.ok) {
81
+ let errorMessage;
82
+ try {
83
+ const errorData = (await response.json());
84
+ errorMessage = errorData.error || `HTTP ${response.status}`;
85
+ if (errorData.details) {
86
+ errorMessage += `: ${errorData.details}`;
87
+ }
88
+ }
89
+ catch {
90
+ errorMessage = await response.text();
91
+ }
92
+ throw new Error(`API ingest failed: ${errorMessage}`);
93
+ }
94
+ const result = (await response.json());
95
+ console.log(`✅ Report uploaded successfully`);
96
+ console.log(` Report ID: ${result.reportId}`);
97
+ console.log(` Test Run ID: ${result.testRunId}`);
98
+ console.log(` Summary: ${result.summary.passed}/${result.summary.total} passed`);
99
+ return result;
100
+ }
101
+ catch (error) {
102
+ const errorMessage = error instanceof Error ? error.message : String(error);
103
+ const message = `Failed to upload report: ${errorMessage}`;
104
+ if (this.config.failOnUploadError) {
105
+ throw new Error(message);
106
+ }
107
+ else {
108
+ console.error(`❌ ${message}`);
109
+ return null;
110
+ }
111
+ }
112
+ }
113
+ /**
114
+ * Upload all artifacts from the CTRF report
115
+ */
116
+ async uploadArtifacts(report, ingestResponse) {
117
+ try {
118
+ const totalAttachments = report.results.tests.reduce((sum, test) => sum + (test.attachments?.length || 0), 0);
119
+ if (totalAttachments === 0) {
120
+ console.log('--- Artifact Upload: No artifacts found to upload. ---');
121
+ return 0;
122
+ }
123
+ console.log(`--- Artifact Upload: Starting (${totalAttachments} artifact(s)) ---`);
124
+ let uploadedCount = 0;
125
+ // Iterate through all tests
126
+ for (const test of report.results.tests) {
127
+ if (!test.attachments || test.attachments.length === 0) {
128
+ continue;
129
+ }
130
+ // Find matching test result from ingest response
131
+ const testResult = ingestResponse.testResults.find((tr) => tr.name === test.name);
132
+ if (!testResult) {
133
+ console.warn(`[Artifact] Could not find test result for: ${test.name}`);
134
+ continue;
135
+ }
136
+ // Upload each attachment
137
+ for (const attachment of test.attachments) {
138
+ console.log(`[Artifact] Preparing to upload: ${attachment.path}`);
139
+ try {
140
+ const uploaded = await this.uploadSingleArtifact(testResult.id, attachment, ingestResponse.reportId);
141
+ if (uploaded) {
142
+ uploadedCount++;
143
+ // console.log(`[Artifact] Successfully uploaded: ${attachment.path}`);
144
+ }
145
+ }
146
+ catch (error) {
147
+ const errorMessage = error instanceof Error ? error.message : String(error);
148
+ if (errorMessage.includes('File not found')) {
149
+ console.error(`[Artifact] File not found: ${attachment.path}`);
150
+ }
151
+ else {
152
+ console.error(`[Artifact] Failed to upload: ${attachment.path}`);
153
+ console.error(`[Artifact] Error:`, errorMessage);
154
+ }
155
+ }
156
+ }
157
+ }
158
+ console.log(`--- Artifact Upload: Completed. Total artifacts attempted: ${totalAttachments}, uploaded: ${uploadedCount} ---`);
159
+ return uploadedCount;
160
+ }
161
+ catch (error) {
162
+ const errorMessage = error instanceof Error ? error.message : String(error);
163
+ const message = `Failed to upload artifacts: ${errorMessage}`;
164
+ if (this.config.failOnUploadError) {
165
+ throw new Error(message);
166
+ }
167
+ else {
168
+ console.error(`❌ ${message}`);
169
+ return 0;
170
+ }
171
+ }
172
+ }
173
+ /**
174
+ * Upload a single artifact file
175
+ */
176
+ async uploadSingleArtifact(testResultId, attachment, reportId) {
177
+ // Resolve file path
178
+ const filePath = path.resolve(attachment.path);
179
+ // Check if file exists
180
+ try {
181
+ await fs.access(filePath);
182
+ }
183
+ catch {
184
+ console.warn(` File not found: ${filePath}`);
185
+ return false;
186
+ }
187
+ // Read file
188
+ let fileBuffer;
189
+ try {
190
+ fileBuffer = await fs.readFile(filePath);
191
+ }
192
+ catch (error) {
193
+ const errorMessage = error instanceof Error ? error.message : String(error);
194
+ throw new Error(`Failed to read file: ${errorMessage}`);
195
+ }
196
+ // Create native FormData with Blob (compatible with native fetch)
197
+ const blob = new Blob([fileBuffer], { type: attachment.contentType });
198
+ const formData = new FormData();
199
+ formData.append('testResultId', testResultId);
200
+ formData.append('ctrfAttachmentName', attachment.name);
201
+ formData.append('file', blob, path.basename(filePath));
202
+ // Upload to API
203
+ const uploadUrl = `${this.apiUrl}/api/v1/artifacts/${reportId}`;
204
+ const response = await fetch(uploadUrl, {
205
+ method: 'POST',
206
+ headers: {
207
+ 'X-API-KEY': this.config.apiKey,
208
+ // Note: Don't set Content-Type - fetch sets it automatically with boundary
209
+ },
210
+ body: formData,
211
+ });
212
+ if (!response.ok) {
213
+ const errorText = await response.text();
214
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
215
+ }
216
+ await response.json();
217
+ return true;
218
+ }
219
+ }
220
+ exports.ReportUploader = ReportUploader;
221
+ /**
222
+ * Detect git context from environment variables
223
+ */
224
+ function detectGitContext() {
225
+ // Try GitHub Actions
226
+ if (process.env.GITHUB_REF && process.env.GITHUB_SHA) {
227
+ const ref = process.env.GITHUB_REF;
228
+ const branch = ref.replace('refs/heads/', '').replace('refs/tags/', '');
229
+ return {
230
+ branch,
231
+ commitSha: process.env.GITHUB_SHA,
232
+ };
233
+ }
234
+ // Try GitLab CI
235
+ if (process.env.CI_COMMIT_BRANCH && process.env.CI_COMMIT_SHA) {
236
+ return {
237
+ branch: process.env.CI_COMMIT_BRANCH,
238
+ commitSha: process.env.CI_COMMIT_SHA,
239
+ };
240
+ }
241
+ // Try CircleCI
242
+ if (process.env.CIRCLE_BRANCH && process.env.CIRCLE_SHA1) {
243
+ return {
244
+ branch: process.env.CIRCLE_BRANCH,
245
+ commitSha: process.env.CIRCLE_SHA1,
246
+ };
247
+ }
248
+ // Try Jenkins
249
+ if (process.env.GIT_BRANCH && process.env.GIT_COMMIT) {
250
+ return {
251
+ branch: process.env.GIT_BRANCH,
252
+ commitSha: process.env.GIT_COMMIT,
253
+ };
254
+ }
255
+ return {};
256
+ }
257
+ //# sourceMappingURL=uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader.js","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@testream/playwright-reporter",
3
+ "version": "0.1.0",
4
+ "description": "Playwright CTRF reporter with automatic upload to Jira Test Management backend",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "format": "prettier --write '**/*.ts'",
10
+ "lint": "eslint src/**/*.ts",
11
+ "prepublishOnly": "npm run build",
12
+ "test": "echo \"No tests yet\" && exit 0",
13
+ "all": "npm run format && npm run lint && npm run build"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/your-org/jira-test-manager.git"
18
+ },
19
+ "keywords": [
20
+ "playwright",
21
+ "reporter",
22
+ "testing",
23
+ "test-management",
24
+ "ctrf",
25
+ "test-results",
26
+ "jira"
27
+ ],
28
+ "author": "Jira Test Manager Team",
29
+ "license": "SEE LICENSE IN LICENSE",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "peerDependencies": {
34
+ "@playwright/test": ">=1.40.0"
35
+ },
36
+ "dependencies": {
37
+ "playwright-ctrf-json-reporter": "^0.0.27"
38
+ },
39
+ "devDependencies": {
40
+ "@playwright/test": "^1.40.0",
41
+ "@types/node": "^20.10.6",
42
+ "@typescript-eslint/eslint-plugin": "^6.17.0",
43
+ "@typescript-eslint/parser": "^6.17.0",
44
+ "dotenv": "^17.2.3",
45
+ "eslint": "^8.56.0",
46
+ "prettier": "^3.1.1",
47
+ "typescript": "^5.3.3"
48
+ },
49
+ "engines": {
50
+ "node": ">=18.0.0"
51
+ },
52
+ "files": [
53
+ "dist",
54
+ "README.md",
55
+ "LICENSE"
56
+ ]
57
+ }