@@ -5,6 +5,7 @@ const fixtures = require('../common/fixtures');
55const fs = require ( 'fs' ) ;
66const fsPromises = fs . promises ;
77const path = require ( 'path' ) ;
8+ const events = require ( 'events' ) ;
89const { inspect } = require ( 'util' ) ;
910const { Worker } = require ( 'worker_threads' ) ;
1011
@@ -152,21 +153,30 @@ class WPTTestSpec {
152153this . filename = filename ;
153154
154155this . requires = new Set ( ) ;
155- this . failReasons = [ ] ;
156+ this . failedTests = [ ] ;
157+ this . flakyTests = [ ] ;
156158this . skipReasons = [ ] ;
157159for ( const item of rules ) {
158160if ( item . requires . length ) {
159161for ( const req of item . requires ) {
160162this . requires . add ( req ) ;
161163}
162164}
163- if ( item . fail ) {
164- this . failReasons . push ( item . fail ) ;
165+ if ( Array . isArray ( item . fail ?. expected ) ) {
166+ this . failedTests . push ( ...item . fail . expected ) ;
167+ }
168+ if ( Array . isArray ( item . fail ?. flaky ) ) {
169+ this . failedTests . push ( ...item . fail . flaky ) ;
170+ this . flakyTests . push ( ...item . fail . flaky ) ;
165171}
166172if ( item . skip ) {
167173this . skipReasons . push ( item . skip ) ;
168174}
169175}
176+
177+ this . failedTests = [ ...new Set ( this . failedTests ) ] ;
178+ this . flakyTests = [ ...new Set ( this . flakyTests ) ] ;
179+ this . skipReasons = [ ...new Set ( this . skipReasons ) ] ;
170180}
171181
172182getRelativePath ( ) {
@@ -368,7 +378,7 @@ class WPTRunner {
368378
369379// TODO(joyeecheung): work with the upstream to port more tests in .html
370380// to .js.
371- runJsTests ( ) {
381+ async runJsTests ( ) {
372382let queue = [ ] ;
373383
374384// If the tests are run as `node test/wpt/test-something.js subset.any.js`,
@@ -459,6 +469,8 @@ class WPTRunner {
459469) ;
460470this . inProgress . delete ( testFileName ) ;
461471} ) ;
472+
473+ await events . once ( worker , 'exit' ) . catch ( ( ) => { } ) ;
462474}
463475
464476process . on ( 'exit' , ( ) => {
@@ -469,34 +481,72 @@ class WPTRunner {
469481}
470482}
471483inspect . defaultOptions . depth = Infinity ;
472- console . log ( this . results ) ;
484+ // Sorts the rules to have consistent output
485+ console . log ( JSON . stringify ( Object . keys ( this . results ) . sort ( ) . reduce (
486+ ( obj , key ) => {
487+ obj [ key ] = this . results [ key ] ;
488+ return obj ;
489+ } ,
490+ { }
491+ ) , null , 2 ) ) ;
473492
474493const failures = [ ] ;
475494let expectedFailures = 0 ;
476495let skipped = 0 ;
477- for ( const key of Object . keys ( this . results ) ) {
478- const item = this . results [ key ] ;
479- if ( item . fail && item . fail . unexpected ) {
496+ for ( const [ key , item ] of Object . entries ( this . results ) ) {
497+ if ( item . fail ?. unexpected ) {
480498failures . push ( key ) ;
481499}
482- if ( item . fail && item . fail . expected ) {
500+ if ( item . fail ? .expected ) {
483501expectedFailures ++ ;
484502}
485503if ( item . skip ) {
486504skipped ++ ;
487505}
488506}
507+
508+ const unexpectedPasses = [ ] ;
509+ for ( const [ key , specMap ] of this . specMap ) {
510+ // File has no expected failures
511+ if ( ! specMap . failedTests . length ) {
512+ continue ;
513+ }
514+
515+ // File was (maybe even conditionally) skipped
516+ if ( this . results [ key ] ?. skip ) {
517+ continue ;
518+ }
519+
520+ // Full check: every expected to fail test is present
521+ if ( specMap . failedTests . some ( ( expectedToFail ) => {
522+ if ( specMap . flakyTests . includes ( expectedToFail ) ) {
523+ return false ;
524+ }
525+ return this . results [ key ] ?. fail ?. expected ?. includes ( expectedToFail ) !== true ;
526+ } ) ) {
527+ unexpectedPasses . push ( key ) ;
528+ continue ;
529+ }
530+ }
531+
489532const ran = total - skipped ;
490533const passed = ran - expectedFailures - failures . length ;
491534console . log ( `Ran ${ ran } /${ total } tests, ${ skipped } skipped,` ,
492535`${ passed } passed, ${ expectedFailures } expected failures,` ,
493- `${ failures . length } unexpected failures` ) ;
536+ `${ failures . length } unexpected failures,` ,
537+ `${ unexpectedPasses . length } unexpected passes` ) ;
494538if ( failures . length > 0 ) {
495539const file = path . join ( 'test' , 'wpt' , 'status' , `${ this . path } .json` ) ;
496540throw new Error (
497541`Found ${ failures . length } unexpected failures. ` +
498542`Consider updating ${ file } for these files:\n${ failures . join ( '\n' ) } ` ) ;
499543}
544+ if ( unexpectedPasses . length > 0 ) {
545+ const file = path . join ( 'test' , 'wpt' , 'status' , `${ this . path } .json` ) ;
546+ throw new Error (
547+ `Found ${ unexpectedPasses . length } unexpected passes. ` +
548+ `Consider updating ${ file } for these files:\n${ unexpectedPasses . join ( '\n' ) } ` ) ;
549+ }
500550} ) ;
501551}
502552
@@ -577,8 +627,9 @@ class WPTRunner {
577627if ( ! result [ item . status ] [ key ] ) {
578628result [ item . status ] [ key ] = [ ] ;
579629}
580- if ( result [ item . status ] [ key ] . indexOf ( item . reason ) === - 1 ) {
581- result [ item . status ] [ key ] . push ( item . reason ) ;
630+ const hasName = result [ item . status ] [ key ] . includes ( item . name ) ;
631+ if ( ! hasName ) {
632+ result [ item . status ] [ key ] . push ( item . name ) ;
582633}
583634}
584635}
@@ -589,10 +640,10 @@ class WPTRunner {
589640
590641fail ( filename , test , status ) {
591642const spec = this . specMap . get ( filename ) ;
592- const expected = ! ! ( spec . failReasons . length ) ;
643+ const expected = spec . failedTests . includes ( test . name ) ;
593644if ( expected ) {
594645console . log ( `[EXPECTED_FAILURE][${ status . toUpperCase ( ) } ] ${ test . name } ` ) ;
595- console . log ( spec . failReasons . join ( '; ' ) ) ;
646+ console . log ( test . message || status ) ;
596647} else {
597648console . log ( `[UNEXPECTED_FAILURE][${ status . toUpperCase ( ) } ] ${ test . name } ` ) ;
598649}
@@ -604,6 +655,7 @@ class WPTRunner {
604655` ${ require . main . filename } ${ filename } ` ;
605656console . log ( `Command: ${ command } \n` ) ;
606657this . addTestResult ( filename , {
658+ name : test . name ,
607659 expected,
608660status : kFail ,
609661reason : test . message || status
0 commit comments