playwright-slack-report-burak 3.0.30 → 3.0.33

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.
@@ -9,9 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const fs = require('fs');
10
10
  const path = require('path');
11
11
  const axios = require('axios');
12
- const { exec, execSync } = require('child_process');
13
- const { promisify } = require('util');
14
- const execAsync = promisify(exec);
12
+ const { exec } = require('child_process');
15
13
  let AdmZip;
16
14
  try {
17
15
  AdmZip = require('adm-zip');
@@ -20,18 +18,6 @@ try {
20
18
  AdmZip = null;
21
19
  }
22
20
 
23
- // Get package version
24
- let packageVersion = 'unknown';
25
- try {
26
- const packageJsonPath = path.join(__dirname, '../../package.json');
27
- if (fs.existsSync(packageJsonPath)) {
28
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
29
- packageVersion = packageJson.version || 'unknown';
30
- }
31
- } catch (e) {
32
- // Version detection failed, use default
33
- }
34
-
35
21
  class ResultsParser {
36
22
  result;
37
23
  separateFlakyTests;
@@ -45,77 +31,6 @@ class ResultsParser {
45
31
  constructor(options = { separateFlakyTests: false }) {
46
32
  this.result = [];
47
33
  this.separateFlakyTests = options.separateFlakyTests;
48
- // Log package version
49
- console.log(`šŸ“¦ [ResultsParser] playwright-slack-report-burak v${packageVersion}`);
50
- }
51
- /**
52
- * Recursively print directory tree structure
53
- * @param {string} dirPath - Directory path to print
54
- * @param {string} prefix - Prefix for tree visualization
55
- * @param {number} maxDepth - Maximum depth to traverse (default: 5)
56
- */
57
- printDirectoryTree(dirPath, prefix = '', maxDepth = 5) {
58
- if (maxDepth <= 0) return;
59
- if (!fs.existsSync(dirPath)) {
60
- console.log(`${prefix}${path.basename(dirPath)}/ (does not exist)`);
61
- return;
62
- }
63
-
64
- try {
65
- const stats = fs.statSync(dirPath);
66
- if (!stats.isDirectory()) {
67
- const size = stats.size;
68
- const sizeStr = size > 1024 ? `${(size / 1024).toFixed(2)}KB` : `${size}B`;
69
- console.log(`${prefix}${path.basename(dirPath)} (${sizeStr})`);
70
- return;
71
- }
72
-
73
- const dirName = path.basename(dirPath) || dirPath;
74
- console.log(`${prefix}${dirName}/`);
75
-
76
- const entries = fs.readdirSync(dirPath, { withFileTypes: true });
77
- entries.sort((a, b) => {
78
- if (a.isDirectory() && !b.isDirectory()) return -1;
79
- if (!a.isDirectory() && b.isDirectory()) return 1;
80
- return a.name.localeCompare(b.name);
81
- });
82
-
83
- entries.forEach((entry, index) => {
84
- const isLast = index === entries.length - 1;
85
- const newPrefix = prefix + (isLast ? '└── ' : 'ā”œā”€ā”€ ');
86
- const nextPrefix = prefix + (isLast ? ' ' : '│ ');
87
- const fullPath = path.join(dirPath, entry.name);
88
-
89
- if (entry.isDirectory()) {
90
- this.printDirectoryTree(fullPath, nextPrefix, maxDepth - 1);
91
- } else {
92
- try {
93
- const fileStats = fs.statSync(fullPath);
94
- const size = fileStats.size;
95
- const sizeStr = size > 1024 * 1024
96
- ? `${(size / (1024 * 1024)).toFixed(2)}MB`
97
- : size > 1024
98
- ? `${(size / 1024).toFixed(2)}KB`
99
- : `${size}B`;
100
- console.log(`${newPrefix}${entry.name} (${sizeStr})`);
101
- } catch (err) {
102
- console.log(`${newPrefix}${entry.name} (error reading)`);
103
- }
104
- }
105
- });
106
- } catch (error) {
107
- console.log(`${prefix}${path.basename(dirPath)}/ (error: ${error.message})`);
108
- }
109
- }
110
-
111
- /**
112
- * Update shard information after detection (e.g., from GitHub API)
113
- * @param {number} shardIndex - The current shard index (1-based, shard 1 is aggregator)
114
- * @param {number} totalShardCount - The total number of shards
115
- */
116
- updateShardInfo(shardIndex, totalShardCount) {
117
- this.shardIndex = shardIndex;
118
- this.totalShardCount = totalShardCount;
119
34
  }
120
35
  async getParsedResults() {
121
36
  const summary = {
@@ -174,9 +89,11 @@ class ResultsParser {
174
89
 
175
90
  if (this.shardIndex === 1 && this.totalShardCount > 1) {
176
91
  if (process.env.CI) {
92
+ console.log('Fetching all artifacts...');
177
93
  await this.fetchAllArtifacts();
178
94
  } else {
179
95
  while (!this.allNodeSummaryFilesExist() || !this.allBlobZipsExist()) {
96
+ console.log('Waiting for all both to exist...');
180
97
  await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second
181
98
  }
182
99
  }
@@ -184,7 +101,6 @@ class ResultsParser {
184
101
 
185
102
  if (this.shardIndex === 1 && this.allNodeSummaryFilesExist() && this.allBlobZipsExist()) {
186
103
  // Merge all node summaries into the final summary
187
- // Loop from 1 to totalShardCount (1-based indexing)
188
104
  for (let i = 1; i <= this.totalShardCount; i++) {
189
105
  const nodeSummaryFile = path.join(summariesDir, `node_summary_${i}.json`);
190
106
  const fileToRead = nodeSummaryFile;
@@ -221,7 +137,7 @@ class ResultsParser {
221
137
  }
222
138
  }
223
139
 
224
- await this.mergeReports();
140
+ this.mergeReports();
225
141
  }
226
142
  return summary;
227
143
  }
@@ -400,7 +316,6 @@ class ResultsParser {
400
316
  console.log('Checking if all node summary files exist...');
401
317
  const summariesDir = path.join('./', 'playwright-report');
402
318
 
403
- // Check files from 1 to totalShardCount (1-based indexing)
404
319
  for (let i = 1; i <= this.totalShardCount; i++) {
405
320
  const nodeSummaryFile = path.join(summariesDir, `node_summary_${i}.json`);
406
321
  if (!fs.existsSync(nodeSummaryFile)) {
@@ -414,7 +329,6 @@ class ResultsParser {
414
329
  console.log('Checking if all blob zips exist...');
415
330
  const summariesDir = path.join('./', 'playwright-report');
416
331
 
417
- // Check files from 1 to totalShardCount (1-based indexing)
418
332
  for (let i = 1; i <= this.totalShardCount; i++) {
419
333
  const blobZipFile = path.join(summariesDir, `blob-report-node-${i}.zip`);
420
334
  if (!fs.existsSync(blobZipFile)) {
@@ -426,55 +340,15 @@ class ResultsParser {
426
340
 
427
341
  async fetchAllArtifacts() {
428
342
  const summariesDir = path.join('./', 'playwright-report');
429
- if (!fs.existsSync(summariesDir)) {
430
- fs.mkdirSync(summariesDir, { recursive: true });
431
- }
432
-
433
- console.log(`Shard 1: Waiting for artifacts from ${this.totalShardCount - 1} other shard(s)...`);
434
-
435
- // Fetch artifacts for all shards except shard 1 (since we're shard 1)
436
- // We need to fetch from shards 2, 3, 4, ... (all except shard 1, using 1-based indexing)
437
- for (let i = 1; i <= this.totalShardCount; i++) {
438
- if (i === 1) continue; // Skip shard 1 (we are shard 1)
439
- console.log(`Shard 1: Fetching artifacts from shard ${i}...`);
440
- await this.fetchArtifact(i, `node_summary_${i}.json`, summariesDir);
441
- await this.fetchArtifact(i, `blob-report-node-${i}.zip`, summariesDir);
442
- }
443
-
444
- // After fetching, verify all files exist and wait if needed
445
- let retryCount = 0;
446
- const maxRetries = 60; // Wait up to 10 minutes (60 * 10 seconds)
447
-
448
- while ((!this.allNodeSummaryFilesExist() || !this.allBlobZipsExist()) && retryCount < maxRetries) {
449
- console.log(`Shard 1: Waiting for all artifacts to be available (attempt ${retryCount + 1}/${maxRetries})...`);
450
-
451
- // Re-fetch any missing artifacts
452
- for (let i = 1; i <= this.totalShardCount; i++) {
453
- if (i === 1) continue; // Skip shard 1 (we are shard 1)
454
- const nodeSummaryFile = path.join(summariesDir, `node_summary_${i}.json`);
455
- const blobZipFile = path.join(summariesDir, `blob-report-node-${i}.zip`);
456
-
457
- if (!fs.existsSync(nodeSummaryFile)) {
458
- console.log(`Shard 1: Re-fetching missing node_summary_${i}.json...`);
459
- await this.fetchArtifact(i, `node_summary_${i}.json`, summariesDir);
460
- }
461
-
462
- if (!fs.existsSync(blobZipFile)) {
463
- console.log(`Shard 1: Re-fetching missing blob-report-node-${i}.zip...`);
464
- await this.fetchArtifact(i, `blob-report-node-${i}.zip`, summariesDir);
465
- }
466
- }
467
-
468
- retryCount++;
469
- if (!this.allNodeSummaryFilesExist() || !this.allBlobZipsExist()) {
470
- await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds before retry
471
- }
472
- }
473
-
474
- if (this.allNodeSummaryFilesExist() && this.allBlobZipsExist()) {
475
- console.log(`Shard 1: Successfully fetched all artifacts from ${this.totalShardCount - 1} other shard(s).`);
476
- } else {
477
- console.warn(`Shard 1: Warning - Some artifacts may still be missing after ${maxRetries} attempts.`);
343
+ while (!this.allNodeSummaryFilesExist() || !this.allBlobZipsExist()) {
344
+ console.log('Waiting for all blob zips to exist...');
345
+ if (!fs.existsSync(summariesDir)) {
346
+ fs.mkdirSync(summariesDir, { recursive: true });
347
+ }
348
+ for (let i = 2; i <= this.totalShardCount; i++) {
349
+ await this.fetchArtifact(i, `node_summary_${i}.json`, summariesDir);
350
+ await this.fetchArtifact(i, `blob-report-node-${i}.zip`, summariesDir);
351
+ }
478
352
  }
479
353
  }
480
354
 
@@ -486,20 +360,9 @@ class ResultsParser {
486
360
  async fetchArtifactFromGitHubActions(i, file, filePath) {
487
361
  const githubToken = process.env.SAFETYWINGTEST_GITHUB_TOKEN;
488
362
  const repo = process.env.GITHUB_REPOSITORY;
489
- const runId = process.env.GITHUB_RUN_ID;
490
-
491
- if (!githubToken || !repo) {
492
- console.error('GitHub Actions: Missing SAFETYWINGTEST_GITHUB_TOKEN or GITHUB_REPOSITORY');
493
- return;
494
- }
495
-
496
- // GitHub Actions artifact API endpoint
497
363
  const githubApiUrl = `https://api.github.com/repos/${repo}/actions/artifacts`;
498
364
 
499
- // Try multiple artifact naming patterns (all 1-based):
500
- // 1. html-report-{i} (1-based workflow style)
501
- // 2. blob-report-node-{i} (direct blob reports)
502
- // 3. test-results-{i} (alternative naming)
365
+ // Try multiple artifact naming patterns
503
366
  const artifactNamePatterns = [
504
367
  `html-report-${i}`,
505
368
  `blob-report-node-${i}`,
@@ -527,10 +390,7 @@ class ResultsParser {
527
390
  a.name.includes(`shard-${i}`) ||
528
391
  a.name.includes(`node-${i}`)
529
392
  );
530
- if (artifact) {
531
- console.log(`Found artifact: ${artifact.name} (matched pattern: ${pattern})`);
532
- break;
533
- }
393
+ if (artifact) break;
534
394
  }
535
395
 
536
396
  if (artifact && artifact.archive_download_url) {
@@ -550,69 +410,15 @@ class ResultsParser {
550
410
 
551
411
  // Extract ZIP and find the specific file
552
412
  const zip = new AdmZip(downloadResponse.data);
553
-
554
- // Try direct file match first
555
- let zipEntry = zip.getEntry(file);
556
-
557
- // If not found, try common path variations
558
- if (!zipEntry) {
559
- const possiblePaths = [
560
- file,
561
- `playwright-report/${file}`,
562
- `html-report-${i}/${file}`,
563
- `html-report-${i}/playwright-report/${file}`,
564
- ];
565
- for (const possiblePath of possiblePaths) {
566
- zipEntry = zip.getEntry(possiblePath);
567
- if (zipEntry) break;
568
- }
569
- }
413
+ const zipEntry = zip.getEntry(file) || zip.getEntry(`playwright-report/${file}`);
570
414
 
571
415
  if (zipEntry) {
572
416
  fs.writeFileSync(filePath, zipEntry.getData());
573
- console.log(`Successfully fetched file ${file} from GitHub Actions shard ${i} (artifact: ${artifact.name})`);
417
+ console.log(`Successfully fetched file ${file} from shard ${i}`);
574
418
  break;
575
419
  } else {
576
- // If file not found in ZIP root, extract and search recursively
577
- const extractPath = path.join(path.dirname(filePath), `temp-artifact-${i}`);
578
- zip.extractAllTo(extractPath, true);
579
-
580
- // Look for the file recursively
581
- const searchInDir = (dir, targetFile) => {
582
- const entries = fs.readdirSync(dir, { withFileTypes: true });
583
- for (const entry of entries) {
584
- const fullPath = path.join(dir, entry.name);
585
- if (entry.isDirectory()) {
586
- const found = searchInDir(fullPath, targetFile);
587
- if (found) return found;
588
- } else {
589
- // Check exact match
590
- if (entry.name === targetFile) {
591
- return fullPath;
592
- }
593
- // Check if ends with target file
594
- if (entry.name.endsWith(targetFile)) {
595
- return fullPath;
596
- }
597
- }
598
- }
599
- return null;
600
- };
601
-
602
- // Try to find the file recursively
603
- let foundPath = searchInDir(extractPath, file);
604
-
605
- if (foundPath) {
606
- fs.copyFileSync(foundPath, filePath);
607
- console.log(`Successfully fetched file ${file} from GitHub Actions shard ${i} (artifact: ${artifact.name})`);
608
- // Clean up temp directory
609
- fs.rmSync(extractPath, { recursive: true, force: true });
610
- break;
611
- } else {
612
- console.warn(`File ${file} not found in artifact ${artifact.name}. Retrying in 10 seconds...`);
613
- fs.rmSync(extractPath, { recursive: true, force: true });
614
- await new Promise(resolve => setTimeout(resolve, 10000));
615
- }
420
+ console.warn(`File ${file} not found in artifact ${artifact.name}. Retrying in 10 seconds...`);
421
+ await new Promise(resolve => setTimeout(resolve, 10000));
616
422
  }
617
423
  } else {
618
424
  console.warn(`Artifact not found (tried: ${artifactNamePatterns.join(', ')}). Retrying in 10 seconds...`);
@@ -620,168 +426,32 @@ class ResultsParser {
620
426
  }
621
427
  } catch (error) {
622
428
  if (error.response && error.response.status === 404) {
623
- console.warn(`Artifact not found. Retrying in 10 seconds...`);
429
+ console.warn(`File ${file} not found. Retrying in 10 seconds...`);
624
430
  await new Promise(resolve => setTimeout(resolve, 10000));
625
431
  } else {
626
- console.error(`Failed to fetch artifact from GitHub Actions shard ${i}!`, error.message);
627
- await new Promise(resolve => setTimeout(resolve, 10000));
432
+ console.error(`Failed to fetch file ${file} from shard ${i}!`, error);
433
+ break;
628
434
  }
629
435
  }
630
436
  }
631
437
  }
632
- async mergeReports() {
438
+ mergeReports() {
439
+ let breakMergeWaiter = false;
633
440
  try {
634
- const summariesDir = path.join('./', 'playwright-report');
635
- const blobReportsDir = path.join(summariesDir, 'blob-reports');
636
- const mergedBlobsDir = path.join(summariesDir, 'mergedBlobsDir');
637
-
638
- console.log('\n=== Starting merge process ===');
639
- console.log(`Summaries directory: ${path.resolve(summariesDir)}`);
640
- console.log(`Blob reports directory: ${path.resolve(blobReportsDir)}`);
641
- console.log(`Merged blobs directory: ${path.resolve(mergedBlobsDir)}`);
642
-
643
- // Show initial directory structure
644
- console.log('\nšŸ“ Initial playwright-report directory structure:');
645
- if (fs.existsSync(summariesDir)) {
646
- this.printDirectoryTree(summariesDir);
647
- } else {
648
- console.log(' (directory does not exist yet)');
649
- }
650
-
651
- // Create directory for extracted blob reports
652
- if (!fs.existsSync(blobReportsDir)) {
653
- fs.mkdirSync(blobReportsDir, { recursive: true });
654
- }
655
-
656
- // Create directory for merged blob reports output
657
- if (!fs.existsSync(mergedBlobsDir)) {
658
- fs.mkdirSync(mergedBlobsDir, { recursive: true });
659
- }
660
-
661
- // Extract all blob zips to preserve traces
662
- console.log('\nšŸ“¦ Extracting blob reports to preserve traces...');
663
- let hasBlobReports = false;
664
- for (let i = 1; i <= this.totalShardCount; i++) {
665
- const blobZipFile = path.join(summariesDir, `blob-report-node-${i}.zip`);
666
- if (fs.existsSync(blobZipFile)) {
667
- if (!AdmZip) {
668
- console.warn('adm-zip is required for blob extraction. Falling back to HTML report merge.');
669
- break;
670
- }
671
-
672
- const zip = new AdmZip(blobZipFile);
673
- const extractPath = path.join(blobReportsDir, `node-${i}`);
674
- zip.extractAllTo(extractPath, true);
675
- console.log(`Extracted blob report from shard ${i}`);
676
- hasBlobReports = true;
677
- }
678
- }
679
-
680
- // Show directory structure after extraction
681
- if (hasBlobReports) {
682
- console.log('\nšŸ“ Directory structure after blob extraction:');
683
- this.printDirectoryTree(summariesDir);
684
- }
685
-
686
- // Merge blob reports instead of HTML reports to preserve traces
687
- if (hasBlobReports && fs.existsSync(blobReportsDir) && fs.readdirSync(blobReportsDir).length > 0) {
688
- console.log('\nšŸ”„ Merging blob reports (preserves traces)...');
689
- let tempConfigPath = null;
690
- try {
691
- // Merge blob reports - use config file to specify output directory
692
- // This prevents wiping the playwright-report directory
693
- const blobReportsRelativePath = path.relative(summariesDir, blobReportsDir);
694
- const mergedBlobsAbsolutePath = path.resolve(mergedBlobsDir);
695
- console.log(`Merging blob reports from: ${blobReportsRelativePath}`);
696
- console.log(`Output directory: ${mergedBlobsAbsolutePath}`);
697
-
698
- // Create temporary config file to specify output folder
699
- tempConfigPath = path.join(summariesDir, 'merge-config.js');
700
- // Escape backslashes and single quotes in path for JavaScript string
701
- const escapedPath = mergedBlobsAbsolutePath.replace(/\\/g, '/').replace(/'/g, "\\'");
702
- const configContent = `module.exports = {
703
- reporter: [['html', { outputFolder: '${escapedPath}' }]]
704
- };`;
705
- fs.writeFileSync(tempConfigPath, configContent);
706
- console.log(`Created temporary config file: ${tempConfigPath}`);
707
- console.log(`Config content: ${configContent}`);
708
-
709
- const mergeCommand = `npx playwright merge-reports --reporter html --config "${tempConfigPath}" "${blobReportsRelativePath}"`;
710
- console.log(`Executing: ${mergeCommand}`);
711
- const mergeResult = await execAsync(mergeCommand, { cwd: summariesDir });
712
- console.log('Merge command output:', mergeResult.stdout);
713
- if (mergeResult.stderr) {
714
- console.warn('Merge command stderr:', mergeResult.stderr);
715
- }
716
- console.log('Blob reports merged successfully with traces preserved.');
717
-
718
- // Show directory structure after merge
719
- console.log('\nšŸ“ Directory structure after merge:');
720
- this.printDirectoryTree(summariesDir);
721
- console.log('\nšŸ“ Merged blobs directory contents:');
722
- this.printDirectoryTree(mergedBlobsDir);
723
- } catch (error) {
724
- console.warn('Warning: Failed to merge blob reports. Falling back to HTML merge.', error.message);
725
- if (error.stdout) console.log('Merge stdout:', error.stdout);
726
- if (error.stderr) console.warn('Merge stderr:', error.stderr);
727
-
728
- // Show directory structure after failed merge
729
- console.log('\nšŸ“ Directory structure after failed merge:');
730
- this.printDirectoryTree(summariesDir);
731
-
732
- // Fallback to HTML merge
733
- execSync(`npx playwright merge-reports --reporter html -c ./playwright-report playwright-report`, { stdio: 'inherit' });
734
- } finally {
735
- // Clean up temporary config file
736
- if (tempConfigPath && fs.existsSync(tempConfigPath)) {
737
- try {
738
- fs.unlinkSync(tempConfigPath);
739
- console.log(`Cleaned up temporary config file: ${tempConfigPath}`);
740
- } catch (cleanupError) {
741
- console.warn(`Warning: Failed to clean up temp config file: ${cleanupError.message}`);
742
- }
441
+ // Execute the command to merge reports
442
+ exec(`npx playwright merge-reports --reporter html -c ./playwright-report playwright-report`);
443
+ // Wait until index.html exists
444
+ while (!fs.existsSync(path.join('./playwright-report', 'index.html'))) {
445
+ console.log('Waiting 2 seconds for merged html report to be generated...');
446
+ const currentTime = new Date().getTime();
447
+ breakMergeWaiter = false;
448
+ while (!breakMergeWaiter) {
449
+ if(new Date().getTime() - currentTime > 2000) {
450
+ breakMergeWaiter = true;
743
451
  }
744
452
  }
745
- } else {
746
- // Fallback to HTML merge if no blob reports found
747
- console.log('No blob reports found, falling back to HTML report merge...');
748
- execSync(`npx playwright merge-reports --reporter html -c ./playwright-report playwright-report`, { stdio: 'inherit' });
749
- }
750
-
751
- // Wait until index.html exists in mergedBlobsDir (with timeout)
752
- const maxWaitTime = 60000; // 60 seconds max wait
753
- const startWaitTime = new Date().getTime();
754
- const indexHtmlPath = path.join(mergedBlobsDir, 'index.html');
755
-
756
- console.log('\nā³ Waiting for merged HTML report to be generated...');
757
- while (!fs.existsSync(indexHtmlPath)) {
758
- const elapsed = new Date().getTime() - startWaitTime;
759
- if (elapsed > maxWaitTime) {
760
- console.warn(`\nā±ļø Timeout: index.html not found in ${mergedBlobsDir} after ${maxWaitTime}ms`);
761
- console.log(`Checking if directory exists: ${fs.existsSync(mergedBlobsDir)}`);
762
- if (fs.existsSync(mergedBlobsDir)) {
763
- console.log('\nšŸ“ Full directory tree at timeout:');
764
- this.printDirectoryTree(summariesDir);
765
- console.log('\nšŸ“ Merged blobs directory detailed contents:');
766
- this.printDirectoryTree(mergedBlobsDir);
767
- } else {
768
- console.log('Merged blobs directory does not exist!');
769
- }
770
- break;
771
- }
772
- console.log(`Waiting for merged html report to be generated... (${Math.round(elapsed/1000)}s elapsed)`);
773
- await new Promise(resolve => setTimeout(resolve, 2000));
774
- }
775
-
776
- if (fs.existsSync(indexHtmlPath)) {
777
- console.log('\nāœ… Reports merged successfully.');
778
- console.log('\nšŸ“ Final directory structure:');
779
- this.printDirectoryTree(summariesDir);
780
- } else {
781
- console.warn('\nāš ļø Warning: Merged report index.html not found, but continuing...');
782
- console.log('\nšŸ“ Final directory structure:');
783
- this.printDirectoryTree(summariesDir);
784
453
  }
454
+ console.log('Reports merged successfully.');
785
455
  } catch (error) {
786
456
  // Log a warning instead of throwing an error
787
457
  console.warn('Warning: Failed to merge reports. This may not affect the overall process.', error.message);
@@ -6,27 +6,6 @@ const webhook_1 = require("@slack/webhook");
6
6
  const ResultsParser_1 = require("./ResultsParser");
7
7
  const SlackClient_1 = require("./SlackClient");
8
8
  const SlackWebhookClient_1 = require("./SlackWebhookClient");
9
- let axios;
10
- try {
11
- axios = require('axios');
12
- } catch (e) {
13
- // axios optional for GitHub Actions API detection
14
- axios = null;
15
- }
16
-
17
- // Get package version
18
- const fs = require('fs');
19
- const path = require('path');
20
- let packageVersion = 'unknown';
21
- try {
22
- const packageJsonPath = path.join(__dirname, '../../package.json');
23
- if (fs.existsSync(packageJsonPath)) {
24
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
25
- packageVersion = packageJson.version || 'unknown';
26
- }
27
- } catch (e) {
28
- // Version detection failed, use default
29
- }
30
9
 
31
10
  class SlackReporter {
32
11
  customLayout;
@@ -46,11 +25,7 @@ class SlackReporter {
46
25
  suite;
47
26
  separateFlaky = false;
48
27
  logs = [];
49
- fullConfig;
50
28
  onBegin(fullConfig, suite) {
51
- // Log package version
52
- console.log(`šŸ“¦ [SlackReporter] playwright-slack-report-burak v${packageVersion}`);
53
- this.fullConfig = fullConfig;
54
29
  this.suite = suite;
55
30
  this.logs = [];
56
31
  const slackReporterConfig = fullConfig.reporter.filter((f) => f[0].toLowerCase().includes('slackreporter'))[0][1];
@@ -96,52 +71,11 @@ class SlackReporter {
96
71
  this.log(message);
97
72
  return;
98
73
  }
99
- // SHARDING SUPPORT - Stop slack messages for non-shard-1 shard(s)
100
- // Only shard 1 should post when aggregating results from multiple shards
101
-
102
- // Get shard info from environment variables
103
- const currentShardIndex = process.env.SHARD_INDEX;
104
- const totalShards = process.env.TOTAL_SHARDS ? parseInt(process.env.TOTAL_SHARDS, 10) : 1;
105
-
106
- // CRITICAL: In CI, if we can't detect shard info, block posting
107
- // This prevents duplicate messages when running with multiple shards
108
- if (process.env.CI && currentShardIndex === undefined && totalShards > 1) {
109
- this.log(`āŒ [Shard Detection] BLOCKING: CI environment detected but SHARD_INDEX not set.`);
110
- this.log(`āŒ This prevents duplicate messages when running with multiple shards.`);
111
- this.log(`āŒ Skipping Slack report to prevent duplicate messages from all shards.`);
112
- this.log(`šŸ’” Fix: Add SHARD_INDEX env var to your workflow:`);
113
- this.log(`šŸ’” env:`);
114
- this.log(`šŸ’” SHARD_INDEX: $\{\{ strategy.job-index \}\} # Only shard 1 should post`);
115
- this.log(`šŸ’” TOTAL_SHARDS: $\{\{ strategy.job-total \}\}`);
116
- return;
117
- }
118
-
119
- // Convert to number for comparison (default to 1 if undefined, since shard 1 is the aggregator)
120
- const shardIndexNum = currentShardIndex !== undefined ? parseInt(currentShardIndex, 10) : 1;
121
-
122
- // CRITICAL: Update ResultsParser with detected shard values immediately after detection
123
- // This ensures ResultsParser always has correct values, even if we block posting
124
- this.resultsParser.updateShardInfo(shardIndexNum, totalShards);
125
-
126
- // CRITICAL: ALL shards must create their node_summary files, even if they don't post to Slack
127
- // This must happen BEFORE the early return for non-shard-1 shards
128
74
  const resultSummary = await this.resultsParser.getParsedResults();
129
-
130
- // Only allow shard 1 to post when there are multiple shards
131
- // This ensures only one shard posts the aggregated report
132
- if (totalShards > 1 && shardIndexNum !== 1) {
133
- this.log(`āŒ [Shard Detection] BLOCKING: Non-shard-1 detected (shard ${shardIndexNum} of ${totalShards})`);
134
- this.log(`āŒ Stopping reporter for shard ${shardIndexNum} of ${totalShards}`);
135
- this.log(`ā„¹ļø Only shard 1 will post the aggregated report.`);
136
- this.log(`āœ… Node summary file created for shard ${shardIndexNum}`);
137
- return;
138
- }
139
-
140
- // Single shard - always allow posting
141
- if (totalShards === 1) {
142
- this.log(`āœ… [Shard Detection] ALLOWING: Single shard detected. Posting Slack report.`);
143
- } else {
144
- this.log(`āœ… [Shard Detection] ALLOWING: Multiple shards detected (${totalShards}). Shard ${shardIndexNum} will post aggregated report.`);
75
+ // SHARDING SUPPORT - Stop slack messages for non-shard-1 shard(s)
76
+ if (process.env.SHARD_INDEX && process.env.SHARD_INDEX !== '1') {
77
+ this.log(`āŒ Stopping reporter for non-shard-1 index ${process.env.SHARD_INDEX} of ${process.env.TOTAL_SHARDS}`);
78
+ return;
145
79
  }
146
80
  resultSummary.meta = this.meta;
147
81
  const maxRetry = Math.max(...resultSummary.tests.map((o) => o.retry));
package/package.json CHANGED
@@ -32,7 +32,7 @@
32
32
  "lint-fix": "npx eslint . --ext .ts --fix"
33
33
  },
34
34
  "name": "playwright-slack-report-burak",
35
- "version": "3.0.30",
35
+ "version": "3.0.33",
36
36
  "main": "index.js",
37
37
  "types": "dist/index.d.ts",
38
38
  "author": "Burak B. <burak.boluk@hotmail.com>",