playwright-testchimp-reporter 0.0.1

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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TestChimpHQ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,362 @@
1
+ # playwright-testchimp-reporter
2
+
3
+ Playwright reporter for TestChimp test execution tracking and requirement traceability. Automatically reports test execution results to TestChimp backend, enabling continuous requirement coverage tracking in your CI/CD pipelines.
4
+
5
+ ## Features
6
+
7
+ - ✅ **Automatic test execution tracking**: Reports test results to TestChimp backend
8
+ - ✅ **Requirement traceability**: Links test executions to scenarios via `// @Scenario:` comments
9
+ - ✅ **CI/CD integration**: Works with any CI/CD platform (GitHub Actions, GitLab CI, Jenkins, etc.)
10
+ - ✅ **Flexible configuration**: Configure via environment variables or Playwright config
11
+ - ✅ **Screenshot capture**: Automatically captures screenshots for failing steps
12
+ - ✅ **Retry handling**: Configurable retry attempt reporting
13
+ - ✅ **Verbose logging**: Optional detailed logging for debugging
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install --save-dev playwright-testchimp-reporter
19
+ ```
20
+
21
+ Or with yarn:
22
+
23
+ ```bash
24
+ yarn add -D playwright-testchimp-reporter
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ### 1. Install the package
30
+
31
+ ```bash
32
+ npm install --save-dev playwright-testchimp-reporter
33
+ ```
34
+
35
+ ### 2. Configure in `playwright.config.ts`
36
+
37
+ ```typescript
38
+ import { defineConfig } from '@playwright/test';
39
+
40
+ export default defineConfig({
41
+ reporter: [
42
+ ['list'], // Standard list reporter
43
+ ['playwright-testchimp-reporter', {
44
+ // Credentials from environment variables (recommended)
45
+ // See Configuration section for all options
46
+ }]
47
+ ],
48
+ // ... rest of your config
49
+ });
50
+ ```
51
+
52
+ ### 3. Set environment variables
53
+
54
+ ```bash
55
+ export TESTCHIMP_API_KEY=your_api_key
56
+ export TESTCHIMP_PROJECT_ID=your_project_id
57
+ ```
58
+
59
+ ### 4. Run your tests
60
+
61
+ ```bash
62
+ npx playwright test
63
+ ```
64
+
65
+ Test execution results will be automatically reported to TestChimp!
66
+
67
+ ## Configuration
68
+
69
+ ### Required Configuration
70
+
71
+ You must provide API credentials either via environment variables (recommended) or in the config:
72
+
73
+ **Environment Variables (Recommended)**:
74
+ ```bash
75
+ TESTCHIMP_API_KEY=your_api_key
76
+ TESTCHIMP_PROJECT_ID=your_project_id
77
+ ```
78
+
79
+ **Config Options**:
80
+ ```typescript
81
+ {
82
+ apiKey: 'your_api_key',
83
+ projectId: 'your_project_id',
84
+ }
85
+ ```
86
+
87
+ ### Optional Configuration
88
+
89
+ All configuration options can be provided via environment variables or in the config:
90
+
91
+ | Option | Environment Variable | Default | Description |
92
+ |--------|---------------------|---------|-------------|
93
+ | `apiUrl` | `TESTCHIMP_API_URL` | `https://featureservice.testchimp.io` | TestChimp API URL |
94
+ | `testsFolder` | `TESTCHIMP_TESTS_FOLDER` | `tests` | Base folder for relative path calculation |
95
+ | `release` | `TESTCHIMP_RELEASE` | - | Release/version identifier |
96
+ | `environment` | `TESTCHIMP_ENV` | - | Environment name (e.g., staging, production) |
97
+ | `reportOnlyFinalAttempt` | - | `true` | Only report final retry attempt |
98
+ | `captureScreenshots` | - | `true` | Capture screenshots for failing steps |
99
+ | `verbose` | - | `false` | Enable verbose logging |
100
+
101
+ ### Complete Configuration Example
102
+
103
+ ```typescript
104
+ import { defineConfig } from '@playwright/test';
105
+
106
+ export default defineConfig({
107
+ testDir: './tests',
108
+ reporter: [
109
+ ['list'],
110
+ ['playwright-testchimp-reporter', {
111
+ // Credentials from environment variables (recommended)
112
+ // Optional: override defaults
113
+ reportOnlyFinalAttempt: true,
114
+ captureScreenshots: true,
115
+ verbose: process.env.CI === 'true', // Verbose in CI
116
+ }]
117
+ ],
118
+ use: {
119
+ baseURL: 'https://example.com',
120
+ },
121
+ });
122
+ ```
123
+
124
+ ## Linking Tests to Scenarios
125
+
126
+ To enable requirement traceability, add scenario comments to your tests:
127
+
128
+ ```javascript
129
+ // @Scenario: User can log in with valid credentials
130
+ test('login test', async ({ page }) => {
131
+ await page.goto('https://example.com/login');
132
+ await page.fill('#username', 'testuser');
133
+ await page.fill('#password', 'password123');
134
+ await page.click('button[type="submit"]');
135
+ await expect(page).toHaveURL('https://example.com/dashboard');
136
+ });
137
+ ```
138
+
139
+ The reporter automatically extracts these comments and links test executions to scenarios. Scenario titles must match exactly (case-sensitive).
140
+
141
+ ### Multiple Scenarios
142
+
143
+ You can link a single test to multiple scenarios:
144
+
145
+ ```javascript
146
+ // @Scenario: User can log in with valid credentials
147
+ // @Scenario: User session persists after login
148
+ test('login and session test', async ({ page }) => {
149
+ // ... test code
150
+ });
151
+ ```
152
+
153
+ ## CI/CD Integration
154
+
155
+ ### GitHub Actions
156
+
157
+ ```yaml
158
+ name: Run Tests
159
+
160
+ on:
161
+ push:
162
+ branches: [ main, develop ]
163
+ pull_request:
164
+ branches: [ main ]
165
+
166
+ jobs:
167
+ test:
168
+ runs-on: ubuntu-latest
169
+ steps:
170
+ - uses: actions/checkout@v3
171
+
172
+ - name: Setup Node.js
173
+ uses: actions/setup-node@v3
174
+ with:
175
+ node-version: '18'
176
+
177
+ - name: Install dependencies
178
+ run: npm ci
179
+
180
+ - name: Install Playwright browsers
181
+ run: npx playwright install --with-deps
182
+
183
+ - name: Run tests
184
+ env:
185
+ TESTCHIMP_API_KEY: ${{ secrets.TESTCHIMP_API_KEY }}
186
+ TESTCHIMP_PROJECT_ID: ${{ secrets.TESTCHIMP_PROJECT_ID }}
187
+ TESTCHIMP_ENV: staging
188
+ TESTCHIMP_RELEASE: ${{ github.ref_name }}
189
+ run: npx playwright test
190
+ ```
191
+
192
+ ### GitLab CI
193
+
194
+ ```yaml
195
+ test:
196
+ image: node:18
197
+ before_script:
198
+ - npm ci
199
+ - npx playwright install --with-deps
200
+ script:
201
+ - npx playwright test
202
+ variables:
203
+ TESTCHIMP_API_KEY: $TESTCHIMP_API_KEY
204
+ TESTCHIMP_PROJECT_ID: $TESTCHIMP_PROJECT_ID
205
+ TESTCHIMP_ENV: staging
206
+ TESTCHIMP_RELEASE: $CI_COMMIT_REF_NAME
207
+ ```
208
+
209
+ ### Jenkins
210
+
211
+ ```groovy
212
+ pipeline {
213
+ agent any
214
+ environment {
215
+ TESTCHIMP_API_KEY = credentials('testchimp-api-key')
216
+ TESTCHIMP_PROJECT_ID = credentials('testchimp-project-id')
217
+ TESTCHIMP_ENV = 'staging'
218
+ TESTCHIMP_RELEASE = env.BUILD_NUMBER
219
+ }
220
+ stages {
221
+ stage('Test') {
222
+ steps {
223
+ sh 'npm ci'
224
+ sh 'npx playwright install --with-deps'
225
+ sh 'npx playwright test'
226
+ }
227
+ }
228
+ }
229
+ }
230
+ ```
231
+
232
+ ## How It Works
233
+
234
+ 1. **Test execution**: Tests run normally using the standard Playwright runner
235
+ 2. **Automatic reporting**: The reporter captures:
236
+ - Test name, file path, and suite structure
237
+ - Step-by-step execution results
238
+ - Pass/fail status
239
+ - Error messages (if any)
240
+ - Screenshots for failing steps (if enabled)
241
+ 3. **Backend ingestion**: Execution data is sent to TestChimp backend
242
+ 4. **Coverage tracking**: Test executions are automatically linked to scenarios based on `// @Scenario:` comments
243
+ 5. **Traceability updates**: Coverage information is updated in real-time in the TestChimp platform
244
+
245
+ ## Configuration Options Reference
246
+
247
+ ### `apiKey` / `TESTCHIMP_API_KEY`
248
+ - **Type**: `string`
249
+ - **Required**: Yes
250
+ - **Description**: API key for TestChimp authentication
251
+
252
+ ### `projectId` / `TESTCHIMP_PROJECT_ID`
253
+ - **Type**: `string`
254
+ - **Required**: Yes
255
+ - **Description**: TestChimp project identifier
256
+
257
+ ### `apiUrl` / `TESTCHIMP_API_URL`
258
+ - **Type**: `string`
259
+ - **Default**: `https://featureservice.testchimp.io`
260
+ - **Description**: TestChimp API URL
261
+
262
+ ### `testsFolder` / `TESTCHIMP_TESTS_FOLDER`
263
+ - **Type**: `string`
264
+ - **Default**: `tests`
265
+ - **Description**: Base folder for relative path calculation. Used to derive test file paths relative to this folder.
266
+
267
+ ### `release` / `TESTCHIMP_RELEASE`
268
+ - **Type**: `string`
269
+ - **Default**: `''`
270
+ - **Description**: Release/version identifier. Useful for tracking test executions by release.
271
+
272
+ ### `environment` / `TESTCHIMP_ENV`
273
+ - **Type**: `string`
274
+ - **Default**: `''`
275
+ - **Description**: Environment name (e.g., `staging`, `production`). Useful for tracking coverage separately by environment.
276
+
277
+ ### `reportOnlyFinalAttempt`
278
+ - **Type**: `boolean`
279
+ - **Default**: `true`
280
+ - **Description**: When `true`, only the final retry attempt is reported. When `false`, all retry attempts are reported.
281
+
282
+ ### `captureScreenshots`
283
+ - **Type**: `boolean`
284
+ - **Default**: `true`
285
+ - **Description**: When `true`, screenshots are captured and attached to failing steps as base64-encoded images.
286
+
287
+ ### `verbose`
288
+ - **Type**: `boolean`
289
+ - **Default**: `false`
290
+ - **Description**: When `true`, enables detailed logging for debugging. Useful for troubleshooting configuration issues.
291
+
292
+ ## Troubleshooting
293
+
294
+ ### Reporter Not Sending Data
295
+
296
+ **Check credentials**:
297
+ - Verify `TESTCHIMP_API_KEY` and `TESTCHIMP_PROJECT_ID` are set correctly
298
+ - Ensure credentials are valid and have access to the project
299
+
300
+ **Enable verbose logging**:
301
+ ```typescript
302
+ {
303
+ verbose: true
304
+ }
305
+ ```
306
+
307
+ **Check network connectivity**:
308
+ - Ensure your CI environment can reach the TestChimp API
309
+ - Check firewall rules if running in a restricted network
310
+
311
+ ### Tests Not Linked to Scenarios
312
+
313
+ **Verify scenario comments**:
314
+ - Ensure `// @Scenario:` comments are present in your tests
315
+ - Check that comments are placed before the test function
316
+
317
+ **Check scenario titles**:
318
+ - Scenario titles must match exactly (case-sensitive)
319
+ - Verify the scenario exists in your TestChimp project
320
+
321
+ **Review test file paths**:
322
+ - Ensure test files are in the expected location
323
+ - Check that `testsFolder` configuration matches your project structure
324
+
325
+ ### Missing Screenshots
326
+
327
+ **Enable screenshot capture**:
328
+ ```typescript
329
+ {
330
+ captureScreenshots: true
331
+ }
332
+ ```
333
+
334
+ **Check Playwright config**:
335
+ - Ensure Playwright is configured to capture screenshots on failure
336
+ - Verify screenshot settings in your `playwright.config.ts`
337
+
338
+ ### Authentication Errors
339
+
340
+ If you see authentication errors:
341
+ - Verify your API key is correct
342
+ - Check that your project ID matches your TestChimp project
343
+ - Ensure credentials are properly set as environment variables or in config
344
+
345
+ ## Requirements
346
+
347
+ - **Playwright**: `>=1.40.0`
348
+ - **Node.js**: `>=16.0.0`
349
+
350
+ ## License
351
+
352
+ MIT
353
+
354
+ ## Links
355
+
356
+ - **GitHub Repository**: [https://github.com/testchimphq/playwright-testchimp-reporter](https://github.com/testchimphq/playwright-testchimp-reporter)
357
+ - **TestChimp Documentation**: [https://docs.testchimp.io](https://docs.testchimp.io)
358
+ - **Playwright Documentation**: [https://playwright.dev](https://playwright.dev)
359
+
360
+ ## Support
361
+
362
+ For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/testchimphq/playwright-testchimp-reporter).
@@ -0,0 +1,19 @@
1
+ import { IngestSmartTestExecutionReportResponse, SmartTestExecutionReport } from './types';
2
+ /**
3
+ * HTTP client for communicating with the TestChimp backend API
4
+ */
5
+ export declare class TestChimpApiClient {
6
+ private client;
7
+ private projectId;
8
+ private verbose;
9
+ constructor(apiUrl: string, apiKey: string, projectId: string, verbose?: boolean);
10
+ /**
11
+ * Send a test execution report to the TestChimp backend
12
+ */
13
+ ingestExecutionReport(report: SmartTestExecutionReport): Promise<IngestSmartTestExecutionReportResponse>;
14
+ /**
15
+ * Check if the client is properly configured
16
+ */
17
+ isConfigured(): boolean;
18
+ }
19
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sCAAsC,EACtC,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAkDjB;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe;IAevF;;OAEG;IACG,qBAAqB,CACzB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,sCAAsC,CAAC;IAgClD;;OAEG;IACH,YAAY,IAAI,OAAO;CAGxB"}
@@ -0,0 +1,129 @@
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.TestChimpApiClient = void 0;
37
+ const axios_1 = __importStar(require("axios"));
38
+ /**
39
+ * Convert camelCase keys to snake_case recursively
40
+ */
41
+ function toSnakeCase(obj) {
42
+ if (obj === null || obj === undefined) {
43
+ return obj;
44
+ }
45
+ if (Array.isArray(obj)) {
46
+ return obj.map(toSnakeCase);
47
+ }
48
+ if (typeof obj === 'object') {
49
+ const result = {};
50
+ for (const [key, value] of Object.entries(obj)) {
51
+ const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
52
+ result[snakeKey] = toSnakeCase(value);
53
+ }
54
+ return result;
55
+ }
56
+ return obj;
57
+ }
58
+ /**
59
+ * Convert snake_case keys to camelCase recursively
60
+ */
61
+ function toCamelCase(obj) {
62
+ if (obj === null || obj === undefined) {
63
+ return obj;
64
+ }
65
+ if (Array.isArray(obj)) {
66
+ return obj.map(toCamelCase);
67
+ }
68
+ if (typeof obj === 'object') {
69
+ const result = {};
70
+ for (const [key, value] of Object.entries(obj)) {
71
+ const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
72
+ result[camelKey] = toCamelCase(value);
73
+ }
74
+ return result;
75
+ }
76
+ return obj;
77
+ }
78
+ /**
79
+ * HTTP client for communicating with the TestChimp backend API
80
+ */
81
+ class TestChimpApiClient {
82
+ constructor(apiUrl, apiKey, projectId, verbose = false) {
83
+ this.projectId = projectId;
84
+ this.verbose = verbose;
85
+ this.client = axios_1.default.create({
86
+ baseURL: apiUrl,
87
+ headers: {
88
+ 'Content-Type': 'application/json',
89
+ 'testchimp-api-key': apiKey,
90
+ 'testchimp-project-id': projectId
91
+ },
92
+ timeout: 30000
93
+ });
94
+ }
95
+ /**
96
+ * Send a test execution report to the TestChimp backend
97
+ */
98
+ async ingestExecutionReport(report) {
99
+ // Convert camelCase to snake_case for the API
100
+ const snakeCaseReport = toSnakeCase({ report });
101
+ try {
102
+ if (this.verbose) {
103
+ console.log('[TestChimp] Sending report for test:', report.testName);
104
+ }
105
+ const response = await this.client.post('/api/ingest_smarttest_execution_report', snakeCaseReport);
106
+ // Convert response from snake_case to camelCase
107
+ return toCamelCase(response.data);
108
+ }
109
+ catch (error) {
110
+ if (error instanceof axios_1.AxiosError) {
111
+ const status = error.response?.status;
112
+ const message = error.response?.data?.message || error.message;
113
+ console.error(`[TestChimp] API error (${status}): ${message}`);
114
+ if (status === 401 || status === 403) {
115
+ throw new Error(`[TestChimp] Authentication failed. Check TESTCHIMP_API_KEY and TESTCHIMP_PROJECT_ID.`);
116
+ }
117
+ }
118
+ throw error;
119
+ }
120
+ }
121
+ /**
122
+ * Check if the client is properly configured
123
+ */
124
+ isConfigured() {
125
+ return !!this.projectId;
126
+ }
127
+ }
128
+ exports.TestChimpApiClient = TestChimpApiClient;
129
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * playwright-testchimp-reporter
3
+ *
4
+ * Playwright reporter for TestChimp test execution tracking and coverage reporting.
5
+ *
6
+ * @example
7
+ * // playwright.config.ts
8
+ * import { defineConfig } from '@playwright/test';
9
+ *
10
+ * export default defineConfig({
11
+ * reporter: [
12
+ * ['list'],
13
+ * ['playwright-testchimp-reporter', {
14
+ * verbose: true,
15
+ * reportOnlyFinalAttempt: true,
16
+ * captureScreenshots: true
17
+ * }]
18
+ * ]
19
+ * });
20
+ *
21
+ * Environment Variables:
22
+ * - TESTCHIMP_API_KEY (required): API key for authentication
23
+ * - TESTCHIMP_PROJECT_ID (required): Project identifier
24
+ * - TESTCHIMP_API_URL (optional): API URL (default: https://api.testchimp.io)
25
+ * - TESTCHIMP_TESTS_FOLDER (optional): Base folder for relative path calculation
26
+ * - TESTCHIMP_RELEASE (optional): Release/version identifier
27
+ * - TESTCHIMP_ENV (optional): Environment name (e.g., staging, prod)
28
+ */
29
+ export { TestChimpReporter } from './testchimp-reporter';
30
+ export { TestChimpApiClient } from './api-client';
31
+ export * from './types';
32
+ export * from './utils';
33
+ import { TestChimpReporter } from './testchimp-reporter';
34
+ export default TestChimpReporter;
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,eAAe,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /**
3
+ * playwright-testchimp-reporter
4
+ *
5
+ * Playwright reporter for TestChimp test execution tracking and coverage reporting.
6
+ *
7
+ * @example
8
+ * // playwright.config.ts
9
+ * import { defineConfig } from '@playwright/test';
10
+ *
11
+ * export default defineConfig({
12
+ * reporter: [
13
+ * ['list'],
14
+ * ['playwright-testchimp-reporter', {
15
+ * verbose: true,
16
+ * reportOnlyFinalAttempt: true,
17
+ * captureScreenshots: true
18
+ * }]
19
+ * ]
20
+ * });
21
+ *
22
+ * Environment Variables:
23
+ * - TESTCHIMP_API_KEY (required): API key for authentication
24
+ * - TESTCHIMP_PROJECT_ID (required): Project identifier
25
+ * - TESTCHIMP_API_URL (optional): API URL (default: https://api.testchimp.io)
26
+ * - TESTCHIMP_TESTS_FOLDER (optional): Base folder for relative path calculation
27
+ * - TESTCHIMP_RELEASE (optional): Release/version identifier
28
+ * - TESTCHIMP_ENV (optional): Environment name (e.g., staging, prod)
29
+ */
30
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ var desc = Object.getOwnPropertyDescriptor(m, k);
33
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
34
+ desc = { enumerable: true, get: function() { return m[k]; } };
35
+ }
36
+ Object.defineProperty(o, k2, desc);
37
+ }) : (function(o, m, k, k2) {
38
+ if (k2 === undefined) k2 = k;
39
+ o[k2] = m[k];
40
+ }));
41
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
42
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.TestChimpApiClient = exports.TestChimpReporter = void 0;
46
+ var testchimp_reporter_1 = require("./testchimp-reporter");
47
+ Object.defineProperty(exports, "TestChimpReporter", { enumerable: true, get: function () { return testchimp_reporter_1.TestChimpReporter; } });
48
+ var api_client_1 = require("./api-client");
49
+ Object.defineProperty(exports, "TestChimpApiClient", { enumerable: true, get: function () { return api_client_1.TestChimpApiClient; } });
50
+ __exportStar(require("./types"), exports);
51
+ __exportStar(require("./utils"), exports);
52
+ // Default export for Playwright reporter configuration
53
+ const testchimp_reporter_2 = require("./testchimp-reporter");
54
+ exports.default = testchimp_reporter_2.TestChimpReporter;
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;;;;;;;;;;;;;;;AAEH,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,2CAAkD;AAAzC,gHAAA,kBAAkB,OAAA;AAC3B,0CAAwB;AACxB,0CAAwB;AAExB,uDAAuD;AACvD,6DAAyD;AACzD,kBAAe,sCAAiB,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { Reporter, FullConfig, Suite, TestCase, TestResult, TestStep, FullResult } from '@playwright/test/reporter';
2
+ import { TestChimpReporterOptions } from './types';
3
+ /**
4
+ * TestChimp Playwright Reporter
5
+ *
6
+ * Reports test execution data to the TestChimp backend for
7
+ * coverage tracking and traceability.
8
+ *
9
+ * @example
10
+ * // playwright.config.ts
11
+ * export default defineConfig({
12
+ * reporter: [
13
+ * ['playwright-testchimp-reporter', {
14
+ * verbose: true,
15
+ * reportOnlyFinalAttempt: true
16
+ * }]
17
+ * ]
18
+ * });
19
+ */
20
+ export declare class TestChimpReporter implements Reporter {
21
+ private config;
22
+ private options;
23
+ private apiClient;
24
+ private batchInvocationId;
25
+ private testsFolder;
26
+ private testExecutions;
27
+ private testRetryInfo;
28
+ private isEnabled;
29
+ constructor(options?: TestChimpReporterOptions);
30
+ onBegin(config: FullConfig, suite: Suite): void;
31
+ onTestBegin(test: TestCase, result: TestResult): void;
32
+ onStepEnd(test: TestCase, result: TestResult, step: TestStep): void;
33
+ onTestEnd(test: TestCase, result: TestResult): Promise<void>;
34
+ onEnd(result: FullResult): Promise<void>;
35
+ private getTestKey;
36
+ private scanTestRetries;
37
+ private buildReport;
38
+ private mapStatus;
39
+ /**
40
+ * Attach screenshots as base64 to failing steps only
41
+ */
42
+ private attachScreenshotsToFailingSteps;
43
+ }
44
+ //# sourceMappingURL=testchimp-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testchimp-reporter.d.ts","sourceRoot":"","sources":["../src/testchimp-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAInC,OAAO,EACL,wBAAwB,EAKzB,MAAM,SAAS,CAAC;AAqBjB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;IAChD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,WAAW,CAAc;IAGjC,OAAO,CAAC,cAAc,CAA8C;IAGpE,OAAO,CAAC,aAAa,CAAqC;IAG1D,OAAO,CAAC,SAAS,CAAkB;gBAEvB,OAAO,GAAE,wBAA6B;IAclD,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAgC/C,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAwBrD,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAkC7D,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA0C5D,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9C,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,WAAW;IAoCnB,OAAO,CAAC,SAAS;IAcjB;;OAEG;IACH,OAAO,CAAC,+BAA+B;CAuCxC"}
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TestChimpReporter = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const api_client_1 = require("./api-client");
9
+ const types_1 = require("./types");
10
+ const utils_1 = require("./utils");
11
+ /**
12
+ * TestChimp Playwright Reporter
13
+ *
14
+ * Reports test execution data to the TestChimp backend for
15
+ * coverage tracking and traceability.
16
+ *
17
+ * @example
18
+ * // playwright.config.ts
19
+ * export default defineConfig({
20
+ * reporter: [
21
+ * ['playwright-testchimp-reporter', {
22
+ * verbose: true,
23
+ * reportOnlyFinalAttempt: true
24
+ * }]
25
+ * ]
26
+ * });
27
+ */
28
+ class TestChimpReporter {
29
+ constructor(options = {}) {
30
+ this.apiClient = null;
31
+ this.batchInvocationId = '';
32
+ this.testsFolder = '';
33
+ // Track test executions (keyed by test ID + attempt)
34
+ this.testExecutions = new Map();
35
+ // Track retry counts per test (to identify final attempt)
36
+ this.testRetryInfo = new Map();
37
+ // Flag to indicate if reporter is properly configured
38
+ this.isEnabled = false;
39
+ this.options = {
40
+ apiKey: options.apiKey || '',
41
+ apiUrl: options.apiUrl || '',
42
+ projectId: options.projectId || '',
43
+ testsFolder: options.testsFolder || '',
44
+ release: options.release || '',
45
+ environment: options.environment || '',
46
+ reportOnlyFinalAttempt: options.reportOnlyFinalAttempt ?? true,
47
+ captureScreenshots: options.captureScreenshots ?? true,
48
+ verbose: options.verbose ?? false
49
+ };
50
+ }
51
+ onBegin(config, suite) {
52
+ this.config = config;
53
+ this.batchInvocationId = (0, utils_1.generateUUID)();
54
+ // Initialize configuration from env vars (env vars take precedence)
55
+ const apiKey = (0, utils_1.getEnvVar)('TESTCHIMP_API_KEY', this.options.apiKey);
56
+ const apiUrl = (0, utils_1.getEnvVar)('TESTCHIMP_API_URL', this.options.apiUrl) || 'https://featureservice.testchimp.io';
57
+ const projectId = (0, utils_1.getEnvVar)('TESTCHIMP_PROJECT_ID', this.options.projectId);
58
+ this.testsFolder = (0, utils_1.getEnvVar)('TESTCHIMP_TESTS_FOLDER', this.options.testsFolder) || 'tests';
59
+ // Update options with env var values for release/environment
60
+ this.options.release = (0, utils_1.getEnvVar)('TESTCHIMP_RELEASE', this.options.release) || '';
61
+ this.options.environment = (0, utils_1.getEnvVar)('TESTCHIMP_ENV', this.options.environment) || '';
62
+ if (!apiKey || !projectId) {
63
+ console.warn('[TestChimp] Missing TESTCHIMP_API_KEY or TESTCHIMP_PROJECT_ID. Reporting disabled.');
64
+ this.isEnabled = false;
65
+ return;
66
+ }
67
+ this.apiClient = new api_client_1.TestChimpApiClient(apiUrl, apiKey, projectId, this.options.verbose);
68
+ this.isEnabled = true;
69
+ if (this.options.verbose) {
70
+ console.log(`[TestChimp] Reporter initialized. Batch ID: ${this.batchInvocationId}`);
71
+ console.log(`[TestChimp] Tests folder: ${this.testsFolder || '(root)'}`);
72
+ }
73
+ // Scan suite to understand retry configuration
74
+ this.scanTestRetries(suite);
75
+ }
76
+ onTestBegin(test, result) {
77
+ if (!this.isEnabled)
78
+ return;
79
+ const testKey = this.getTestKey(test, result.retry);
80
+ this.testExecutions.set(testKey, {
81
+ testCase: test,
82
+ steps: [],
83
+ startedAt: Date.now(),
84
+ attemptNumber: result.retry + 1
85
+ });
86
+ // Update retry tracking
87
+ const retryKey = test.id;
88
+ const retryInfo = this.testRetryInfo.get(retryKey);
89
+ if (retryInfo) {
90
+ retryInfo.currentAttempt = result.retry;
91
+ }
92
+ if (this.options.verbose) {
93
+ console.log(`[TestChimp] Test started: ${test.title} (attempt ${result.retry + 1})`);
94
+ }
95
+ }
96
+ onStepEnd(test, result, step) {
97
+ if (!this.isEnabled)
98
+ return;
99
+ const testKey = this.getTestKey(test, result.retry);
100
+ const execution = this.testExecutions.get(testKey);
101
+ if (!execution)
102
+ return;
103
+ // Only capture test.step category (user-defined steps), not internal hooks
104
+ // Also capture 'expect' category for assertions
105
+ if (step.category !== 'test.step' && step.category !== 'expect') {
106
+ return;
107
+ }
108
+ const stepNumber = execution.steps.length + 1;
109
+ const stepId = (0, utils_1.generateStepId)(stepNumber);
110
+ const executionStep = {
111
+ stepId,
112
+ description: step.title,
113
+ status: step.error
114
+ ? types_1.StepExecutionStatus.FAILURE_STEP_EXECUTION
115
+ : types_1.StepExecutionStatus.SUCCESS_STEP_EXECUTION,
116
+ error: step.error?.message,
117
+ wasRepaired: false
118
+ };
119
+ execution.steps.push(executionStep);
120
+ if (this.options.verbose && step.error) {
121
+ console.log(`[TestChimp] Step failed: ${step.title}`);
122
+ }
123
+ }
124
+ async onTestEnd(test, result) {
125
+ if (!this.isEnabled || !this.apiClient)
126
+ return;
127
+ const testKey = this.getTestKey(test, result.retry);
128
+ const execution = this.testExecutions.get(testKey);
129
+ if (!execution)
130
+ return;
131
+ // Check if this is the final attempt (for retry handling)
132
+ const retryKey = test.id;
133
+ const retryInfo = this.testRetryInfo.get(retryKey);
134
+ const isFinalAttempt = !retryInfo || result.retry >= retryInfo.maxRetries;
135
+ // Skip non-final attempts if configured
136
+ if (this.options.reportOnlyFinalAttempt && !isFinalAttempt) {
137
+ if (this.options.verbose) {
138
+ console.log(`[TestChimp] Skipping non-final attempt ${result.retry + 1} for: ${test.title}`);
139
+ }
140
+ this.testExecutions.delete(testKey);
141
+ return;
142
+ }
143
+ // Build the report
144
+ const report = this.buildReport(test, result, execution);
145
+ try {
146
+ const response = await this.apiClient.ingestExecutionReport(report);
147
+ if (this.options.verbose) {
148
+ console.log(`[TestChimp] Reported: ${test.title} (jobId: ${response.jobId}, testFound: ${response.testFound})`);
149
+ if (response.scenariosPopulated && response.scenariosPopulated > 0) {
150
+ console.log(`[TestChimp] Auto-populated ${response.scenariosPopulated} scenario(s)`);
151
+ }
152
+ }
153
+ }
154
+ catch (error) {
155
+ console.error(`[TestChimp] Failed to report test: ${test.title}`, error);
156
+ }
157
+ // Cleanup
158
+ this.testExecutions.delete(testKey);
159
+ }
160
+ async onEnd(result) {
161
+ if (this.options.verbose) {
162
+ console.log(`[TestChimp] Test run completed. Status: ${result.status}`);
163
+ console.log(`[TestChimp] Batch invocation ID: ${this.batchInvocationId}`);
164
+ }
165
+ }
166
+ // ============================================================================
167
+ // Private helpers
168
+ // ============================================================================
169
+ getTestKey(test, retry) {
170
+ return `${test.id}_attempt_${retry}`;
171
+ }
172
+ scanTestRetries(suite) {
173
+ const scanSuite = (s) => {
174
+ for (const test of s.tests) {
175
+ this.testRetryInfo.set(test.id, {
176
+ maxRetries: test.retries,
177
+ currentAttempt: 0
178
+ });
179
+ }
180
+ for (const child of s.suites) {
181
+ scanSuite(child);
182
+ }
183
+ };
184
+ scanSuite(suite);
185
+ if (this.options.verbose) {
186
+ console.log(`[TestChimp] Scanned ${this.testRetryInfo.size} test(s)`);
187
+ }
188
+ }
189
+ buildReport(test, result, execution) {
190
+ // Derive paths from test location
191
+ const paths = (0, utils_1.derivePaths)(test, this.testsFolder, this.config.rootDir);
192
+ // Map Playwright status to SmartTestExecutionStatus
193
+ const status = this.mapStatus(result.status);
194
+ // Attach screenshots to failing steps only
195
+ if (this.options.captureScreenshots) {
196
+ this.attachScreenshotsToFailingSteps(execution.steps, result.attachments);
197
+ }
198
+ return {
199
+ folderPath: paths.folderPath,
200
+ fileName: paths.fileName,
201
+ suitePath: paths.suitePath,
202
+ testName: paths.testName,
203
+ release: this.options.release || undefined,
204
+ environment: this.options.environment || undefined,
205
+ batchInvocationId: this.batchInvocationId,
206
+ jobDetail: {
207
+ testName: paths.testName,
208
+ steps: execution.steps,
209
+ status,
210
+ error: result.error?.message,
211
+ scenarioCoverageResults: [] // Backend will populate if empty
212
+ },
213
+ startedAtMillis: execution.startedAt,
214
+ completedAtMillis: Date.now()
215
+ };
216
+ }
217
+ mapStatus(playwrightStatus) {
218
+ switch (playwrightStatus) {
219
+ case 'passed':
220
+ return types_1.SmartTestExecutionStatus.SMART_TEST_EXECUTION_COMPLETED;
221
+ case 'failed':
222
+ case 'timedOut':
223
+ return types_1.SmartTestExecutionStatus.SMART_TEST_EXECUTION_FAILED;
224
+ case 'skipped':
225
+ case 'interrupted':
226
+ default:
227
+ return types_1.SmartTestExecutionStatus.UNKNOWN_SMART_TEST_EXECUTION_STATUS;
228
+ }
229
+ }
230
+ /**
231
+ * Attach screenshots as base64 to failing steps only
232
+ */
233
+ attachScreenshotsToFailingSteps(steps, attachments) {
234
+ // Filter for image attachments with paths
235
+ const screenshots = attachments.filter((a) => a.contentType?.startsWith('image/') && a.path);
236
+ if (screenshots.length === 0)
237
+ return;
238
+ // Find failing steps
239
+ const failingSteps = steps.filter((s) => s.status === types_1.StepExecutionStatus.FAILURE_STEP_EXECUTION && !s.screenshotBase64);
240
+ if (failingSteps.length === 0)
241
+ return;
242
+ // Attach screenshots to failing steps
243
+ for (let i = 0; i < Math.min(screenshots.length, failingSteps.length); i++) {
244
+ const screenshot = screenshots[i];
245
+ const step = failingSteps[i];
246
+ if (screenshot.path) {
247
+ try {
248
+ const imageBuffer = fs_1.default.readFileSync(screenshot.path);
249
+ step.screenshotBase64 = imageBuffer.toString('base64');
250
+ if (this.options.verbose) {
251
+ console.log(`[TestChimp] Attached screenshot to failing step: ${step.description}`);
252
+ }
253
+ }
254
+ catch (error) {
255
+ if (this.options.verbose) {
256
+ console.warn(`[TestChimp] Failed to read screenshot: ${screenshot.path}`, error);
257
+ }
258
+ }
259
+ }
260
+ }
261
+ }
262
+ }
263
+ exports.TestChimpReporter = TestChimpReporter;
264
+ //# sourceMappingURL=testchimp-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testchimp-reporter.js","sourceRoot":"","sources":["../src/testchimp-reporter.ts"],"names":[],"mappings":";;;;;;AASA,4CAAoB;AAEpB,6CAAkD;AAClD,mCAMiB;AACjB,mCAA+E;AAoB/E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,iBAAiB;IAgB5B,YAAY,UAAoC,EAAE;QAb1C,cAAS,GAA8B,IAAI,CAAC;QAC5C,sBAAiB,GAAW,EAAE,CAAC;QAC/B,gBAAW,GAAW,EAAE,CAAC;QAEjC,qDAAqD;QAC7C,mBAAc,GAAoC,IAAI,GAAG,EAAE,CAAC;QAEpE,0DAA0D;QAClD,kBAAa,GAA2B,IAAI,GAAG,EAAE,CAAC;QAE1D,sDAAsD;QAC9C,cAAS,GAAY,KAAK,CAAC;QAGjC,IAAI,CAAC,OAAO,GAAG;YACb,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;YAClC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;YACtC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;YACtC,sBAAsB,EAAE,OAAO,CAAC,sBAAsB,IAAI,IAAI;YAC9D,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,IAAI;YACtD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;SAClC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,MAAkB,EAAE,KAAY;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,iBAAiB,GAAG,IAAA,oBAAY,GAAE,CAAC;QAExC,oEAAoE;QACpE,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,qCAAqC,CAAC;QAC5G,MAAM,SAAS,GAAG,IAAA,iBAAS,EAAC,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5E,IAAI,CAAC,WAAW,GAAG,IAAA,iBAAS,EAAC,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC;QAE5F,6DAA6D;QAC7D,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAA,iBAAS,EAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClF,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAA,iBAAS,EAAC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAEtF,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAC;YACnG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,+BAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;YACrF,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,WAAW,IAAI,QAAQ,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,+CAA+C;QAC/C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,WAAW,CAAC,IAAc,EAAE,MAAkB;QAC5C,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAEpD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE;YAC/B,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,aAAa,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC;SAChC,CAAC,CAAC;QAEH,wBAAwB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1C,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,KAAK,aAAa,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,SAAS,CAAC,IAAc,EAAE,MAAkB,EAAE,IAAc;QAC1D,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,2EAA2E;QAC3E,gDAAgD;QAChD,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChE,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAA,sBAAc,EAAC,UAAU,CAAC,CAAC;QAE1C,MAAM,aAAa,GAA2B;YAC5C,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,KAAK;YACvB,MAAM,EAAE,IAAI,CAAC,KAAK;gBAChB,CAAC,CAAC,2BAAmB,CAAC,sBAAsB;gBAC5C,CAAC,CAAC,2BAAmB,CAAC,sBAAsB;YAC9C,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO;YAC1B,WAAW,EAAE,KAAK;SACnB,CAAC;QAEF,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAc,EAAE,MAAkB;QAChD,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAE/C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,0DAA0D;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,cAAc,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,UAAU,CAAC;QAE1E,wCAAwC;QACxC,IAAI,IAAI,CAAC,OAAO,CAAC,sBAAsB,IAAI,CAAC,cAAc,EAAE,CAAC;YAC3D,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,0CAA0C,MAAM,CAAC,KAAK,GAAG,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC/F,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,mBAAmB;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAEpE,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,KAAK,YAAY,QAAQ,CAAC,KAAK,gBAAgB,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;gBAChH,IAAI,QAAQ,CAAC,kBAAkB,IAAI,QAAQ,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;oBACnE,OAAO,CAAC,GAAG,CAAC,8BAA8B,QAAQ,CAAC,kBAAkB,cAAc,CAAC,CAAC;gBACvF,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;QAED,UAAU;QACV,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAkB;QAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,2CAA2C,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,kBAAkB;IAClB,+EAA+E;IAEvE,UAAU,CAAC,IAAc,EAAE,KAAa;QAC9C,OAAO,GAAG,IAAI,CAAC,EAAE,YAAY,KAAK,EAAE,CAAC;IACvC,CAAC;IAEO,eAAe,CAAC,KAAY;QAClC,MAAM,SAAS,GAAG,CAAC,CAAQ,EAAE,EAAE;YAC7B,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE;oBAC9B,UAAU,EAAE,IAAI,CAAC,OAAO;oBACxB,cAAc,EAAE,CAAC;iBAClB,CAAC,CAAC;YACL,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBAC7B,SAAS,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC;QACF,SAAS,CAAC,KAAK,CAAC,CAAC;QAEjB,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAEO,WAAW,CACjB,IAAc,EACd,MAAkB,EAClB,SAA6B;QAE7B,kCAAkC;QAClC,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEvE,oDAAoD;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE7C,2CAA2C;QAC3C,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;YACpC,IAAI,CAAC,+BAA+B,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO;YACL,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,SAAS;YAC1C,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS;YAClD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,SAAS,EAAE;gBACT,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,MAAM;gBACN,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO;gBAC5B,uBAAuB,EAAE,EAAE,CAAC,iCAAiC;aAC9D;YACD,eAAe,EAAE,SAAS,CAAC,SAAS;YACpC,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE;SAC9B,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,gBAAwB;QACxC,QAAQ,gBAAgB,EAAE,CAAC;YACzB,KAAK,QAAQ;gBACX,OAAO,gCAAwB,CAAC,8BAA8B,CAAC;YACjE,KAAK,QAAQ,CAAC;YACd,KAAK,UAAU;gBACb,OAAO,gCAAwB,CAAC,2BAA2B,CAAC;YAC9D,KAAK,SAAS,CAAC;YACf,KAAK,aAAa,CAAC;YACnB;gBACE,OAAO,gCAAwB,CAAC,mCAAmC,CAAC;QACxE,CAAC;IACH,CAAC;IAED;;OAEG;IACK,+BAA+B,CACrC,KAA+B,EAC/B,WAAsC;QAEtC,0CAA0C;QAC1C,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CACrD,CAAC;QAEF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAErC,qBAAqB;QACrB,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,2BAAmB,CAAC,sBAAsB,IAAI,CAAC,CAAC,CAAC,gBAAgB,CACtF,CAAC;QAEF,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEtC,sCAAsC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3E,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAE7B,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,YAAE,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBACrD,IAAI,CAAC,gBAAgB,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBAEvD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,oDAAoD,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;oBACtF,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;wBACzB,OAAO,CAAC,IAAI,CAAC,0CAA0C,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;oBACnF,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAhSD,8CAgSC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Type definitions for the TestChimp Playwright reporter
3
+ * Uses camelCase for TypeScript interfaces
4
+ */
5
+ export declare enum SmartTestExecutionStatus {
6
+ UNKNOWN_SMART_TEST_EXECUTION_STATUS = 0,
7
+ SMART_TEST_EXECUTION_QUEUED = 1,
8
+ SMART_TEST_EXECUTION_IN_PROGRESS = 2,
9
+ SMART_TEST_EXECUTION_COMPLETED = 3,
10
+ SMART_TEST_EXECUTION_FAILED = 4,
11
+ SMART_TEST_EXECUTION_COMPLETED_WITH_REPAIRS = 5
12
+ }
13
+ export declare enum StepExecutionStatus {
14
+ UNKNOWN_STEP_EXECUTION_STATUS = 0,
15
+ SUCCESS_STEP_EXECUTION = 1,
16
+ FAILURE_STEP_EXECUTION = 2
17
+ }
18
+ export declare enum ScenarioCoverageStatus {
19
+ UNKNOWN_SCENARIO_COVERAGE_STATUS = 0,
20
+ SUCCESSFUL_SCENARIO_COVERAGE = 1,
21
+ FAILED_SCENARIO_COVERAGE = 2,
22
+ NOT_ATTEMPTED_SCENARIO_COVERAGE = 3
23
+ }
24
+ export interface SmartTestExecutionStep {
25
+ stepId?: string;
26
+ description: string;
27
+ code?: string;
28
+ screenshotBase64?: string;
29
+ status: StepExecutionStatus;
30
+ error?: string;
31
+ wasRepaired?: boolean;
32
+ }
33
+ export interface ScenarioCoverageResult {
34
+ scenarioTitle: string;
35
+ scenarioId?: string;
36
+ status: ScenarioCoverageStatus;
37
+ }
38
+ export interface SmartTestExecutionJobDetail {
39
+ testName: string;
40
+ steps: SmartTestExecutionStep[];
41
+ status: SmartTestExecutionStatus;
42
+ error?: string;
43
+ updatedScript?: string;
44
+ scenarioCoverageResults: ScenarioCoverageResult[];
45
+ }
46
+ export interface SmartTestExecutionReport {
47
+ folderPath: string;
48
+ fileName: string;
49
+ suitePath: string[];
50
+ testName: string;
51
+ release?: string;
52
+ environment?: string;
53
+ batchInvocationId?: string;
54
+ jobDetail: SmartTestExecutionJobDetail;
55
+ startedAtMillis?: number;
56
+ completedAtMillis?: number;
57
+ }
58
+ export interface IngestSmartTestExecutionReportRequest {
59
+ report: SmartTestExecutionReport;
60
+ }
61
+ export interface IngestSmartTestExecutionReportResponse {
62
+ jobId: string;
63
+ testId?: string;
64
+ testFound: boolean;
65
+ scenariosPopulated?: number;
66
+ }
67
+ /**
68
+ * Reporter configuration options
69
+ */
70
+ export interface TestChimpReporterOptions {
71
+ /** Override TESTCHIMP_API_KEY env var */
72
+ apiKey?: string;
73
+ /** Override TESTCHIMP_API_URL env var (default: https://featureservice.testchimp.io) */
74
+ apiUrl?: string;
75
+ /** Override TESTCHIMP_PROJECT_ID env var */
76
+ projectId?: string;
77
+ /** Override TESTCHIMP_TESTS_FOLDER env var - base folder for relative path calculation */
78
+ testsFolder?: string;
79
+ /** Override TESTCHIMP_RELEASE env var */
80
+ release?: string;
81
+ /** Override TESTCHIMP_ENV env var */
82
+ environment?: string;
83
+ /** Only report final retry attempt (default: true) */
84
+ reportOnlyFinalAttempt?: boolean;
85
+ /** Capture screenshots for failing steps (default: true) */
86
+ captureScreenshots?: boolean;
87
+ /** Enable verbose logging (default: false) */
88
+ verbose?: boolean;
89
+ }
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAY,wBAAwB;IAClC,mCAAmC,IAAI;IACvC,2BAA2B,IAAI;IAC/B,gCAAgC,IAAI;IACpC,8BAA8B,IAAI;IAClC,2BAA2B,IAAI;IAC/B,2CAA2C,IAAI;CAChD;AAED,oBAAY,mBAAmB;IAC7B,6BAA6B,IAAI;IACjC,sBAAsB,IAAI;IAC1B,sBAAsB,IAAI;CAC3B;AAED,oBAAY,sBAAsB;IAChC,gCAAgC,IAAI;IACpC,4BAA4B,IAAI;IAChC,wBAAwB,IAAI;IAC5B,+BAA+B,IAAI;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,MAAM,EAAE,wBAAwB,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,sBAAsB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,2BAA2B,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,qCAAqC;IACpD,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,MAAM,WAAW,sCAAsC;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
package/dist/types.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /**
3
+ * Type definitions for the TestChimp Playwright reporter
4
+ * Uses camelCase for TypeScript interfaces
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ScenarioCoverageStatus = exports.StepExecutionStatus = exports.SmartTestExecutionStatus = void 0;
8
+ var SmartTestExecutionStatus;
9
+ (function (SmartTestExecutionStatus) {
10
+ SmartTestExecutionStatus[SmartTestExecutionStatus["UNKNOWN_SMART_TEST_EXECUTION_STATUS"] = 0] = "UNKNOWN_SMART_TEST_EXECUTION_STATUS";
11
+ SmartTestExecutionStatus[SmartTestExecutionStatus["SMART_TEST_EXECUTION_QUEUED"] = 1] = "SMART_TEST_EXECUTION_QUEUED";
12
+ SmartTestExecutionStatus[SmartTestExecutionStatus["SMART_TEST_EXECUTION_IN_PROGRESS"] = 2] = "SMART_TEST_EXECUTION_IN_PROGRESS";
13
+ SmartTestExecutionStatus[SmartTestExecutionStatus["SMART_TEST_EXECUTION_COMPLETED"] = 3] = "SMART_TEST_EXECUTION_COMPLETED";
14
+ SmartTestExecutionStatus[SmartTestExecutionStatus["SMART_TEST_EXECUTION_FAILED"] = 4] = "SMART_TEST_EXECUTION_FAILED";
15
+ SmartTestExecutionStatus[SmartTestExecutionStatus["SMART_TEST_EXECUTION_COMPLETED_WITH_REPAIRS"] = 5] = "SMART_TEST_EXECUTION_COMPLETED_WITH_REPAIRS";
16
+ })(SmartTestExecutionStatus || (exports.SmartTestExecutionStatus = SmartTestExecutionStatus = {}));
17
+ var StepExecutionStatus;
18
+ (function (StepExecutionStatus) {
19
+ StepExecutionStatus[StepExecutionStatus["UNKNOWN_STEP_EXECUTION_STATUS"] = 0] = "UNKNOWN_STEP_EXECUTION_STATUS";
20
+ StepExecutionStatus[StepExecutionStatus["SUCCESS_STEP_EXECUTION"] = 1] = "SUCCESS_STEP_EXECUTION";
21
+ StepExecutionStatus[StepExecutionStatus["FAILURE_STEP_EXECUTION"] = 2] = "FAILURE_STEP_EXECUTION";
22
+ })(StepExecutionStatus || (exports.StepExecutionStatus = StepExecutionStatus = {}));
23
+ var ScenarioCoverageStatus;
24
+ (function (ScenarioCoverageStatus) {
25
+ ScenarioCoverageStatus[ScenarioCoverageStatus["UNKNOWN_SCENARIO_COVERAGE_STATUS"] = 0] = "UNKNOWN_SCENARIO_COVERAGE_STATUS";
26
+ ScenarioCoverageStatus[ScenarioCoverageStatus["SUCCESSFUL_SCENARIO_COVERAGE"] = 1] = "SUCCESSFUL_SCENARIO_COVERAGE";
27
+ ScenarioCoverageStatus[ScenarioCoverageStatus["FAILED_SCENARIO_COVERAGE"] = 2] = "FAILED_SCENARIO_COVERAGE";
28
+ ScenarioCoverageStatus[ScenarioCoverageStatus["NOT_ATTEMPTED_SCENARIO_COVERAGE"] = 3] = "NOT_ATTEMPTED_SCENARIO_COVERAGE";
29
+ })(ScenarioCoverageStatus || (exports.ScenarioCoverageStatus = ScenarioCoverageStatus = {}));
30
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,IAAY,wBAOX;AAPD,WAAY,wBAAwB;IAClC,qIAAuC,CAAA;IACvC,qHAA+B,CAAA;IAC/B,+HAAoC,CAAA;IACpC,2HAAkC,CAAA;IAClC,qHAA+B,CAAA;IAC/B,qJAA+C,CAAA;AACjD,CAAC,EAPW,wBAAwB,wCAAxB,wBAAwB,QAOnC;AAED,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,+GAAiC,CAAA;IACjC,iGAA0B,CAAA;IAC1B,iGAA0B,CAAA;AAC5B,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B;AAED,IAAY,sBAKX;AALD,WAAY,sBAAsB;IAChC,2HAAoC,CAAA;IACpC,mHAAgC,CAAA;IAChC,2GAA4B,CAAA;IAC5B,yHAAmC,CAAA;AACrC,CAAC,EALW,sBAAsB,sCAAtB,sBAAsB,QAKjC"}
@@ -0,0 +1,33 @@
1
+ import type { TestCase } from '@playwright/test/reporter';
2
+ /**
3
+ * Derived path components for test identification
4
+ */
5
+ export interface DerivedPaths {
6
+ folderPath: string;
7
+ fileName: string;
8
+ suitePath: string[];
9
+ testName: string;
10
+ }
11
+ /**
12
+ * Derive path components from a Playwright TestCase
13
+ *
14
+ * @param test The Playwright TestCase
15
+ * @param testsFolder Base folder for relative path calculation (optional)
16
+ * @param rootDir Playwright root directory
17
+ * @returns Derived path components for test identification
18
+ */
19
+ export declare function derivePaths(test: TestCase, testsFolder: string, rootDir: string): DerivedPaths;
20
+ /**
21
+ * Generate a simple unique ID for steps
22
+ */
23
+ export declare function generateStepId(stepNumber: number): string;
24
+ /**
25
+ * Safely get an environment variable with optional default
26
+ */
27
+ export declare function getEnvVar(name: string, defaultValue?: string): string | undefined;
28
+ /**
29
+ * Generate a UUID v4
30
+ * Simple implementation without external dependency
31
+ */
32
+ export declare function generateUUID(): string;
33
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAS,MAAM,2BAA2B,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,YAAY,CAoCd;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjF;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
package/dist/utils.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.derivePaths = derivePaths;
7
+ exports.generateStepId = generateStepId;
8
+ exports.getEnvVar = getEnvVar;
9
+ exports.generateUUID = generateUUID;
10
+ const path_1 = __importDefault(require("path"));
11
+ /**
12
+ * Derive path components from a Playwright TestCase
13
+ *
14
+ * @param test The Playwright TestCase
15
+ * @param testsFolder Base folder for relative path calculation (optional)
16
+ * @param rootDir Playwright root directory
17
+ * @returns Derived path components for test identification
18
+ */
19
+ function derivePaths(test, testsFolder, rootDir) {
20
+ // Get the file path relative to testsFolder (or rootDir if not specified)
21
+ const basePath = testsFolder ? path_1.default.resolve(rootDir, testsFolder) : rootDir;
22
+ const absolutePath = test.location.file;
23
+ const relativePath = path_1.default.relative(basePath, absolutePath);
24
+ const folderPath = path_1.default.dirname(relativePath);
25
+ const fileName = path_1.default.basename(relativePath);
26
+ // Build suite path from parent suites (describe blocks)
27
+ // Walk up the parent chain, collecting suite titles
28
+ const suitePath = [];
29
+ let parent = test.parent;
30
+ while (parent) {
31
+ // Skip if title is empty or matches the file name (file-level suite)
32
+ if (parent.title &&
33
+ !parent.title.endsWith('.spec.ts') &&
34
+ !parent.title.endsWith('.test.ts') &&
35
+ !parent.title.endsWith('.spec.js') &&
36
+ !parent.title.endsWith('.test.js')) {
37
+ // Only add non-file-level, non-project-level suites
38
+ // Project suites have no parent with a title
39
+ if (parent.parent) {
40
+ suitePath.unshift(parent.title);
41
+ }
42
+ }
43
+ parent = parent.parent;
44
+ }
45
+ return {
46
+ folderPath: folderPath === '.' ? '' : folderPath,
47
+ fileName,
48
+ suitePath,
49
+ testName: test.title
50
+ };
51
+ }
52
+ /**
53
+ * Generate a simple unique ID for steps
54
+ */
55
+ function generateStepId(stepNumber) {
56
+ return `step_${stepNumber}_${Date.now()}`;
57
+ }
58
+ /**
59
+ * Safely get an environment variable with optional default
60
+ */
61
+ function getEnvVar(name, defaultValue) {
62
+ return process.env[name] || defaultValue;
63
+ }
64
+ /**
65
+ * Generate a UUID v4
66
+ * Simple implementation without external dependency
67
+ */
68
+ function generateUUID() {
69
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
70
+ const r = (Math.random() * 16) | 0;
71
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
72
+ return v.toString(16);
73
+ });
74
+ }
75
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;AAqBA,kCAwCC;AAKD,wCAEC;AAKD,8BAEC;AAMD,oCAMC;AAvFD,gDAAwB;AAaxB;;;;;;;GAOG;AACH,SAAgB,WAAW,CACzB,IAAc,EACd,WAAmB,EACnB,OAAe;IAEf,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,cAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IACxC,MAAM,YAAY,GAAG,cAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAE3D,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE7C,wDAAwD;IACxD,oDAAoD;IACpD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,MAAM,GAAsB,IAAI,CAAC,MAAM,CAAC;IAE5C,OAAO,MAAM,EAAE,CAAC;QACd,qEAAqE;QACrE,IAAI,MAAM,CAAC,KAAK;YACZ,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,oDAAoD;YACpD,6CAA6C;YAC7C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,OAAO;QACL,UAAU,EAAE,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU;QAChD,QAAQ;QACR,SAAS;QACT,QAAQ,EAAE,IAAI,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,UAAkB;IAC/C,OAAO,QAAQ,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,IAAY,EAAE,YAAqB;IAC3D,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY;IAC1B,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "playwright-testchimp-reporter",
3
+ "version": "0.0.1",
4
+ "description": "Playwright reporter for TestChimp test execution tracking and coverage reporting",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist/"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "watch": "tsc --watch",
13
+ "clean": "rm -rf dist"
14
+ },
15
+ "peerDependencies": {
16
+ "@playwright/test": ">=1.40.0"
17
+ },
18
+ "dependencies": {
19
+ "axios": "^1.6.0"
20
+ },
21
+ "devDependencies": {
22
+ "@playwright/test": "^1.40.0",
23
+ "@types/node": "^20.10.0",
24
+ "typescript": "^5.3.0"
25
+ },
26
+ "keywords": [
27
+ "testchimp",
28
+ "playwright",
29
+ "reporter",
30
+ "test-automation",
31
+ "coverage"
32
+ ],
33
+ "author": "TestChimp",
34
+ "license": "MIT"
35
+ }