@alternative-path/testlens-playwright-reporter 0.4.8 → 0.4.9
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/README.md +83 -0
- package/index.d.ts +5 -0
- package/index.js +33 -3
- package/index.ts +1750 -1714
- package/package.json +75 -75
package/README.md
CHANGED
|
@@ -126,6 +126,88 @@ The reporter automatically reads these environment variables (no config changes
|
|
|
126
126
|
- **API Key**: `TESTLENS_API_KEY` (also checks: `testlens_api_key`, `TESTLENS_KEY`, `testlensApiKey`, `PLAYWRIGHT_API_KEY`, `PW_API_KEY`)
|
|
127
127
|
- **Build Name**: `testlensBuildName` (also checks: `TESTLENS_BUILD_NAME`, `BUILDNAME`, `BUILD_NAME`)
|
|
128
128
|
- **Build Tag**: `testlensBuildTag` (also checks: `TESTLENS_BUILD_TAG`, `BUILDTAG`, `BUILD_TAG`)
|
|
129
|
+
- **Execution ID** (one run per pipeline): see [One test run per pipeline execution](#one-test-run-per-pipeline-execution) below.
|
|
130
|
+
|
|
131
|
+
### One test run per pipeline execution
|
|
132
|
+
|
|
133
|
+
If your pipeline runs `npx playwright test` in **multiple steps**, you get one TestLens run per step. To group all steps into **one** run, set **`TESTLENS_EXECUTION_ID`** to your pipeline’s run identifier (e.g. build number or run ID) in every step. Use one of the three methods below. For per-CI examples (Bitbucket, GitHub, GitLab, Azure DevOps, Jenkins), see **[PIPELINE_EXECUTION_ID.md](./PIPELINE_EXECUTION_ID.md)**.
|
|
134
|
+
|
|
135
|
+
#### 1. Environment variable (recommended in CI)
|
|
136
|
+
|
|
137
|
+
Set one of these env vars **before** each Playwright step. The reporter uses the **first one it finds** (in this order):
|
|
138
|
+
|
|
139
|
+
| Env var | When to use |
|
|
140
|
+
|---------|--------------|
|
|
141
|
+
| `TESTLENS_EXECUTION_ID` | Any pipeline; set this to your build/run ID |
|
|
142
|
+
| `TestlensExecutionId`, `TestLensExecutionId`, `testlensexecutionid` | Alternative spellings |
|
|
143
|
+
| `BITBUCKET_BUILD_UUID` | Bitbucket Pipelines (auto-set; no config needed) |
|
|
144
|
+
| `GITHUB_RUN_ID` | GitHub Actions (auto-set) |
|
|
145
|
+
| `CI_PIPELINE_ID`, `CI_JOB_ID` | GitLab CI |
|
|
146
|
+
| `BUILD_BUILDID`, `SYSTEM_JOBID` | Azure DevOps |
|
|
147
|
+
| `BUILD_ID`, `BUILD_NUMBER` | Jenkins |
|
|
148
|
+
| `CIRCLE_WORKFLOW_ID`, `CIRCLE_BUILD_NUM` | CircleCI |
|
|
149
|
+
|
|
150
|
+
**Command examples:**
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Linux / macOS
|
|
154
|
+
export TESTLENS_EXECUTION_ID="${BITBUCKET_BUILD_UUID}"
|
|
155
|
+
npx playwright test
|
|
156
|
+
|
|
157
|
+
# Or inline
|
|
158
|
+
TESTLENS_EXECUTION_ID="my-build-123" npx playwright test
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
# Windows PowerShell
|
|
163
|
+
$env:TESTLENS_EXECUTION_ID = $env:BITBUCKET_BUILD_UUID
|
|
164
|
+
npx playwright test
|
|
165
|
+
|
|
166
|
+
# Or inline
|
|
167
|
+
$env:TESTLENS_EXECUTION_ID="my-build-123"; npx playwright test
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```cmd
|
|
171
|
+
REM Windows CMD
|
|
172
|
+
set TESTLENS_EXECUTION_ID=my-build-123 && npx playwright test
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### 2. Config option `executionId`
|
|
176
|
+
|
|
177
|
+
In your Playwright config, set the top-level reporter option:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// playwright.config.ts
|
|
181
|
+
reporter: [
|
|
182
|
+
['@alternative-path/testlens-playwright-reporter', {
|
|
183
|
+
apiKey: process.env.TESTLENS_API_KEY,
|
|
184
|
+
executionId: process.env.BITBUCKET_BUILD_UUID, // or any string
|
|
185
|
+
}]
|
|
186
|
+
],
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### 3. Config option `customMetadata`
|
|
190
|
+
|
|
191
|
+
You can pass the execution ID inside `customMetadata` (as `executionId` or `TESTLENS_EXECUTION_ID`):
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// playwright.config.ts
|
|
195
|
+
reporter: [
|
|
196
|
+
['@alternative-path/testlens-playwright-reporter', {
|
|
197
|
+
apiKey: process.env.TESTLENS_API_KEY,
|
|
198
|
+
customMetadata: {
|
|
199
|
+
executionId: process.env.BITBUCKET_BUILD_UUID,
|
|
200
|
+
// or: TESTLENS_EXECUTION_ID: process.env.BITBUCKET_BUILD_UUID,
|
|
201
|
+
testlensBuildName: 'Build123',
|
|
202
|
+
testlensBuildTag: 'smoke',
|
|
203
|
+
},
|
|
204
|
+
}]
|
|
205
|
+
],
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### Recommendation
|
|
209
|
+
|
|
210
|
+
Prefer a **UUID or globally unique ID** (e.g. `BITBUCKET_BUILD_UUID`, `GITHUB_RUN_ID`) so different repos or pipelines never share the same run. Build numbers like `BUILD_NUMBER` reset per repo and can collide. See **[PIPELINE_EXECUTION_ID.md](./PIPELINE_EXECUTION_ID.md)** for per-CI examples.
|
|
129
211
|
|
|
130
212
|
### Notes
|
|
131
213
|
|
|
@@ -140,6 +222,7 @@ The reporter automatically reads these environment variables (no config changes
|
|
|
140
222
|
| Option | Type | Default | Description |
|
|
141
223
|
|--------|------|---------|-------------|
|
|
142
224
|
| `apiKey` | `string` | **Required** | Your TestLens API key |
|
|
225
|
+
| `executionId` | `string` | — | Optional. When set (or use env `TESTLENS_EXECUTION_ID`, any auto-detected CI run ID, or `customMetadata.executionId` / `customMetadata.TESTLENS_EXECUTION_ID`), used as run ID so multiple pipeline steps share one run. See [PIPELINE_EXECUTION_ID.md](./PIPELINE_EXECUTION_ID.md). |
|
|
143
226
|
|
|
144
227
|
## Artifacts
|
|
145
228
|
|
package/index.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export interface TestLensReporterConfig {
|
|
|
28
28
|
ignoreSslErrors?: boolean;
|
|
29
29
|
/** Custom metadata from CLI arguments (automatically parsed from --key=value arguments) */
|
|
30
30
|
customMetadata?: Record<string, string | string[]>;
|
|
31
|
+
/** Execution ID for one run per pipeline (e.g. from TESTLENS_EXECUTION_ID or CI build UUID). When set, used as runId so multiple steps share one run. */
|
|
32
|
+
executionId?: string;
|
|
31
33
|
}
|
|
32
34
|
export interface TestLensReporterOptions {
|
|
33
35
|
/** TestLens API endpoint URL */
|
|
@@ -58,6 +60,8 @@ export interface TestLensReporterOptions {
|
|
|
58
60
|
ignoreSslErrors?: boolean;
|
|
59
61
|
/** Custom metadata from CLI arguments (automatically parsed from --key=value arguments) */
|
|
60
62
|
customMetadata?: Record<string, string | string[]>;
|
|
63
|
+
/** Execution ID for one run per pipeline (e.g. from TESTLENS_EXECUTION_ID or CI build UUID). When set, used as runId so multiple steps share one run. */
|
|
64
|
+
executionId?: string;
|
|
61
65
|
}
|
|
62
66
|
export interface GitInfo {
|
|
63
67
|
branch: string;
|
|
@@ -157,6 +161,7 @@ export declare class TestLensReporter implements Reporter {
|
|
|
157
161
|
private axiosInstance;
|
|
158
162
|
private runId;
|
|
159
163
|
private runMetadata;
|
|
164
|
+
private usedExecutionId;
|
|
160
165
|
private specMap;
|
|
161
166
|
private testMap;
|
|
162
167
|
private runCreationFailed;
|
package/index.js
CHANGED
|
@@ -91,6 +91,23 @@ class TestLensReporter {
|
|
|
91
91
|
// Support both TestLens-specific names (recommended) and common CI names
|
|
92
92
|
'testlensBuildTag': ['testlensBuildTag', 'TESTLENS_BUILD_TAG', 'TESTLENS_BUILDTAG', 'BUILDTAG', 'BUILD_TAG', 'TestlensBuildTag', 'TestLensBuildTag'],
|
|
93
93
|
'testlensBuildName': ['testlensBuildName', 'TESTLENS_BUILD_NAME', 'TESTLENS_BUILDNAME', 'BUILDNAME', 'BUILD_NAME', 'TestlensBuildName', 'TestLensBuildName'],
|
|
94
|
+
// Execution ID for one run per pipeline (checked in order; prefer TESTLENS_EXECUTION_ID, then CI-specific UUIDs)
|
|
95
|
+
'executionId': [
|
|
96
|
+
'TESTLENS_EXECUTION_ID',
|
|
97
|
+
'TestlensExecutionId',
|
|
98
|
+
'TestLensExecutionId',
|
|
99
|
+
'testlensexecutionid',
|
|
100
|
+
'BITBUCKET_BUILD_UUID',
|
|
101
|
+
'GITHUB_RUN_ID',
|
|
102
|
+
'CI_PIPELINE_ID',
|
|
103
|
+
'CI_JOB_ID',
|
|
104
|
+
'BUILD_BUILDID',
|
|
105
|
+
'SYSTEM_JOBID',
|
|
106
|
+
'BUILD_ID',
|
|
107
|
+
'BUILD_NUMBER',
|
|
108
|
+
'CIRCLE_WORKFLOW_ID',
|
|
109
|
+
'CIRCLE_BUILD_NUM'
|
|
110
|
+
],
|
|
94
111
|
'environment': ['ENVIRONMENT', 'ENV', 'NODE_ENV', 'DEPLOYMENT_ENV'],
|
|
95
112
|
'branch': ['BRANCH', 'GIT_BRANCH', 'CI_COMMIT_BRANCH', 'GITHUB_REF_NAME'],
|
|
96
113
|
'team': ['TEAM', 'TEAM_NAME'],
|
|
@@ -118,6 +135,7 @@ class TestLensReporter {
|
|
|
118
135
|
return customArgs;
|
|
119
136
|
}
|
|
120
137
|
constructor(options) {
|
|
138
|
+
this.usedExecutionId = false; // True when runId came from executionId (multi-step); backend should aggregate runEnd
|
|
121
139
|
this.runCreationFailed = false; // Track if run creation failed due to limits
|
|
122
140
|
this.cliArgs = {}; // Store CLI args separately
|
|
123
141
|
this.pendingUploads = new Set(); // Track pending artifact uploads
|
|
@@ -157,7 +175,8 @@ class TestLensReporter {
|
|
|
157
175
|
timeout: options.timeout || 60000,
|
|
158
176
|
rejectUnauthorized: options.rejectUnauthorized,
|
|
159
177
|
ignoreSslErrors: options.ignoreSslErrors,
|
|
160
|
-
customMetadata: { ...options.customMetadata, ...customArgs } // Config metadata first, then CLI args override
|
|
178
|
+
customMetadata: { ...options.customMetadata, ...customArgs }, // Config metadata first, then CLI args override
|
|
179
|
+
executionId: options.executionId
|
|
161
180
|
};
|
|
162
181
|
if (!this.config.apiKey) {
|
|
163
182
|
throw new Error('API_KEY is required for TestLensReporter. Pass it as apiKey option in your playwright config or set one of these environment variables: TESTLENS_API_KEY, TESTLENS_KEY, PLAYWRIGHT_API_KEY, PW_API_KEY, API_KEY, or APIKEY.');
|
|
@@ -223,7 +242,17 @@ class TestLensReporter {
|
|
|
223
242
|
}
|
|
224
243
|
return Promise.reject(error);
|
|
225
244
|
});
|
|
226
|
-
this.
|
|
245
|
+
const executionIdFromCustomMetadata = this.config.customMetadata?.executionId ?? this.config.customMetadata?.TESTLENS_EXECUTION_ID;
|
|
246
|
+
const executionIdFromCustomMetadataStr = Array.isArray(executionIdFromCustomMetadata)
|
|
247
|
+
? executionIdFromCustomMetadata[0]
|
|
248
|
+
: executionIdFromCustomMetadata;
|
|
249
|
+
const executionIdRaw = options.executionId ??
|
|
250
|
+
process.env.TESTLENS_EXECUTION_ID ??
|
|
251
|
+
customArgs.executionId ??
|
|
252
|
+
executionIdFromCustomMetadataStr;
|
|
253
|
+
const executionId = typeof executionIdRaw === 'string' && executionIdRaw.trim() ? String(executionIdRaw).trim() : undefined;
|
|
254
|
+
this.runId = executionId || (0, crypto_1.randomUUID)();
|
|
255
|
+
this.usedExecutionId = !!executionId;
|
|
227
256
|
this.runMetadata = this.initializeRunMetadata();
|
|
228
257
|
this.specMap = new Map();
|
|
229
258
|
this.testMap = new Map();
|
|
@@ -713,7 +742,8 @@ class TestLensReporter {
|
|
|
713
742
|
failedTests, // Already includes timedOut tests (normalized to 'failed')
|
|
714
743
|
skippedTests,
|
|
715
744
|
timedOutTests, // For informational purposes
|
|
716
|
-
status: normalizedRunStatus
|
|
745
|
+
status: normalizedRunStatus,
|
|
746
|
+
aggregationMode: this.usedExecutionId ? 'append' : 'replace'
|
|
717
747
|
}
|
|
718
748
|
});
|
|
719
749
|
// Show Build Name if provided, otherwise show Run ID
|