playwright-testchimp 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 +21 -0
- package/README.md +171 -0
- package/dist/api-client.d.ts +51 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +282 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/reporter.d.ts +7 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +26 -0
- package/dist/reporter.js.map +1 -0
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +93 -0
- package/dist/runtime.js.map +1 -0
- package/dist/testchimp-reporter.d.ts +82 -0
- package/dist/testchimp-reporter.d.ts.map +1 -0
- package/dist/testchimp-reporter.js +777 -0
- package/dist/testchimp-reporter.js.map +1 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +30 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +93 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +305 -0
- package/dist/utils.js.map +1 -0
- package/dist/worldstate.d.ts +15 -0
- package/dist/worldstate.d.ts.map +1 -0
- package/dist/worldstate.js +136 -0
- package/dist/worldstate.js.map +1 -0
- package/package.json +58 -0
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,171 @@
|
|
|
1
|
+
# playwright-testchimp
|
|
2
|
+
|
|
3
|
+
A [Playwright](https://playwright.dev/) reporter that sends test execution results to the [TestChimp](https://testchimp.io) platform. It powers **QA intelligence insights**, surfaces **AI-native steps** (e.g. `ai.act`, `ai.verify`) from the standard Playwright runner into TestChimp for CI, and **augments RUM events** from [testchimp-rum-js](https://www.npmjs.com/package/testchimp-rum-js) so test runs align with real user events for **TrueCoverage**.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
### 1. Report execution results to TestChimp for QA intelligence
|
|
10
|
+
|
|
11
|
+
The reporter collects test runs (pass/fail, steps, errors, timing) and sends them to the TestChimp backend. TestChimp uses this data to:
|
|
12
|
+
|
|
13
|
+
- Track which tests ran, when, and their outcome
|
|
14
|
+
- Drive dashboards, trends, and QA intelligence
|
|
15
|
+
- Correlate failures with steps and screenshots for faster debugging
|
|
16
|
+
- Support traceability between tests, scenarios, and coverage
|
|
17
|
+
|
|
18
|
+
You run tests with the normal Playwright CLI or via your CI (GitHub Actions etc.); the reporter runs in process and posts results to TestChimp without changing how you execute tests.
|
|
19
|
+
|
|
20
|
+
### 2. Pipe AI-native steps through TestChimp so they work wherever you run tests
|
|
21
|
+
|
|
22
|
+
The reporter plugin pipes AI-native step calls (`ai.act`, `ai.verify`, etc.) via TestChimp backends, so that those steps work seamlessly—wherever you run your tests (local, CI, or any environment).
|
|
23
|
+
|
|
24
|
+
### 3. Augment testchimp-rum-js events for TrueCoverage (test ↔ real user alignment)
|
|
25
|
+
|
|
26
|
+
[testchimp-rum-js](https://www.npmjs.com/package/testchimp-rum-js) emits real user events from the browser to TestChimp. When the same app is exercised **in CI by Playwright**, you want those events to be tagged with **which test** produced them so TestChimp can:
|
|
27
|
+
|
|
28
|
+
- Align test runs with real user sessions (TrueCoverage)
|
|
29
|
+
- See which tests generated which events
|
|
30
|
+
- Compare test coverage to production usage to drive better QA strategy.
|
|
31
|
+
|
|
32
|
+
Read more about TestChimps' TrueCoverage feature [here](https://docs.testchimp.io/truecoverage/intro).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install playwright-testchimp
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Peer dependency: `@playwright/test` (e.g. `>=1.40.0`).
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
### 1. Playwright config
|
|
49
|
+
|
|
50
|
+
Configure the reporter in your playwright.config.js like below:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// playwright.config.ts
|
|
54
|
+
import { defineConfig } from '@playwright/test';
|
|
55
|
+
|
|
56
|
+
// Optional: import runtime so CI test info is injected for testchimp-rum-js (TrueCoverage)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
reporter: [
|
|
61
|
+
['list'],
|
|
62
|
+
['playwright-testchimp/reporter', {
|
|
63
|
+
verbose: true,
|
|
64
|
+
reportOnlyFinalAttempt: true,
|
|
65
|
+
captureScreenshots: true,
|
|
66
|
+
}],
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For TrueCoverage, add the following import in your tests:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
import 'playwright-testchimp/runtime';
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. Environment variables
|
|
78
|
+
|
|
79
|
+
Set these so the reporter can talk to TestChimp (env vars override programmatic options):
|
|
80
|
+
|
|
81
|
+
| Variable | Required | Description |
|
|
82
|
+
|----------|----------|-------------|
|
|
83
|
+
| `TESTCHIMP_API_KEY` | Yes | API key for TestChimp. |
|
|
84
|
+
| `TESTCHIMP_PROJECT_ID` | No | Legacy/optional; the backend resolves the project from the API key when omitted. |
|
|
85
|
+
| `TESTCHIMP_TESTS_FOLDER` | No | Base folder for relative paths (default: `tests`). |
|
|
86
|
+
| `TESTCHIMP_RELEASE` | No | Release/version identifier. |
|
|
87
|
+
| `TESTCHIMP_ENV` | No | Environment (e.g. `staging`, `prod`). |
|
|
88
|
+
|
|
89
|
+
If `TESTCHIMP_API_KEY` is missing, the reporter logs a warning and disables reporting (no request is sent).
|
|
90
|
+
|
|
91
|
+
### 3. Run tests
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
export TESTCHIMP_API_KEY=your-api-key
|
|
95
|
+
npx playwright test
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Results are reported to TestChimp after each test (or after the final attempt when using retries and `reportOnlyFinalAttempt: true`).
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Reporter options
|
|
103
|
+
|
|
104
|
+
You can pass options in `playwright.config.ts`:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
['playwright-testchimp/reporter', {
|
|
108
|
+
apiKey: '...', // override env (not recommended in CI)
|
|
109
|
+
backendUrl: '...', // override TESTCHIMP_BACKEND_URL
|
|
110
|
+
projectId: '...', // optional override env
|
|
111
|
+
testsFolder: 'tests', // base dir for relative path calculation
|
|
112
|
+
release: '1.0.0',
|
|
113
|
+
environment: 'staging',
|
|
114
|
+
reportOnlyFinalAttempt: true, // only send report for last retry (default: true)
|
|
115
|
+
captureScreenshots: true, // attach screenshots to failing steps (default: true)
|
|
116
|
+
verbose: false, // extra logging (default: false)
|
|
117
|
+
}]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Environment variables take precedence over these options.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## What gets reported
|
|
125
|
+
|
|
126
|
+
For each test (or its final attempt when using retries), the reporter sends a **Smart Test Execution Report** that includes:
|
|
127
|
+
|
|
128
|
+
- **Identity**: `folderPath`, `fileName`, `suitePath`, `testName` (derived from test file and describe blocks).
|
|
129
|
+
- **Run context**: `batchInvocationId`, `branchName` (from env when available), `release`, `environment`.
|
|
130
|
+
- **Job detail**:
|
|
131
|
+
- **Steps**: Every Playwright step with category `test.step`, `expect`, or `pw:api` (including AI-native steps).
|
|
132
|
+
- **Status**: Completed, Failed, or Unknown (mapped from Playwright status).
|
|
133
|
+
- **Error**: Top-level test error message if failed.
|
|
134
|
+
- **Screenshots**: For failing steps, when `captureScreenshots` is true and Playwright has attached screenshots (e.g. `screenshot: 'only-on-failure'`).
|
|
135
|
+
|
|
136
|
+
Retries are tracked; with `reportOnlyFinalAttempt: true` only the last attempt is reported.
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Exports
|
|
142
|
+
|
|
143
|
+
- **Subpath**: `playwright-testchimp/reporter` — explicit reporter entry for Playwright `reporter` config.
|
|
144
|
+
- **Named**: `TestChimpReporter`, `TestChimpApiClient`, and types/utilities from `./types` and `./utils`.
|
|
145
|
+
- **Subpath**: `playwright-testchimp/runtime` — side-effect import only; registers `test.beforeEach` to inject CI test info.
|
|
146
|
+
- **Subpath**: `playwright-testchimp/worldstate` — exports `defineWorldState` and `ensureWorldState` for world-state setup/teardown in tests.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Troubleshooting
|
|
151
|
+
|
|
152
|
+
- **“Reporting disabled”**
|
|
153
|
+
Set `TESTCHIMP_API_KEY` (or pass it in reporter options). `TESTCHIMP_PROJECT_ID` should be present to enable TrueCoverage.
|
|
154
|
+
|
|
155
|
+
- **No steps or only some steps**
|
|
156
|
+
Only steps with category `test.step`, `expect`, or `pw:api` are reported. Internal/hook steps are excluded.
|
|
157
|
+
|
|
158
|
+
- **No screenshots on failure**
|
|
159
|
+
Enable screenshot capture in Playwright (e.g. `use: { screenshot: 'only-on-failure' }`). The reporter only attaches existing attachments to failing steps.
|
|
160
|
+
|
|
161
|
+
- **RUM events not linked to tests**
|
|
162
|
+
Ensure you `import 'playwright-testchimp/runtime'` in the test files.
|
|
163
|
+
|
|
164
|
+
- **Verbose logging**
|
|
165
|
+
Set `verbose: true` in reporter options or use it during setup to see which steps are captured and when reports are sent.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
MIT.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { IngestSmartTestExecutionReportResponse, SmartTestExecutionReport, SmartTestExecutionJobDetail } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* HTTP client for communicating with the TestChimp backend API
|
|
4
|
+
*/
|
|
5
|
+
export declare class TestChimpApiClient {
|
|
6
|
+
private client;
|
|
7
|
+
private apiKey;
|
|
8
|
+
private projectId;
|
|
9
|
+
private verbose;
|
|
10
|
+
constructor(apiUrl: string, apiKey: string, projectId: string, verbose?: boolean);
|
|
11
|
+
/**
|
|
12
|
+
* Send a test execution report to the TestChimp backend
|
|
13
|
+
*/
|
|
14
|
+
ingestExecutionReport(report: SmartTestExecutionReport): Promise<IngestSmartTestExecutionReportResponse>;
|
|
15
|
+
/**
|
|
16
|
+
* Upload a single attachment (e.g. compressed screenshot) to the backend.
|
|
17
|
+
* Uses multipart/form-data and returns the parsed response (expects { gcpPath }).
|
|
18
|
+
*/
|
|
19
|
+
uploadAttachment(buffer: Buffer, contentType: string, options?: {
|
|
20
|
+
filename?: string;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
maxRetries?: number;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
gcpPath: string;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Platform mode: send full job detail on step end (blind upsert).
|
|
28
|
+
* POST {backend}/api/platform/step_end with jobId and jobDetail.
|
|
29
|
+
*/
|
|
30
|
+
platformStepEnd(jobId: string, jobDetail: SmartTestExecutionJobDetail): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Platform mode: send final job detail on test end (upsert + scenario coverage).
|
|
33
|
+
* POST {backend}/api/platform/test_end with jobId and jobDetail.
|
|
34
|
+
*/
|
|
35
|
+
platformTestEnd(jobId: string, jobDetail: SmartTestExecutionJobDetail): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Check if the client is properly configured
|
|
38
|
+
*/
|
|
39
|
+
isConfigured(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Repair mode: emit a single progress event (step-level).
|
|
42
|
+
* POST {backend}/api/platform/repair_step_end with { jobId, event }.
|
|
43
|
+
*/
|
|
44
|
+
repairStepEnd(jobId: string, event: Record<string, unknown>): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Repair mode: mark end of one healer run (can be emitted multiple times).
|
|
47
|
+
* POST {backend}/api/platform/repair_test_end with { jobId, summary }.
|
|
48
|
+
*/
|
|
49
|
+
repairTestEnd(jobId: string, summary: Record<string, unknown>): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
//# 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":"AAEA,OAAO,EACL,sCAAsC,EACtC,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AAkDjB;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,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;IAqBvF;;OAEG;IACG,qBAAqB,CACzB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,sCAAsC,CAAC;IA+ClD;;;OAGG;IACG,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GACvE,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAqD/B;;;OAGG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3F;;;OAGG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3F;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjF;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAapF"}
|
|
@@ -0,0 +1,282 @@
|
|
|
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.TestChimpApiClient = void 0;
|
|
40
|
+
const axios_1 = __importStar(require("axios"));
|
|
41
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
42
|
+
/**
|
|
43
|
+
* Convert camelCase keys to snake_case recursively
|
|
44
|
+
*/
|
|
45
|
+
function toSnakeCase(obj) {
|
|
46
|
+
if (obj === null || obj === undefined) {
|
|
47
|
+
return obj;
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(obj)) {
|
|
50
|
+
return obj.map(toSnakeCase);
|
|
51
|
+
}
|
|
52
|
+
if (typeof obj === 'object') {
|
|
53
|
+
const result = {};
|
|
54
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
55
|
+
const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
56
|
+
result[snakeKey] = toSnakeCase(value);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
return obj;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Convert snake_case keys to camelCase recursively
|
|
64
|
+
*/
|
|
65
|
+
function toCamelCase(obj) {
|
|
66
|
+
if (obj === null || obj === undefined) {
|
|
67
|
+
return obj;
|
|
68
|
+
}
|
|
69
|
+
if (Array.isArray(obj)) {
|
|
70
|
+
return obj.map(toCamelCase);
|
|
71
|
+
}
|
|
72
|
+
if (typeof obj === 'object') {
|
|
73
|
+
const result = {};
|
|
74
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
75
|
+
const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
76
|
+
result[camelKey] = toCamelCase(value);
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* HTTP client for communicating with the TestChimp backend API
|
|
84
|
+
*/
|
|
85
|
+
class TestChimpApiClient {
|
|
86
|
+
constructor(apiUrl, apiKey, projectId, verbose = false) {
|
|
87
|
+
this.apiKey = apiKey;
|
|
88
|
+
this.projectId = projectId;
|
|
89
|
+
this.verbose = verbose;
|
|
90
|
+
const headers = {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
'testchimp-api-key': apiKey
|
|
93
|
+
};
|
|
94
|
+
const trimmedProject = projectId?.trim();
|
|
95
|
+
if (trimmedProject) {
|
|
96
|
+
headers['project-id'] = trimmedProject;
|
|
97
|
+
}
|
|
98
|
+
this.client = axios_1.default.create({
|
|
99
|
+
baseURL: apiUrl,
|
|
100
|
+
headers,
|
|
101
|
+
timeout: 30000
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Send a test execution report to the TestChimp backend
|
|
106
|
+
*/
|
|
107
|
+
async ingestExecutionReport(report) {
|
|
108
|
+
// Convert camelCase to snake_case for the API
|
|
109
|
+
const snakeCaseReport = toSnakeCase({ report });
|
|
110
|
+
try {
|
|
111
|
+
// Always log when sending reports (not just when verbose)
|
|
112
|
+
console.log(`[TestChimp] Sending report for test: ${report.testName} (status: ${report.jobDetail?.status}, steps: ${report.jobDetail?.steps?.length || 0})`);
|
|
113
|
+
// Log screenshot details if verbose
|
|
114
|
+
if (this.verbose && report.jobDetail?.steps) {
|
|
115
|
+
const stepsWithScreenshots = report.jobDetail.steps.filter(s => s.screenshotBase64);
|
|
116
|
+
if (stepsWithScreenshots.length > 0) {
|
|
117
|
+
console.log(`[TestChimp] Including ${stepsWithScreenshots.length} step(s) with screenshots`);
|
|
118
|
+
stepsWithScreenshots.forEach((step, idx) => {
|
|
119
|
+
const screenshotSize = step.screenshotBase64?.length || 0;
|
|
120
|
+
console.log(`[TestChimp] Step ${idx + 1}: "${step.description}" - screenshot size: ${screenshotSize} bytes`);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
console.log(`[TestChimp] No screenshots attached to any steps`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const response = await this.client.post('/api/ingest_smarttest_execution_report', snakeCaseReport);
|
|
128
|
+
// Convert response from snake_case to camelCase
|
|
129
|
+
return toCamelCase(response.data);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (error instanceof axios_1.AxiosError) {
|
|
133
|
+
const status = error.response?.status;
|
|
134
|
+
const message = error.response?.data?.message || error.message;
|
|
135
|
+
console.error(`[TestChimp] API error (${status}): ${message}`);
|
|
136
|
+
if (status === 401 || status === 403) {
|
|
137
|
+
throw new Error(`[TestChimp] Authentication failed. Check TESTCHIMP_API_KEY (TESTCHIMP_PROJECT_ID is optional; the backend resolves the project from the API key).`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Upload a single attachment (e.g. compressed screenshot) to the backend.
|
|
145
|
+
* Uses multipart/form-data and returns the parsed response (expects { gcpPath }).
|
|
146
|
+
*/
|
|
147
|
+
async uploadAttachment(buffer, contentType, options) {
|
|
148
|
+
const filename = options?.filename || 'attachment.bin';
|
|
149
|
+
const timeoutMs = options?.timeoutMs ?? 120000;
|
|
150
|
+
const maxRetries = options?.maxRetries ?? 2;
|
|
151
|
+
let lastError = null;
|
|
152
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
153
|
+
try {
|
|
154
|
+
const form = new form_data_1.default();
|
|
155
|
+
// Filename is not used for storage (server generates ULID), but helps set content type.
|
|
156
|
+
form.append('file', buffer, {
|
|
157
|
+
filename,
|
|
158
|
+
contentType,
|
|
159
|
+
});
|
|
160
|
+
const response = await this.client.post('/api/upload_attachment', form, {
|
|
161
|
+
headers: {
|
|
162
|
+
// Let form-data set the correct multipart boundary & content type.
|
|
163
|
+
...form.getHeaders(),
|
|
164
|
+
},
|
|
165
|
+
timeout: timeoutMs
|
|
166
|
+
});
|
|
167
|
+
const data = response.data;
|
|
168
|
+
const gcpPath = data.gcpPath;
|
|
169
|
+
if (!gcpPath) {
|
|
170
|
+
console.error('[TestChimp] upload_attachment response missing gcpPath. Keys:', Object.keys(data || {}));
|
|
171
|
+
throw new Error('[TestChimp] upload_attachment response missing gcpPath');
|
|
172
|
+
}
|
|
173
|
+
return { gcpPath };
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
lastError = error;
|
|
177
|
+
if (error instanceof axios_1.AxiosError) {
|
|
178
|
+
const status = error.response?.status;
|
|
179
|
+
const message = error.response?.data?.message || error.message;
|
|
180
|
+
console.error(`[TestChimp] upload_attachment error (${status}) attempt=${attempt + 1}/${maxRetries + 1}: ${message}`);
|
|
181
|
+
const retriable = !status || status >= 500 || status === 408 || status === 429;
|
|
182
|
+
if (!retriable || attempt >= maxRetries) {
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (attempt >= maxRetries) {
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
// Exponential backoff: 300ms, 600ms, 1200ms
|
|
190
|
+
const sleepMs = 300 * Math.pow(2, attempt);
|
|
191
|
+
await new Promise((resolve) => setTimeout(resolve, sleepMs));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
throw lastError instanceof Error ? lastError : new Error('[TestChimp] upload_attachment failed');
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Platform mode: send full job detail on step end (blind upsert).
|
|
198
|
+
* POST {backend}/api/platform/step_end with jobId and jobDetail.
|
|
199
|
+
*/
|
|
200
|
+
async platformStepEnd(jobId, jobDetail) {
|
|
201
|
+
try {
|
|
202
|
+
const body = { jobId, jobDetail };
|
|
203
|
+
if (this.verbose) {
|
|
204
|
+
console.log(`[TestChimp] platform/step_end jobId=${jobId} steps=${jobDetail.steps?.length ?? 0} retryAttemptLogs=${jobDetail.retryAttemptLogs?.length ?? 0}`);
|
|
205
|
+
}
|
|
206
|
+
await this.client.post('/api/platform/step_end', body);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (error instanceof axios_1.AxiosError) {
|
|
210
|
+
const status = error.response?.status;
|
|
211
|
+
const message = error.response?.data?.message || error.message;
|
|
212
|
+
console.error(`[TestChimp] platform/step_end error (${status}): ${message}`);
|
|
213
|
+
}
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Platform mode: send final job detail on test end (upsert + scenario coverage).
|
|
219
|
+
* POST {backend}/api/platform/test_end with jobId and jobDetail.
|
|
220
|
+
*/
|
|
221
|
+
async platformTestEnd(jobId, jobDetail) {
|
|
222
|
+
try {
|
|
223
|
+
const body = { jobId, jobDetail };
|
|
224
|
+
if (this.verbose) {
|
|
225
|
+
console.log(`[TestChimp] platform/test_end jobId=${jobId} status=${jobDetail.status}`);
|
|
226
|
+
}
|
|
227
|
+
await this.client.post('/api/platform/test_end', body);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (error instanceof axios_1.AxiosError) {
|
|
231
|
+
const status = error.response?.status;
|
|
232
|
+
const message = error.response?.data?.message || error.message;
|
|
233
|
+
console.error(`[TestChimp] platform/test_end error (${status}): ${message}`);
|
|
234
|
+
}
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Check if the client is properly configured
|
|
240
|
+
*/
|
|
241
|
+
isConfigured() {
|
|
242
|
+
return !!this.apiKey?.trim();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Repair mode: emit a single progress event (step-level).
|
|
246
|
+
* POST {backend}/api/platform/repair_step_end with { jobId, event }.
|
|
247
|
+
*/
|
|
248
|
+
async repairStepEnd(jobId, event) {
|
|
249
|
+
try {
|
|
250
|
+
const body = { jobId, event };
|
|
251
|
+
await this.client.post('/api/platform/repair_step_end', body);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
if (error instanceof axios_1.AxiosError) {
|
|
255
|
+
const status = error.response?.status;
|
|
256
|
+
const message = error.response?.data?.message || error.message;
|
|
257
|
+
console.error(`[TestChimp] repair_step_end error (${status}): ${message}`);
|
|
258
|
+
}
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Repair mode: mark end of one healer run (can be emitted multiple times).
|
|
264
|
+
* POST {backend}/api/platform/repair_test_end with { jobId, summary }.
|
|
265
|
+
*/
|
|
266
|
+
async repairTestEnd(jobId, summary) {
|
|
267
|
+
try {
|
|
268
|
+
const body = { jobId, summary };
|
|
269
|
+
await this.client.post('/api/platform/repair_test_end', body);
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (error instanceof axios_1.AxiosError) {
|
|
273
|
+
const status = error.response?.status;
|
|
274
|
+
const message = error.response?.data?.message || error.message;
|
|
275
|
+
console.error(`[TestChimp] repair_test_end error (${status}): ${message}`);
|
|
276
|
+
}
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
exports.TestChimpApiClient = TestChimpApiClient;
|
|
282
|
+
//# 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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* playwright-testchimp
|
|
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 (optional): Project identifier; omit when using API-key–only auth
|
|
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
|
+
export * from './worldstate';
|
|
34
|
+
import { TestChimpReporter } from './testchimp-reporter';
|
|
35
|
+
export default TestChimpReporter;
|
|
36
|
+
//# 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;AACxB,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,eAAe,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* playwright-testchimp
|
|
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 (optional): Project identifier; omit when using API-key–only auth
|
|
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
|
+
__exportStar(require("./worldstate"), exports);
|
|
53
|
+
// Default export for Playwright reporter configuration
|
|
54
|
+
const testchimp_reporter_2 = require("./testchimp-reporter");
|
|
55
|
+
exports.default = testchimp_reporter_2.TestChimpReporter;
|
|
56
|
+
//# 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;AACxB,+CAA6B;AAE7B,uDAAuD;AACvD,6DAAyD;AACzD,kBAAe,sCAAiB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { TestChimpReporter } from './testchimp-reporter';
|
|
2
|
+
export { TestChimpApiClient } from './api-client';
|
|
3
|
+
export * from './types';
|
|
4
|
+
export * from './utils';
|
|
5
|
+
import { TestChimpReporter } from './testchimp-reporter';
|
|
6
|
+
export default TestChimpReporter;
|
|
7
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,eAAe,iBAAiB,CAAC"}
|