playwright-slack-report-burak 3.0.2 → 3.0.4
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/dist/src/ResultsParser.js +47 -13
- package/dist/src/SlackReporter.js +18 -32
- package/package.json +1 -1
|
@@ -343,19 +343,53 @@ class ResultsParser {
|
|
|
343
343
|
|
|
344
344
|
async fetchAllArtifacts() {
|
|
345
345
|
const summariesDir = path.join('./', 'playwright-report');
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
346
|
+
if (!fs.existsSync(summariesDir)) {
|
|
347
|
+
fs.mkdirSync(summariesDir, { recursive: true });
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
console.log(`Shard 0: Waiting for artifacts from ${this.totalShardCount - 1} other shard(s)...`);
|
|
351
|
+
|
|
352
|
+
// Fetch artifacts for shards 1 to totalShardCount-1 (since we're shard 0)
|
|
353
|
+
// We need to fetch from all other shards before proceeding
|
|
354
|
+
for (let i = 1; i < this.totalShardCount; i++) {
|
|
355
|
+
console.log(`Shard 0: Fetching artifacts from shard ${i}...`);
|
|
356
|
+
await this.fetchArtifact(i, `node_summary_${i}.json`, summariesDir);
|
|
357
|
+
await this.fetchArtifact(i, `blob-report-node-${i}.zip`, summariesDir);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// After fetching, verify all files exist and wait if needed
|
|
361
|
+
let retryCount = 0;
|
|
362
|
+
const maxRetries = 60; // Wait up to 10 minutes (60 * 10 seconds)
|
|
363
|
+
|
|
364
|
+
while ((!this.allNodeSummaryFilesExist() || !this.allBlobZipsExist()) && retryCount < maxRetries) {
|
|
365
|
+
console.log(`Shard 0: Waiting for all artifacts to be available (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
366
|
+
|
|
367
|
+
// Re-fetch any missing artifacts
|
|
368
|
+
for (let i = 1; i < this.totalShardCount; i++) {
|
|
369
|
+
const nodeSummaryFile = path.join(summariesDir, `node_summary_${i}.json`);
|
|
370
|
+
const blobZipFile = path.join(summariesDir, `blob-report-node-${i}.zip`);
|
|
371
|
+
|
|
372
|
+
if (!fs.existsSync(nodeSummaryFile)) {
|
|
373
|
+
console.log(`Shard 0: Re-fetching missing node_summary_${i}.json...`);
|
|
374
|
+
await this.fetchArtifact(i, `node_summary_${i}.json`, summariesDir);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (!fs.existsSync(blobZipFile)) {
|
|
378
|
+
console.log(`Shard 0: Re-fetching missing blob-report-node-${i}.zip...`);
|
|
379
|
+
await this.fetchArtifact(i, `blob-report-node-${i}.zip`, summariesDir);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
retryCount++;
|
|
384
|
+
if (!this.allNodeSummaryFilesExist() || !this.allBlobZipsExist()) {
|
|
385
|
+
await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds before retry
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (this.allNodeSummaryFilesExist() && this.allBlobZipsExist()) {
|
|
390
|
+
console.log(`Shard 0: Successfully fetched all artifacts from ${this.totalShardCount - 1} other shard(s).`);
|
|
391
|
+
} else {
|
|
392
|
+
console.warn(`Shard 0: Warning - Some artifacts may still be missing after ${maxRetries} attempts.`);
|
|
359
393
|
}
|
|
360
394
|
}
|
|
361
395
|
|
|
@@ -70,51 +70,35 @@ class SlackReporter {
|
|
|
70
70
|
this.log(message);
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
-
const resultSummary = await this.resultsParser.getParsedResults();
|
|
74
73
|
// SHARDING SUPPORT - Stop slack messages for non-zero index shard(s)
|
|
75
|
-
//
|
|
76
|
-
// Only shard 0 (0-based) or shard 1 (1-based) should post when aggregating
|
|
77
|
-
|
|
78
|
-
let currentShardIndex = process.env.MATRIX_SHARD !== undefined
|
|
79
|
-
? process.env.MATRIX_SHARD
|
|
80
|
-
: (process.env.MATRIX_INDEX !== undefined ? process.env.MATRIX_INDEX : undefined);
|
|
81
|
-
|
|
82
|
-
// Get shard info from ResultsParser which might have detected it from artifact fetching
|
|
83
|
-
const parserShardIndex = this.resultsParser.shardIndex;
|
|
84
|
-
const parserTotalShards = this.resultsParser.totalShardCount;
|
|
74
|
+
// Only shard 0 (0-based) should post when aggregating results from multiple shards
|
|
85
75
|
|
|
86
|
-
//
|
|
87
|
-
|
|
76
|
+
// Detect shard index from multiple sources (GitHub Actions compatible)
|
|
77
|
+
let currentShardIndex = process.env.strategy.job-total !== undefined
|
|
78
|
+
? process.env.strategy.job-total
|
|
79
|
+
: undefined;
|
|
88
80
|
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
currentShardIndex = parserShardIndex.toString();
|
|
92
|
-
}
|
|
81
|
+
// Convert to number for comparison (default to 0 if undefined)
|
|
82
|
+
const shardIndexNum = currentShardIndex !== undefined ? parseInt(currentShardIndex, 10) : 0;
|
|
93
83
|
|
|
94
|
-
// CRITICAL:
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
if (process.env.CI && currentShardIndex === undefined) {
|
|
98
|
-
|
|
99
|
-
// Only shard 0/1 should post when aggregating, but we can't detect it without MATRIX_SHARD
|
|
100
|
-
this.log(`❌ CI environment detected but shard index not set (MATRIX_SHARD/MATRIX_INDEX missing).`);
|
|
84
|
+
// CRITICAL: For GitHub Actions with multiple shards, only shard 0 should post
|
|
85
|
+
// If we're in CI with multiple shards and don't know which shard we are, block all posts
|
|
86
|
+
// This prevents duplicate messages when MATRIX_SHARD/MATRIX_INDEX is not set
|
|
87
|
+
if (process.env.CI && totalShards > 1 && currentShardIndex === undefined) {
|
|
88
|
+
this.log(`❌ GitHub Actions detected with ${totalShards} shards but shard index not set (MATRIX_SHARD/MATRIX_INDEX missing).`);
|
|
101
89
|
this.log(`❌ Skipping Slack report to prevent duplicate messages from all shards.`);
|
|
102
90
|
this.log(`💡 Fix: Add these env vars to your workflow:`);
|
|
103
91
|
this.log(`💡 env:`);
|
|
104
|
-
this.log(`💡 MATRIX_SHARD: $\{\{
|
|
92
|
+
this.log(`💡 MATRIX_SHARD: $\{\{ strategy.job-index \}\} # 0-based (only shard 0 posts)`);
|
|
105
93
|
this.log(`💡 MATRIX_COUNT: $\{\{ strategy.job-total \}\}`);
|
|
106
|
-
this.log(`💡 OR use 1-based: MATRIX_SHARD: $\{\{ matrix.shard \}\} (then only shard 1 posts)`);
|
|
107
94
|
return;
|
|
108
95
|
}
|
|
109
96
|
|
|
110
|
-
//
|
|
111
|
-
const shardIndexNum = currentShardIndex !== undefined ? parseInt(currentShardIndex, 10) : 0;
|
|
112
|
-
|
|
113
|
-
// Only allow shard 0 (0-based) or shard 1 (1-based) to post when there are multiple shards
|
|
97
|
+
// Only allow shard 0 (0-based) to post when there are multiple shards
|
|
114
98
|
// This ensures only one shard posts the aggregated report
|
|
115
|
-
if (totalShards > 1 && shardIndexNum !== 0
|
|
99
|
+
if (totalShards > 1 && shardIndexNum !== 0) {
|
|
116
100
|
this.log(`❌ Stopping reporter for non-zero index shard ${currentShardIndex} of ${totalShards}`);
|
|
117
|
-
this.log(`ℹ️ Only shard 0
|
|
101
|
+
this.log(`ℹ️ Only shard 0 will post the aggregated report.`);
|
|
118
102
|
return;
|
|
119
103
|
}
|
|
120
104
|
|
|
@@ -124,6 +108,8 @@ class SlackReporter {
|
|
|
124
108
|
} else {
|
|
125
109
|
this.log(`ℹ️ Multiple shards detected (${totalShards}). Shard ${currentShardIndex} will post aggregated report.`);
|
|
126
110
|
}
|
|
111
|
+
|
|
112
|
+
const resultSummary = await this.resultsParser.getParsedResults();
|
|
127
113
|
resultSummary.meta = this.meta;
|
|
128
114
|
const maxRetry = Math.max(...resultSummary.tests.map((o) => o.retry));
|
|
129
115
|
if (this.sendResults === 'on-failure'
|
package/package.json
CHANGED