testlens-playwright-reporter 0.2.9 → 0.3.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/index.js CHANGED
@@ -46,15 +46,12 @@ class TestLensReporter {
46
46
  if (this.config.ignoreSslErrors) {
47
47
  // Explicit configuration option
48
48
  rejectUnauthorized = false;
49
- console.log('⚠️ SSL certificate validation disabled via ignoreSslErrors option');
50
49
  } else if (this.config.rejectUnauthorized === false) {
51
50
  // Explicit configuration option
52
51
  rejectUnauthorized = false;
53
- console.log('⚠️ SSL certificate validation disabled via rejectUnauthorized option');
54
52
  } else if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
55
53
  // Environment variable override
56
54
  rejectUnauthorized = false;
57
- console.log('⚠️ SSL certificate validation disabled via NODE_TLS_REJECT_UNAUTHORIZED environment variable');
58
55
  }
59
56
 
60
57
  // Set up axios instance with retry logic and enhanced SSL handling
@@ -144,18 +141,9 @@ class TestLensReporter {
144
141
  }
145
142
 
146
143
  async onBegin(config, suite) {
147
- console.log(`🚀 TestLens Reporter starting - Run ID: ${this.runId}`);
148
-
149
144
  // Collect Git information if enabled
150
145
  if (this.config.enableGitInfo) {
151
146
  this.runMetadata.gitInfo = await this.collectGitInfo();
152
- if (this.runMetadata.gitInfo) {
153
- console.log(`📦 Git info collected: branch=${this.runMetadata.gitInfo.branch}, commit=${this.runMetadata.gitInfo.shortCommit}, author=${this.runMetadata.gitInfo.author}`);
154
- } else {
155
- console.log(`⚠️ Git info collection returned null - not in a git repository or git not available`);
156
- }
157
- } else {
158
- console.log(`ℹ️ Git info collection disabled (enableGitInfo: false)`);
159
147
  }
160
148
 
161
149
  // Add shard information if available
@@ -252,11 +240,8 @@ class TestLensReporter {
252
240
  const testId = this.getTestId(test);
253
241
  let testData = this.testMap.get(testId);
254
242
 
255
- console.log(`[TestLens] onTestEnd called for test: ${test.title}, status: ${result.status}, testData exists: ${!!testData}`);
256
-
257
243
  // For skipped tests, onTestBegin might not be called, so we need to create the test data here
258
244
  if (!testData) {
259
- console.log(`[TestLens] Creating test data for skipped/uncreated test: ${test.title}`);
260
245
  // Create spec data if not exists (skipped tests might not have spec data either)
261
246
  const specPath = test.location.file;
262
247
  const specKey = `${specPath}-${test.parent.title}`;
@@ -422,7 +407,6 @@ class TestLensReporter {
422
407
  const isFinalAttempt = result.status === 'passed' || result.status === 'skipped' || result.retry >= test.retries;
423
408
 
424
409
  if (isFinalAttempt) {
425
- console.log(`[TestLens] Sending testEnd - testId: ${testData.id}, status: ${testData.status}, originalStatus: ${testData.originalStatus}`);
426
410
  // Send test end event to API
427
411
  await this.sendToApi({
428
412
  type: 'testEnd',
@@ -508,19 +492,16 @@ class TestLensReporter {
508
492
  });
509
493
 
510
494
  // Wait for background artifact processing to complete (up to 10 seconds)
511
- console.log('⏳ Waiting for background artifact processing to complete...');
512
495
  await new Promise(resolve => setTimeout(resolve, 10000));
513
-
514
- console.log(`📊 TestLens Report completed - Run ID: ${this.runId}`);
515
- console.log(`🎯 Results: ${passedTests} passed, ${failedTests} failed (${timedOutTests} timeouts), ${skippedTests} skipped`);
516
496
  }
517
497
 
518
498
  async sendToApi(payload) {
519
499
  try {
520
- const response = await this.axiosInstance.post('', payload);
521
- if (this.config.enableRealTimeStream) {
522
- console.log(`✅ Sent ${payload.type} event to TestLens`);
523
- }
500
+ const response = await this.axiosInstance.post('', payload, {
501
+ headers: {
502
+ 'X-API-Key': this.config.apiKey
503
+ }
504
+ });
524
505
  } catch (error) {
525
506
  console.error(`❌ Failed to send ${payload.type} event to TestLens:`, {
526
507
  message: error?.message || 'Unknown error',
@@ -534,19 +515,10 @@ class TestLensReporter {
534
515
 
535
516
  async processArtifacts(testId, result) {
536
517
  const attachments = result.attachments;
537
- console.log(`🔍 Processing artifacts for test ${testId}: ${attachments ? attachments.length : 0} attachments found`);
538
-
539
- if (attachments && attachments.length > 0) {
540
- console.log('📎 Attachment details:');
541
- attachments.forEach((attachment, index) => {
542
- console.log(` ${index + 1}. ${attachment.name} (${attachment.contentType}) - Path: ${attachment.path}`);
543
- });
544
- }
545
518
 
546
519
  // Process artifacts with controlled async handling to ensure uploads complete
547
520
  if (attachments && attachments.length > 0) {
548
521
  // Process all artifacts asynchronously but track completion
549
- console.log(`🔄 Processing ${attachments.length} artifacts asynchronously...`);
550
522
 
551
523
  // Use process.nextTick to defer processing to next event loop iteration
552
524
  process.nextTick(async () => {
@@ -560,18 +532,15 @@ class TestLensReporter {
560
532
 
561
533
  // Skip video if disabled in config
562
534
  if (isVideo && !this.config.enableVideo) {
563
- console.log(`⏭️ Skipping video artifact ${attachment.name} - video capture disabled in config`);
564
535
  continue;
565
536
  }
566
537
 
567
538
  // Skip screenshot if disabled in config
568
539
  if (isScreenshot && !this.config.enableScreenshot) {
569
- console.log(`⏭️ Skipping screenshot artifact ${attachment.name} - screenshot capture disabled in config`);
570
540
  continue;
571
541
  }
572
542
 
573
543
  try {
574
- console.log(`📤 Processing ${attachment.name} asynchronously...`);
575
544
 
576
545
  // Determine proper filename with extension
577
546
  // Playwright attachment.name often doesn't have extension, so we need to derive it
@@ -608,7 +577,6 @@ class TestLensReporter {
608
577
 
609
578
  // Skip if upload failed or file was too large
610
579
  if (!s3Data) {
611
- console.log(`⏭️ Skipping artifact ${attachment.name} - upload failed or file too large`);
612
580
  continue;
613
581
  }
614
582
 
@@ -631,8 +599,6 @@ class TestLensReporter {
631
599
  timestamp: new Date().toISOString(),
632
600
  artifact: artifactData
633
601
  });
634
-
635
- console.log(`📎 Processed artifact: ${fileName} (uploaded to S3)`);
636
602
  } catch (error) {
637
603
  console.error(`❌ Failed to process ${attachment.name}:`, error.message);
638
604
  }
@@ -665,8 +631,6 @@ class TestLensReporter {
665
631
  codeBlocks,
666
632
  testSuiteName: path.basename(specPath).replace(/\.(spec|test)\.(js|ts)$/, '')
667
633
  });
668
-
669
- console.log(`📝 Sent ${codeBlocks.length} code blocks for: ${path.basename(specPath)}`);
670
634
  } catch (error) {
671
635
  console.error('Failed to send spec code blocks:', error?.response?.data || error?.message || 'Unknown error');
672
636
  }
@@ -760,7 +724,6 @@ class TestLensReporter {
760
724
  }
761
725
  } catch (e) {
762
726
  // Remote info is optional - handle gracefully
763
- console.log('ℹ️ No git remote configured, skipping remote info');
764
727
  }
765
728
 
766
729
  const isDirty = execSync('git status --porcelain', { encoding: 'utf-8' }).trim().length > 0;
@@ -828,8 +791,6 @@ class TestLensReporter {
828
791
  // Check file size first
829
792
  const fileSize = this.getFileSize(filePath);
830
793
  const fileSizeMB = (fileSize / (1024 * 1024)).toFixed(2);
831
-
832
- console.log(`📤 Uploading ${fileName} (${fileSizeMB}MB) directly to S3...`);
833
794
 
834
795
  const baseUrl = this.config.apiEndpoint.replace('/api/v1/webhook/playwright', '');
835
796
 
@@ -854,8 +815,6 @@ class TestLensReporter {
854
815
  const { uploadUrl, s3Key, metadata } = presignedResponse.data;
855
816
 
856
817
  // Step 2: Upload directly to S3 using presigned URL
857
- console.log(`⬆️ Uploading ${fileName} directly to S3 (bypass server)...`);
858
-
859
818
  const fileBuffer = fs.readFileSync(filePath);
860
819
 
861
820
  // IMPORTANT: When using presigned URLs, we MUST include exactly the headers that were signed
@@ -867,7 +826,7 @@ class TestLensReporter {
867
826
  },
868
827
  maxContentLength: Infinity,
869
828
  maxBodyLength: Infinity,
870
- timeout: Math.max(300000, Math.ceil(fileSize / (1024 * 1024)) * 5000), // 5s per MB, min 5 minutes
829
+ timeout: Math.max(600000, Math.ceil(fileSize / (1024 * 1024)) * 10000), // 10s per MB, min 10 minutes - increased for large trace files
871
830
  // Don't use custom HTTPS agent for S3 uploads
872
831
  httpsAgent: undefined
873
832
  });
@@ -876,8 +835,6 @@ class TestLensReporter {
876
835
  throw new Error(`S3 upload failed with status ${uploadResponse.status}`);
877
836
  }
878
837
 
879
- console.log(`✅ S3 direct upload completed for ${fileName}`);
880
-
881
838
  // Step 3: Confirm upload with server to save metadata
882
839
  const confirmEndpoint = `${baseUrl}/api/v1/artifacts/public/confirm-upload`;
883
840
  const confirmResponse = await this.axiosInstance.post(confirmEndpoint, {
@@ -895,7 +852,6 @@ class TestLensReporter {
895
852
 
896
853
  if (confirmResponse.status === 201 && confirmResponse.data.success) {
897
854
  const artifact = confirmResponse.data.artifact;
898
- console.log(`✅ Upload confirmed and saved to database`);
899
855
  return {
900
856
  key: s3Key,
901
857
  url: artifact.s3Url,
package/index.ts CHANGED
@@ -673,7 +673,11 @@ export class TestLensReporter implements Reporter {
673
673
  private async sendToApi(payload: any): Promise<void> {
674
674
  try {
675
675
  console.log(`📤 Sending ${payload.type} event to ${this.config.apiEndpoint}`);
676
- const response = await this.axiosInstance.post('', payload);
676
+ const response = await this.axiosInstance.post('', payload, {
677
+ headers: {
678
+ 'X-API-Key': this.config.apiKey
679
+ }
680
+ });
677
681
  if (this.config.enableRealTimeStream) {
678
682
  console.log(`✅ Sent ${payload.type} event to TestLens (HTTP ${response.status})`);
679
683
  }
@@ -996,7 +1000,7 @@ export class TestLensReporter implements Reporter {
996
1000
  },
997
1001
  maxContentLength: Infinity,
998
1002
  maxBodyLength: Infinity,
999
- timeout: Math.max(300000, Math.ceil(fileSize / (1024 * 1024)) * 5000), // 5s per MB, min 5 minutes
1003
+ timeout: Math.max(600000, Math.ceil(fileSize / (1024 * 1024)) * 10000), // 10s per MB, min 10 minutes - increased for large trace files
1000
1004
  // Don't use custom HTTPS agent for S3 uploads
1001
1005
  httpsAgent: undefined
1002
1006
  });
package/lib/index.js CHANGED
@@ -493,7 +493,11 @@ class TestLensReporter {
493
493
  async sendToApi(payload) {
494
494
  try {
495
495
  console.log(`📤 Sending ${payload.type} event to ${this.config.apiEndpoint}`);
496
- const response = await this.axiosInstance.post('', payload);
496
+ const response = await this.axiosInstance.post('', payload, {
497
+ headers: {
498
+ 'X-API-Key': this.config.apiKey
499
+ }
500
+ });
497
501
  if (this.config.enableRealTimeStream) {
498
502
  console.log(`✅ Sent ${payload.type} event to TestLens (HTTP ${response.status})`);
499
503
  }
@@ -781,7 +785,7 @@ class TestLensReporter {
781
785
  },
782
786
  maxContentLength: Infinity,
783
787
  maxBodyLength: Infinity,
784
- timeout: Math.max(300000, Math.ceil(fileSize / (1024 * 1024)) * 5000), // 5s per MB, min 5 minutes
788
+ timeout: Math.max(600000, Math.ceil(fileSize / (1024 * 1024)) * 10000), // 10s per MB, min 10 minutes - increased for large trace files
785
789
  // Don't use custom HTTPS agent for S3 uploads
786
790
  httpsAgent: undefined
787
791
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testlens-playwright-reporter",
3
- "version": "0.2.9",
3
+ "version": "0.3.1",
4
4
  "description": "Universal Playwright reporter for TestLens - works with both TypeScript and JavaScript projects",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",