playwright-slack-report-burak 3.0.11 → 3.0.13

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.
@@ -114,41 +114,120 @@ class SlackReporter {
114
114
  this.log(`🔍 [GitHub Actions Detection] No jobs found in workflow run`);
115
115
  return null;
116
116
  }
117
- // Filter jobs that are part of the same workflow run and have the same name (matrix jobs)
118
- // Group by job name to find matrix jobs
117
+
118
+ this.log(`🔍 [GitHub Actions Detection] Found ${jobs.length} total jobs in workflow run`);
119
+
120
+ // Helper function to normalize job names by removing shard indicators
121
+ // e.g., "Run tests (shard 3/4)" -> "Run tests"
122
+ const normalizeJobName = (name) => {
123
+ if (!name) return '';
124
+ // Remove common matrix patterns: (shard X/Y), (X, Y), [X], etc.
125
+ return name
126
+ .replace(/\s*\(shard\s+\d+\/\d+\)/gi, '')
127
+ .replace(/\s*\(\d+\/\d+\)/g, '')
128
+ .replace(/\s*\(\d+,\s*\d+\)/g, '')
129
+ .replace(/\s*\[\d+\]/g, '')
130
+ .trim();
131
+ };
132
+
133
+ // Group jobs by normalized name to find matrix jobs
119
134
  const jobGroups = {};
120
135
  for (const job of jobs) {
121
136
  const jobName = job.name || '';
122
- if (!jobGroups[jobName]) {
123
- jobGroups[jobName] = [];
137
+ const normalizedName = normalizeJobName(jobName);
138
+ if (!jobGroups[normalizedName]) {
139
+ jobGroups[normalizedName] = [];
124
140
  }
125
- jobGroups[jobName].push(job);
141
+ jobGroups[normalizedName].push(job);
142
+ }
143
+
144
+ this.log(`🔍 [GitHub Actions Detection] Grouped into ${Object.keys(jobGroups).length} job group(s)`);
145
+ for (const [groupName, groupJobs] of Object.entries(jobGroups)) {
146
+ this.log(`🔍 Group "${groupName}": ${groupJobs.length} job(s)`);
126
147
  }
148
+
127
149
  // Find the job group that contains the current job
128
150
  let currentJob = null;
129
151
  let jobGroup = null;
130
- for (const [jobName, jobsInGroup] of Object.entries(jobGroups)) {
131
- currentJob = jobsInGroup.find(j => j.id.toString() === currentJobId || j.name === currentJobId);
132
- if (currentJob) {
133
- jobGroup = jobsInGroup;
134
- break;
152
+
153
+ // Strategy 1: Find the currently running job (status: in_progress or completed recently)
154
+ const runningJobs = jobs.filter(j => j.status === 'in_progress' || j.status === 'queued');
155
+ this.log(`🔍 [GitHub Actions Detection] Found ${runningJobs.length} running/queued job(s)`);
156
+
157
+ if (runningJobs.length === 1) {
158
+ // Perfect - only one job is running, must be us
159
+ currentJob = runningJobs[0];
160
+ const normalizedName = normalizeJobName(currentJob.name);
161
+ jobGroup = jobGroups[normalizedName];
162
+ this.log(`🔍 [GitHub Actions Detection] Matched by running status: "${currentJob.name}"`);
163
+ } else if (runningJobs.length > 1) {
164
+ // Multiple running jobs - try to match by job ID or name
165
+ for (const job of runningJobs) {
166
+ // Check if this job's name contains the GITHUB_JOB id
167
+ // But be more specific - avoid matching "Generate test matrix" when looking for "test"
168
+ const jobIdLower = currentJobId.toLowerCase();
169
+ const jobNameLower = (job.name || '').toLowerCase();
170
+
171
+ // Match if job name starts with or equals the job ID (more specific)
172
+ if (jobNameLower.startsWith(jobIdLower) ||
173
+ jobNameLower.includes(`${jobIdLower} `) ||
174
+ jobNameLower.includes(`${jobIdLower}(`) ||
175
+ jobNameLower === jobIdLower) {
176
+ currentJob = job;
177
+ const normalizedName = normalizeJobName(job.name);
178
+ jobGroup = jobGroups[normalizedName];
179
+ this.log(`🔍 [GitHub Actions Detection] Matched running job by ID match: "${job.name}"`);
180
+ break;
181
+ }
182
+ }
183
+
184
+ // Still no match? Take the first running job that looks like a test job
185
+ if (!currentJob) {
186
+ for (const job of runningJobs) {
187
+ if (job.name && (job.name.includes('shard') || job.name.includes('test') || job.name.includes('matrix'))) {
188
+ currentJob = job;
189
+ const normalizedName = normalizeJobName(job.name);
190
+ jobGroup = jobGroups[normalizedName];
191
+ this.log(`🔍 [GitHub Actions Detection] Matched by test-like name: "${job.name}"`);
192
+ break;
193
+ }
194
+ }
135
195
  }
136
196
  }
137
- // If we can't find current job by ID, try to match by name from GITHUB_JOB
138
- if (!currentJob && currentJobId) {
139
- for (const [jobName, jobsInGroup] of Object.entries(jobGroups)) {
140
- if (jobName.includes(currentJobId) || currentJobId.includes(jobName)) {
141
- jobGroup = jobsInGroup;
142
- // Try to find the job by looking at run_attempt or other identifiers
143
- currentJob = jobsInGroup[0];
197
+
198
+ // Strategy 2: If no running job found, look at all jobs
199
+ if (!currentJob) {
200
+ this.log(`🔍 [GitHub Actions Detection] No running job matched, checking all jobs`);
201
+ for (const job of jobs) {
202
+ const jobIdLower = currentJobId.toLowerCase();
203
+ const jobNameLower = (job.name || '').toLowerCase();
204
+
205
+ if (jobNameLower.startsWith(jobIdLower) ||
206
+ jobNameLower.includes(`${jobIdLower} `) ||
207
+ jobNameLower.includes(`${jobIdLower}(`)) {
208
+ currentJob = job;
209
+ const normalizedName = normalizeJobName(job.name);
210
+ jobGroup = jobGroups[normalizedName];
211
+ this.log(`🔍 [GitHub Actions Detection] Matched job by name: "${job.name}"`);
144
212
  break;
145
213
  }
146
214
  }
147
215
  }
148
- // If still no match, use all jobs (might be a single job or we can't determine)
216
+
217
+ // Fallback: Use the largest job group (likely the matrix jobs)
149
218
  if (!jobGroup || jobGroup.length === 0) {
150
- jobGroup = jobs;
151
- currentJob = jobs[0];
219
+ this.log(`🔍 [GitHub Actions Detection] Could not match job, using largest job group`);
220
+ let largestGroup = [];
221
+ let largestGroupName = '';
222
+ for (const [groupName, groupJobs] of Object.entries(jobGroups)) {
223
+ if (groupJobs.length > largestGroup.length) {
224
+ largestGroup = groupJobs;
225
+ largestGroupName = groupName;
226
+ }
227
+ }
228
+ jobGroup = largestGroup;
229
+ currentJob = jobGroup[0];
230
+ this.log(`🔍 [GitHub Actions Detection] Using largest group "${largestGroupName}" with ${jobGroup.length} job(s)`);
152
231
  }
153
232
  // Sort jobs by name or ID to get consistent ordering
154
233
  jobGroup.sort((a, b) => {
@@ -157,13 +236,23 @@ class SlackReporter {
157
236
  }
158
237
  return a.id - b.id;
159
238
  });
160
- // Find index of current job
161
- const currentJobIndex = jobGroup.findIndex(j =>
162
- j.id === currentJob?.id ||
163
- j.name === currentJob?.name ||
164
- (currentJobId && (j.name === currentJobId || j.name?.includes(currentJobId)))
165
- );
166
- const shardIndex = currentJobIndex >= 0 ? currentJobIndex : 0;
239
+
240
+ // Find index of current job in the sorted group
241
+ const currentJobIndex = jobGroup.findIndex(j => j.id === currentJob?.id || j.name === currentJob?.name);
242
+
243
+ // Try to extract shard number from job name (e.g., "shard 3/4" -> index 2)
244
+ let shardIndex = currentJobIndex >= 0 ? currentJobIndex : 0;
245
+ if (currentJob && currentJob.name) {
246
+ const shardMatch = currentJob.name.match(/shard\s+(\d+)\/(\d+)/i);
247
+ if (shardMatch) {
248
+ const shardNum = parseInt(shardMatch[1], 10);
249
+ const totalFromName = parseInt(shardMatch[2], 10);
250
+ // Convert to 0-based index (shard 3/4 -> index 2)
251
+ shardIndex = shardNum - 1;
252
+ this.log(`🔍 [GitHub Actions Detection] Extracted shard info from name: ${shardNum}/${totalFromName} -> index ${shardIndex}`);
253
+ }
254
+ }
255
+
167
256
  const totalShards = jobGroup.length;
168
257
  this.log(`🔍 [GitHub Actions Detection] Detected via API:`);
169
258
  this.log(`🔍 Total jobs in group: ${totalShards}`);
@@ -491,3 +580,4 @@ class SlackReporter {
491
580
  }
492
581
  }
493
582
  exports.default = SlackReporter;
583
+
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.11",
35
+ "version": "3.0.13",
36
36
  "main": "index.js",
37
37
  "types": "dist/index.d.ts",
38
38
  "author": "Burak B. <burak.boluk@hotmail.com>",