@@ -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