playwright-slack-report-burak 3.0.29 ā 3.0.32
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 +30 -2
- package/dist/src/SlackReporter.js +4 -70
- package/package.json +1 -1
|
@@ -686,14 +686,29 @@ class ResultsParser {
|
|
|
686
686
|
// Merge blob reports instead of HTML reports to preserve traces
|
|
687
687
|
if (hasBlobReports && fs.existsSync(blobReportsDir) && fs.readdirSync(blobReportsDir).length > 0) {
|
|
688
688
|
console.log('\nš Merging blob reports (preserves traces)...');
|
|
689
|
+
let tempConfigPath = null;
|
|
689
690
|
try {
|
|
690
|
-
// Merge blob reports - use
|
|
691
|
+
// Merge blob reports - use config file to specify output directory
|
|
691
692
|
// This prevents wiping the playwright-report directory
|
|
692
693
|
const blobReportsRelativePath = path.relative(summariesDir, blobReportsDir);
|
|
693
694
|
const mergedBlobsAbsolutePath = path.resolve(mergedBlobsDir);
|
|
694
695
|
console.log(`Merging blob reports from: ${blobReportsRelativePath}`);
|
|
695
696
|
console.log(`Output directory: ${mergedBlobsAbsolutePath}`);
|
|
696
|
-
|
|
697
|
+
|
|
698
|
+
// Create temporary config file to specify output folder
|
|
699
|
+
tempConfigPath = path.join(summariesDir, 'merge-config.js');
|
|
700
|
+
const tempConfigAbsolutePath = path.resolve(tempConfigPath);
|
|
701
|
+
// Escape backslashes and single quotes in path for JavaScript string
|
|
702
|
+
const escapedPath = mergedBlobsAbsolutePath.replace(/\\/g, '/').replace(/'/g, "\\'");
|
|
703
|
+
const configContent = `module.exports = {
|
|
704
|
+
reporter: [['html', { outputFolder: '${escapedPath}' }]]
|
|
705
|
+
};`;
|
|
706
|
+
fs.writeFileSync(tempConfigPath, configContent);
|
|
707
|
+
console.log(`Created temporary config file: ${tempConfigAbsolutePath}`);
|
|
708
|
+
console.log(`Config content: ${configContent}`);
|
|
709
|
+
|
|
710
|
+
// Use absolute path for config file to avoid path resolution issues
|
|
711
|
+
const mergeCommand = `npx playwright merge-reports --reporter html --config "${tempConfigAbsolutePath}" "${blobReportsRelativePath}"`;
|
|
697
712
|
console.log(`Executing: ${mergeCommand}`);
|
|
698
713
|
const mergeResult = await execAsync(mergeCommand, { cwd: summariesDir });
|
|
699
714
|
console.log('Merge command output:', mergeResult.stdout);
|
|
@@ -718,6 +733,19 @@ class ResultsParser {
|
|
|
718
733
|
|
|
719
734
|
// Fallback to HTML merge
|
|
720
735
|
execSync(`npx playwright merge-reports --reporter html -c ./playwright-report playwright-report`, { stdio: 'inherit' });
|
|
736
|
+
} finally {
|
|
737
|
+
// Clean up temporary config file
|
|
738
|
+
if (tempConfigPath) {
|
|
739
|
+
const configPathToDelete = fs.existsSync(tempConfigPath) ? tempConfigPath : path.resolve(tempConfigPath);
|
|
740
|
+
if (fs.existsSync(configPathToDelete)) {
|
|
741
|
+
try {
|
|
742
|
+
fs.unlinkSync(configPathToDelete);
|
|
743
|
+
console.log(`Cleaned up temporary config file: ${configPathToDelete}`);
|
|
744
|
+
} catch (cleanupError) {
|
|
745
|
+
console.warn(`Warning: Failed to clean up temp config file: ${cleanupError.message}`);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
721
749
|
}
|
|
722
750
|
} else {
|
|
723
751
|
// Fallback to HTML merge if no blob reports found
|
|
@@ -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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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