Skip to content

Commit 38e9800

Browse files
committed
fix: Refactor failure handling in summary generation to separate unexpected and expected failures with improved grouping
1 parent ae3e4fc commit 38e9800

File tree

1 file changed

+40
-33
lines changed

1 file changed

+40
-33
lines changed

utils/generate-failed-test-screenshots-summary.js

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,31 @@ async function main() {
195195
}
196196
collectStats(report.suites || []);
197197

198+
function toSummaryRecord(rawTest) {
199+
const [specFile, ...rest] = rawTest.name.split(" › ");
200+
return {
201+
specFile: normalizeSummaryText(specFile),
202+
name: normalizeSummaryText(rest.join(" › ")),
203+
screenshot: rawTest.screenshot,
204+
error: normalizeSummaryText(rawTest.error),
205+
status: rawTest.status,
206+
expectedFailure: rawTest.expectedFailure,
207+
};
208+
}
209+
210+
function groupBySpec(tests) {
211+
const grouped = {};
212+
for (const test of tests) {
213+
if (!grouped[test.specFile]) grouped[test.specFile] = [];
214+
grouped[test.specFile].push(test);
215+
}
216+
return grouped;
217+
}
218+
198219
// Get failed tests with screenshots and errors
199-
function getFailedTestsWithScreenshotsAndErrors() {
200-
const failed = [];
220+
function getFailureBucketsWithDetails() {
221+
const unexpectedFailures = [];
222+
const expectedFailureTests = [];
201223
function walkSuites(suites, parentTitles = []) {
202224
for (const suite of suites) {
203225
const titles = [...parentTitles, suite.title];
@@ -231,55 +253,43 @@ async function main() {
231253
}
232254
}
233255

234-
failed.push({
256+
const record = {
235257
name: [...titles, spec.title].join(" › "),
236258
screenshot,
237259
error,
238260
status: finalResult.status,
239261
expectedFailure: isExpectedFailure(test, finalResult.status),
240-
});
262+
};
263+
264+
if (record.expectedFailure) {
265+
expectedFailureTests.push(record);
266+
} else {
267+
unexpectedFailures.push(record);
268+
}
241269
}
242270
}
243271
}
244272
if (suite.suites) walkSuites(suite.suites, titles);
245273
}
246274
}
247275
walkSuites(report.suites || []);
248-
return failed;
276+
return { unexpectedFailures, expectedFailureTests };
249277
}
250278

251-
const failedTests = getFailedTestsWithScreenshotsAndErrors();
252-
253-
// Group by spec file (first part of the name, before the first ' › ')
254-
const grouped = {};
255-
for (const test of failedTests) {
256-
const [specFile, ...rest] = test.name.split(" › ");
257-
const normalizedSpecFile = normalizeSummaryText(specFile);
258-
if (!grouped[normalizedSpecFile]) grouped[normalizedSpecFile] = [];
259-
grouped[normalizedSpecFile].push({
260-
name: normalizeSummaryText(rest.join(" › ")),
261-
screenshot: test.screenshot,
262-
error: normalizeSummaryText(test.error),
263-
status: test.status,
264-
expectedFailure: test.expectedFailure,
265-
});
266-
}
279+
const { unexpectedFailures, expectedFailureTests } = getFailureBucketsWithDetails();
280+
const groupedUnexpected = groupBySpec(unexpectedFailures.map(toSummaryRecord));
281+
const groupedExpected = groupBySpec(expectedFailureTests.map(toSummaryRecord));
267282

268283
// HTML output for better formatting and expand/collapse
269284
// Markdown output with collapsible sections and embedded screenshots
270285
let summary = `# Playwright Test Results Summary\n\n`;
271286
summary += `| Total | Passed | Failed | Errors | Expected Failures | Skipped |\n|-------|--------|--------|--------|-------------------|---------|\n| ${total} | ${passed} | ${failed} | ${errored} | ${expectedFailures} | ${skipped} |\n\n`;
272287

273-
const unexpectedFailures = failedTests.filter((t) => !t.expectedFailure);
274-
const expectedFailureTests = failedTests.filter((t) => t.expectedFailure);
275-
276288
if (unexpectedFailures.length === 0 && expectedFailureTests.length === 0) {
277289
summary += `## No failed tests!\n`;
278290
} else {
279-
function appendTestsByType(title, expectedFailureFlag) {
280-
const entries = Object.entries(grouped).filter(([, tests]) =>
281-
tests.some((t) => t.expectedFailure === expectedFailureFlag),
282-
);
291+
function appendGroupedTests(title, groupedTests) {
292+
const entries = Object.entries(groupedTests);
283293
if (entries.length === 0) {
284294
return;
285295
}
@@ -288,9 +298,6 @@ async function main() {
288298
for (const [specFile, tests] of entries) {
289299
summary += `<details><summary><strong>${specFile}</strong></summary>\n`;
290300
for (const test of tests) {
291-
if (test.expectedFailure !== expectedFailureFlag) {
292-
continue;
293-
}
294301
summary += `\n**${test.name}**\n`;
295302
summary += `_Status: ${test.status}${test.expectedFailure ? " (expected failure)" : ""}_\n`;
296303
if (test.screenshot) {
@@ -324,8 +331,8 @@ async function main() {
324331
}
325332
}
326333

327-
appendTestsByType("Unexpected Failures", false);
328-
appendTestsByType("Expected Failures", true);
334+
appendGroupedTests("Unexpected Failures", groupedUnexpected);
335+
appendGroupedTests("Expected Failures", groupedExpected);
329336
}
330337
fs.writeFileSync(outputSummaryPath, summary);
331338
console.log("Summary written to", outputSummaryPath);

0 commit comments

Comments
 (0)