testlens-playwright-reporter 0.1.9 → 0.2.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.
Files changed (4) hide show
  1. package/index.js +57 -39
  2. package/index.ts +57 -39
  3. package/lib/index.js +56 -39
  4. package/package.json +1 -1
package/index.js CHANGED
@@ -179,36 +179,47 @@ class TestLensReporter {
179
179
  });
180
180
  }
181
181
 
182
- // Create test data
183
- const testData = {
184
- id: this.getTestId(test),
185
- name: test.title,
186
- status: 'passed',
187
- originalStatus: 'passed',
188
- duration: 0,
189
- startTime: new Date().toISOString(),
190
- endTime: '',
191
- errorMessages: [],
192
- retryAttempts: test.retries,
193
- currentRetry: result.retry,
194
- annotations: test.annotations.map(ann => ({
195
- type: ann.type,
196
- description: ann.description
197
- })),
198
- projectName: test.parent.project()?.name || 'default',
199
- workerIndex: result.workerIndex,
200
- parallelIndex: result.parallelIndex
201
- };
182
+ const testId = this.getTestId(test);
183
+
184
+ // Only send testStart event on first attempt (retry 0)
185
+ if (result.retry === 0) {
186
+ // Create test data
187
+ const testData = {
188
+ id: testId,
189
+ name: test.title,
190
+ status: 'passed',
191
+ originalStatus: 'passed',
192
+ duration: 0,
193
+ startTime: new Date().toISOString(),
194
+ endTime: '',
195
+ errorMessages: [],
196
+ retryAttempts: test.retries,
197
+ currentRetry: result.retry,
198
+ annotations: test.annotations.map(ann => ({
199
+ type: ann.type,
200
+ description: ann.description
201
+ })),
202
+ projectName: test.parent.project()?.name || 'default',
203
+ workerIndex: result.workerIndex,
204
+ parallelIndex: result.parallelIndex
205
+ };
202
206
 
203
- this.testMap.set(testData.id, testData);
207
+ this.testMap.set(testData.id, testData);
204
208
 
205
- // Send test start event to API
206
- await this.sendToApi({
207
- type: 'testStart',
208
- runId: this.runId,
209
- timestamp: new Date().toISOString(),
210
- test: testData
211
- });
209
+ // Send test start event to API
210
+ await this.sendToApi({
211
+ type: 'testStart',
212
+ runId: this.runId,
213
+ timestamp: new Date().toISOString(),
214
+ test: testData
215
+ });
216
+ } else {
217
+ // For retries, just update the existing test data
218
+ const existingTestData = this.testMap.get(testId);
219
+ if (existingTestData) {
220
+ existingTestData.currentRetry = result.retry;
221
+ }
222
+ }
212
223
  }
213
224
 
214
225
  async onTestEnd(test, result) {
@@ -216,24 +227,31 @@ class TestLensReporter {
216
227
  const testData = this.testMap.get(testId);
217
228
 
218
229
  if (testData) {
219
- // Preserve original status for detailed reporting, but normalize for consistency
230
+ // Update test data with latest result
220
231
  testData.originalStatus = result.status;
221
232
  testData.status = this.normalizeTestStatus(result.status);
222
233
  testData.duration = result.duration;
223
234
  testData.endTime = new Date().toISOString();
224
235
  testData.errorMessages = result.errors.map(error => error.message || error.toString());
236
+ testData.currentRetry = result.retry;
225
237
 
226
- // Send test end event to API
227
- await this.sendToApi({
228
- type: 'testEnd',
229
- runId: this.runId,
230
- timestamp: new Date().toISOString(),
231
- test: testData
232
- });
238
+ // Only send testEnd event after final retry attempt
239
+ // If test passed or this is the last retry, send the event
240
+ const isFinalAttempt = result.status === 'passed' || result.status === 'skipped' || result.retry >= test.retries;
241
+
242
+ if (isFinalAttempt) {
243
+ // Send test end event to API
244
+ await this.sendToApi({
245
+ type: 'testEnd',
246
+ runId: this.runId,
247
+ timestamp: new Date().toISOString(),
248
+ test: testData
249
+ });
233
250
 
234
- // Handle artifacts
235
- if (this.config.enableArtifacts) {
236
- await this.processArtifacts(testId, result);
251
+ // Handle artifacts
252
+ if (this.config.enableArtifacts) {
253
+ await this.processArtifacts(testId, result);
254
+ }
237
255
  }
238
256
  }
239
257
 
package/index.ts CHANGED
@@ -308,36 +308,47 @@ export class TestLensReporter implements Reporter {
308
308
  });
309
309
  }
310
310
 
311
- // Create test data
312
- const testData: TestData = {
313
- id: this.getTestId(test),
314
- name: test.title,
315
- status: 'passed',
316
- originalStatus: 'passed',
317
- duration: 0,
318
- startTime: new Date().toISOString(),
319
- endTime: '',
320
- errorMessages: [],
321
- retryAttempts: test.retries,
322
- currentRetry: result.retry,
323
- annotations: test.annotations.map((ann: any) => ({
324
- type: ann.type,
325
- description: ann.description
326
- })),
327
- projectName: test.parent.project()?.name || 'default',
328
- workerIndex: result.workerIndex,
329
- parallelIndex: result.parallelIndex
330
- };
311
+ const testId = this.getTestId(test);
312
+
313
+ // Only send testStart event on first attempt (retry 0)
314
+ if (result.retry === 0) {
315
+ // Create test data
316
+ const testData: TestData = {
317
+ id: testId,
318
+ name: test.title,
319
+ status: 'passed',
320
+ originalStatus: 'passed',
321
+ duration: 0,
322
+ startTime: new Date().toISOString(),
323
+ endTime: '',
324
+ errorMessages: [],
325
+ retryAttempts: test.retries,
326
+ currentRetry: result.retry,
327
+ annotations: test.annotations.map((ann: any) => ({
328
+ type: ann.type,
329
+ description: ann.description
330
+ })),
331
+ projectName: test.parent.project()?.name || 'default',
332
+ workerIndex: result.workerIndex,
333
+ parallelIndex: result.parallelIndex
334
+ };
331
335
 
332
- this.testMap.set(testData.id, testData);
336
+ this.testMap.set(testData.id, testData);
333
337
 
334
- // Send test start event to API
335
- await this.sendToApi({
336
- type: 'testStart',
337
- runId: this.runId,
338
- timestamp: new Date().toISOString(),
339
- test: testData
340
- });
338
+ // Send test start event to API
339
+ await this.sendToApi({
340
+ type: 'testStart',
341
+ runId: this.runId,
342
+ timestamp: new Date().toISOString(),
343
+ test: testData
344
+ });
345
+ } else {
346
+ // For retries, just update the existing test data
347
+ const existingTestData = this.testMap.get(testId);
348
+ if (existingTestData) {
349
+ existingTestData.currentRetry = result.retry;
350
+ }
351
+ }
341
352
  }
342
353
 
343
354
  async onTestEnd(test: TestCase, result: TestResult): Promise<void> {
@@ -345,24 +356,31 @@ export class TestLensReporter implements Reporter {
345
356
  const testData = this.testMap.get(testId);
346
357
 
347
358
  if (testData) {
348
- // Preserve original status for detailed reporting, but normalize for consistency
359
+ // Update test data with latest result
349
360
  testData.originalStatus = result.status;
350
361
  testData.status = this.normalizeTestStatus(result.status);
351
362
  testData.duration = result.duration;
352
363
  testData.endTime = new Date().toISOString();
353
364
  testData.errorMessages = result.errors.map((error: any) => error.message || error.toString());
365
+ testData.currentRetry = result.retry;
354
366
 
355
- // Send test end event to API
356
- await this.sendToApi({
357
- type: 'testEnd',
358
- runId: this.runId,
359
- timestamp: new Date().toISOString(),
360
- test: testData
361
- });
367
+ // Only send testEnd event after final retry attempt
368
+ // If test passed or this is the last retry, send the event
369
+ const isFinalAttempt = result.status === 'passed' || result.status === 'skipped' || result.retry >= test.retries;
370
+
371
+ if (isFinalAttempt) {
372
+ // Send test end event to API
373
+ await this.sendToApi({
374
+ type: 'testEnd',
375
+ runId: this.runId,
376
+ timestamp: new Date().toISOString(),
377
+ test: testData
378
+ });
362
379
 
363
- // Handle artifacts
364
- if (this.config.enableArtifacts) {
365
- await this.processArtifacts(testId, result);
380
+ // Handle artifacts
381
+ if (this.config.enableArtifacts) {
382
+ await this.processArtifacts(testId, result);
383
+ }
366
384
  }
367
385
  }
368
386
 
package/lib/index.js CHANGED
@@ -196,55 +196,72 @@ class TestLensReporter {
196
196
  spec: specData
197
197
  });
198
198
  }
199
- // Create test data
200
- const testData = {
201
- id: this.getTestId(test),
202
- name: test.title,
203
- status: 'passed',
204
- originalStatus: 'passed',
205
- duration: 0,
206
- startTime: new Date().toISOString(),
207
- endTime: '',
208
- errorMessages: [],
209
- retryAttempts: test.retries,
210
- currentRetry: result.retry,
211
- annotations: test.annotations.map((ann) => ({
212
- type: ann.type,
213
- description: ann.description
214
- })),
215
- projectName: test.parent.project()?.name || 'default',
216
- workerIndex: result.workerIndex,
217
- parallelIndex: result.parallelIndex
218
- };
219
- this.testMap.set(testData.id, testData);
220
- // Send test start event to API
221
- await this.sendToApi({
222
- type: 'testStart',
223
- runId: this.runId,
224
- timestamp: new Date().toISOString(),
225
- test: testData
226
- });
199
+ const testId = this.getTestId(test);
200
+ // Only send testStart event on first attempt (retry 0)
201
+ if (result.retry === 0) {
202
+ // Create test data
203
+ const testData = {
204
+ id: testId,
205
+ name: test.title,
206
+ status: 'passed',
207
+ originalStatus: 'passed',
208
+ duration: 0,
209
+ startTime: new Date().toISOString(),
210
+ endTime: '',
211
+ errorMessages: [],
212
+ retryAttempts: test.retries,
213
+ currentRetry: result.retry,
214
+ annotations: test.annotations.map((ann) => ({
215
+ type: ann.type,
216
+ description: ann.description
217
+ })),
218
+ projectName: test.parent.project()?.name || 'default',
219
+ workerIndex: result.workerIndex,
220
+ parallelIndex: result.parallelIndex
221
+ };
222
+ this.testMap.set(testData.id, testData);
223
+ // Send test start event to API
224
+ await this.sendToApi({
225
+ type: 'testStart',
226
+ runId: this.runId,
227
+ timestamp: new Date().toISOString(),
228
+ test: testData
229
+ });
230
+ }
231
+ else {
232
+ // For retries, just update the existing test data
233
+ const existingTestData = this.testMap.get(testId);
234
+ if (existingTestData) {
235
+ existingTestData.currentRetry = result.retry;
236
+ }
237
+ }
227
238
  }
228
239
  async onTestEnd(test, result) {
229
240
  const testId = this.getTestId(test);
230
241
  const testData = this.testMap.get(testId);
231
242
  if (testData) {
232
- // Preserve original status for detailed reporting, but normalize for consistency
243
+ // Update test data with latest result
233
244
  testData.originalStatus = result.status;
234
245
  testData.status = this.normalizeTestStatus(result.status);
235
246
  testData.duration = result.duration;
236
247
  testData.endTime = new Date().toISOString();
237
248
  testData.errorMessages = result.errors.map((error) => error.message || error.toString());
238
- // Send test end event to API
239
- await this.sendToApi({
240
- type: 'testEnd',
241
- runId: this.runId,
242
- timestamp: new Date().toISOString(),
243
- test: testData
244
- });
245
- // Handle artifacts
246
- if (this.config.enableArtifacts) {
247
- await this.processArtifacts(testId, result);
249
+ testData.currentRetry = result.retry;
250
+ // Only send testEnd event after final retry attempt
251
+ // If test passed or this is the last retry, send the event
252
+ const isFinalAttempt = result.status === 'passed' || result.status === 'skipped' || result.retry >= test.retries;
253
+ if (isFinalAttempt) {
254
+ // Send test end event to API
255
+ await this.sendToApi({
256
+ type: 'testEnd',
257
+ runId: this.runId,
258
+ timestamp: new Date().toISOString(),
259
+ test: testData
260
+ });
261
+ // Handle artifacts
262
+ if (this.config.enableArtifacts) {
263
+ await this.processArtifacts(testId, result);
264
+ }
248
265
  }
249
266
  }
250
267
  // Update spec status
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testlens-playwright-reporter",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "description": "Universal Playwright reporter for TestLens - works with both TypeScript and JavaScript projects",
5
5
  "main": "lib/index.js",
6
6
  "types": "index.d.ts",