Skip to content

Commit

Permalink
test(wpt): add results to an existing WPT Report
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Feb 21, 2023
1 parent e0fd923 commit f3de626
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 9 deletions.
68 changes: 61 additions & 7 deletions test/wpt/runner/runner/runner.mjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
import { deepStrictEqual } from 'node:assert'
import { EventEmitter, once } from 'node:events'
import { readdirSync, readFileSync, statSync } from 'node:fs'
import { readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'
import { basename, isAbsolute, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { Worker } from 'node:worker_threads'
import { parseMeta, handlePipes, normalizeName, colors } from './util.mjs'

const { WPT_REPORT } = process.env
const basePath = fileURLToPath(join(import.meta.url, '../../..'))
const testPath = join(basePath, 'tests')
const statusPath = join(basePath, 'status')

// https://github.com/web-platform-tests/wpt/blob/b24eedd/resources/testharness.js#L3705
function sanitizeUnpairedSurrogates (str) {
return str.replace(
/([\ud800-\udbff]+)(?![\udc00-\udfff])|(^|[^\ud800-\udbff])([\udc00-\udfff]+)/g,
function (_, low, prefix, high) {
let output = prefix || '' // Prefix may be undefined
const string = low || high // Only one of these alternates can match
for (let i = 0; i < string.length; i++) {
output += codeUnitStr(string[i])
}
return output
})
}

function codeUnitStr (char) {
return 'U+' + char.charCodeAt(0).toString(16)
}

export class WPTRunner extends EventEmitter {
/** @type {string} */
#folderName
Expand Down Expand Up @@ -40,16 +59,16 @@ export class WPTRunner extends EventEmitter {
skipped: 0
}

constructor (folder, url) {
constructor (name, url, folder = name) {
super()

this.#folderName = folder
this.#folderPath = join(testPath, folder)
this.#files.push(...WPTRunner.walk(
this.#folderPath,
(file) => file.endsWith('.js')
(file) => file.endsWith('.any.js') && !file.includes('.tentative.')
))
this.#status = JSON.parse(readFileSync(join(statusPath, `${folder}.status.json`)))
this.#status = JSON.parse(readFileSync(join(statusPath, `${name}.status.json`)))
this.#url = url

if (this.#files.length === 0) {
Expand Down Expand Up @@ -93,14 +112,18 @@ export class WPTRunner extends EventEmitter {
const code = test.includes('.sub.')
? handlePipes(readFileSync(test, 'utf-8'), this.#url)
: readFileSync(test, 'utf-8')
if (code.includes('importScripts(')) {
total -= 1
return undefined
}
const meta = this.resolveMeta(code, test)

if (meta.variant.length) {
total += meta.variant.length - 1
}

return [test, code, meta]
})
}).filter(Boolean)

for (const [test, code, meta] of files) {
if (this.#status[basename(test)]?.skip) {
Expand Down Expand Up @@ -134,13 +157,29 @@ export class WPTRunner extends EventEmitter {
}
})

let result, report
if (WPT_REPORT) {
report = JSON.parse(readFileSync(WPT_REPORT))

const fileUrl = new URL(`/${this.#folderName}${test.slice(this.#folderPath.length)}`, 'http://wpt')
fileUrl.pathname = fileUrl.pathname.replace(/\.js$/, '.html')
fileUrl.search = variant

result = {
test: fileUrl.href.slice(fileUrl.origin.length),
subtests: [],
status: 'OK'
}
report.results.push(result)
}

activeWorkers.add(worker)
// These values come directly from the web-platform-tests
const timeout = meta.timeout === 'long' ? 60_000 : 10_000

worker.on('message', (message) => {
if (message.type === 'result') {
this.handleIndividualTestCompletion(message, basename(test))
this.handleIndividualTestCompletion(message, basename(test), result)
} else if (message.type === 'completion') {
this.handleTestCompletion(worker)
}
Expand All @@ -155,9 +194,14 @@ export class WPTRunner extends EventEmitter {

console.log('='.repeat(96))
console.log(colors(`[${finishedFiles}/${total}] PASSED - ${test}`, 'green'))
if (variant) console.log('Variant:', variant)
console.log(`Test took ${(performance.now() - start).toFixed(2)}ms`)
console.log('='.repeat(96))

if (result?.subtests.length > 0) {
writeFileSync(WPT_REPORT, JSON.stringify(report))
}

finishedFiles++
} catch (e) {
console.log(`${test} timed out after ${timeout}ms`)
Expand All @@ -172,7 +216,7 @@ export class WPTRunner extends EventEmitter {
/**
* Called after a test has succeeded or failed.
*/
handleIndividualTestCompletion (message, fileName) {
handleIndividualTestCompletion (message, fileName, wptResult) {
const { fail, allowUnexpectedFailures, flaky } = this.#status[fileName] ?? this.#status

if (message.type === 'result') {
Expand All @@ -181,6 +225,12 @@ export class WPTRunner extends EventEmitter {
if (message.result.status === 1) {
this.#stats.failed += 1

wptResult?.subtests.push({
status: 'FAIL',
name: sanitizeUnpairedSurrogates(message.result.name),
message: sanitizeUnpairedSurrogates(message.result.message)
})

const name = normalizeName(message.result.name)

if (flaky?.includes(name)) {
Expand All @@ -196,6 +246,10 @@ export class WPTRunner extends EventEmitter {
console.error(message.result)
}
} else {
wptResult?.subtests.push({
status: 'PASS',
name: sanitizeUnpairedSurrogates(message.result.name)
})
this.#stats.success += 1
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/wpt/start-mimesniff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ child.on('exit', (code) => process.exit(code))

for await (const [message] of on(child, 'message')) {
if (message.server) {
const runner = new WPTRunner('mimesniff', message.server)
const runner = new WPTRunner('mimesniff', message.server, 'mimesniff/mime-types')
runner.run()

runner.once('completion', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/wpt/start-xhr.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WPTRunner } from './runner/runner/runner.mjs'
import { once } from 'events'

const runner = new WPTRunner('xhr', 'http://localhost:3333')
const runner = new WPTRunner('xhr', 'http://localhost:3333', 'xhr/formdata')
runner.run()

await once(runner, 'completion')

0 comments on commit f3de626

Please sign in to comment.