@@ -8,11 +8,11 @@ const path = require('path');
88const events = require ( 'events' ) ;
99const os = require ( 'os' ) ;
1010const { inspect } = require ( 'util' ) ;
11+ const { pathToFileURL } = require ( 'url' ) ;
1112const { Worker } = require ( 'worker_threads' ) ;
1213const { fork } = require ( 'child_process' ) ;
1314
1415const workerPath = path . join ( __dirname , 'wpt/worker.js' ) ;
15- const kRunWorkerGlobals = false ;
1616const wptNonTestDirs = new Set ( [ 'resources' , 'support' , 'tools' ] ) ;
1717
1818function getBrowserProperties ( ) {
@@ -191,6 +191,24 @@ class ResourceLoader {
191191 fixtures . path ( 'wpt' , base , url ) ;
192192 }
193193
194+ /**
195+ * Map a URL that a test would have fetched from the WPT server (an
196+ * absolute path, or a path relative to the test file) to a file: URL
197+ * into the fixtures directory. URLs that already have a scheme (data:,
198+ * blob:, http:, ...) are returned unchanged.
199+ * @param {string } from the path of the file loading this resource,
200+ * relative to the WPT folder.
201+ * @param {string|URL } url the url of the resource being loaded.
202+ * @returns {string }
203+ */
204+ mapServerURL ( from , url ) {
205+ url = `${ url } ` ;
206+ if ( / ^ [ a - z A - Z ] [ a - z A - Z 0 - 9 + . - ] * : | ^ \/ \/ / . test ( url ) ) {
207+ return url ;
208+ }
209+ return pathToFileURL ( this . toRealFilePath ( from , url ) ) . href ;
210+ }
211+
194212 /**
195213 * Load a resource in test/fixtures/wpt specified with a URL
196214 * @param {string } from the path of the file loading this resource,
@@ -818,7 +836,11 @@ class WPTRunner {
818836 this . resource = new ResourceLoader ( path ) ;
819837 this . concurrency = concurrency ;
820838
821- this . flags = [ ] ;
839+ // Since we need to prepare the Web Worker APIs
840+ // in the harness that runs on all WPT workers,
841+ // we enable the API globally. This has no practical
842+ // effect on the non-web-worker tests, however.
843+ this . flags = [ '--experimental-web-worker' ] ;
822844 this . globalThisInitScripts = [ ] ;
823845 this . initScript = null ;
824846
@@ -845,7 +867,7 @@ class WPTRunner {
845867 * @param {string[] } flags
846868 */
847869 setFlags ( flags ) {
848- this . flags = flags ;
870+ this . flags = this . flags . concat ( flags ) ;
849871 }
850872
851873 /**
@@ -933,22 +955,33 @@ class WPTRunner {
933955 const absolutePath = spec . getAbsolutePath ( ) ;
934956 const relativePath = spec . getRelativePath ( ) ;
935957 const harnessPath = fixtures . path ( 'wpt' , 'resources' , 'testharness.js' ) ;
936- // Scripts specified with the `// META: script=` header
937- const scriptsToRun = meta . script ?. map ( ( script ) => {
958+ // *.worker.js tests are dedicated worker tests by definition. Each
959+ // dedicated worker variant generated from a multi-global (*.any.js)
960+ // test also runs inside an actual Web Worker. Refs:
961+ // https://web-platform-tests.org/writing-tests/testharness.html#multi-global-tests
962+ const isAnyTest = spec . isAnyTest ( ) ;
963+ const isWebWorkerTest = spec . isWebWorkerTest ( ) ;
964+
965+ // Scripts specified with the `// META: script=` header. For tests
966+ // that run inside a Web Worker they are imported by the worker
967+ // instead.
968+ const scriptsToRun = isWebWorkerTest ? [ ] : meta . script ?. map ( ( script ) => {
938969 const obj = {
939970 filename : this . resource . toRealFilePath ( relativePath , script ) ,
940971 code : this . resource . read ( relativePath , script ) ,
941972 } ;
942973 this . scriptsModifier ?. ( obj ) ;
943974 return obj ;
944975 } ) ?? [ ] ;
945- // The actual test
946- const obj = {
947- code : content ,
948- filename : absolutePath ,
949- } ;
950- this . scriptsModifier ?. ( obj ) ;
951- scriptsToRun . push ( obj ) ;
976+ if ( ! isWebWorkerTest ) {
977+ // The actual test
978+ const obj = {
979+ code : content ,
980+ filename : absolutePath ,
981+ } ;
982+ this . scriptsModifier ?. ( obj ) ;
983+ scriptsToRun . push ( obj ) ;
984+ }
952985
953986 jobs . push ( run ( async ( ) => {
954987 this . inProgress . add ( spec ) ;
@@ -964,6 +997,18 @@ class WPTRunner {
964997 filename : harnessPath ,
965998 } ,
966999 scriptsToRun,
1000+ // Set when the test runs inside an actual Web Worker.
1001+ webWorker : isWebWorkerTest ? {
1002+ path : absolutePath ,
1003+ isAnyTest,
1004+ initScript : this . initScript ,
1005+ title : meta . title ,
1006+ variant : spec . variant ,
1007+ scripts : meta . script ?. map (
1008+ ( script ) => this . resource . toRealFilePath ( relativePath , script ) ,
1009+ ) ?? [ ] ,
1010+ skippedTests : spec . skippedTests ,
1011+ } : undefined ,
9671012 needsGc : ! ! meta . script ?. find ( ( script ) => script === '/common/gc.js' ) ,
9681013 skippedTests : spec . skippedTests ,
9691014 } , {
@@ -1255,10 +1300,6 @@ class WPTRunner {
12551300 this . skippedSpecCount = 0 ;
12561301 const arg = process . argv [ 2 ] ;
12571302 for ( const spec of this . specs ) {
1258- if ( ! kRunWorkerGlobals && spec . isWebWorkerTest ( ) ) {
1259- continue ;
1260- }
1261-
12621303 if ( arg ) {
12631304 if ( spec . isSelectedBy ( arg ) ) {
12641305 queue . push ( spec ) ;
@@ -1281,13 +1322,11 @@ class WPTRunner {
12811322 }
12821323
12831324 // If the tests are run as `node test/wpt/test-something.js subset.any.js`,
1284- // only `subset.any.js` (all enabled variants and globals) will be run by
1285- // the runner.
1325+ // only `subset.any.js` (all variants and globals) will be run by the runner.
12861326 // If the tests are run as `node test/wpt/test-something.js 'subset.any.js?1-10'`,
12871327 // only the `?1-10` variant of `subset.any.js` will be run by the runner.
12881328 // A test path as printed with the results, e.g.
1289- // `'dir/subset.any.worker.html?1-10'`, runs exactly that one when its
1290- // global is enabled.
1329+ // `'dir/subset.any.worker.html?1-10'`, runs exactly that one.
12911330 if ( arg && queue . length === 0 ) {
12921331 throw new Error ( `${ arg } not found!` ) ;
12931332 }
0 commit comments