|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +const common = require('../common'); |
| 4 | +const assert = require('assert'); |
| 5 | +const fs = require('fs'); |
| 6 | +const path = require('path'); |
| 7 | +const { spawnSync } = require('child_process'); |
| 8 | +const tmpdir = require('../common/tmpdir'); |
| 9 | + |
| 10 | +if (process.env.NODE_TEST_WPT_REPORT_DIR) { |
| 11 | + const { WPTRunner } = require('../common/wpt'); |
| 12 | + const runner = new WPTRunner('html/webappapis/atob'); |
| 13 | + runner.report.filepath = path.join(process.env.NODE_TEST_WPT_REPORT_DIR, runner.report.filename); |
| 14 | + runner.runJsTests(); |
| 15 | +} else if (process.env.NODE_TEST_WPT_QUERY_PROBE) { |
| 16 | + const { WPTRunner, WPTTestSpec } = require('../common/wpt'); |
| 17 | + const runner = new WPTRunner('compression'); |
| 18 | + if (runner.managed?.mode === 'run') assert.strictEqual(runner.concurrency, 1); |
| 19 | + runner.specs = new Set(['?pass', '?fail'].map((query) => { |
| 20 | + const spec = new WPTTestSpec('compression', 'compression-bad-chunks.any.js', [], query, 'window'); |
| 21 | + spec.failedTests = ['expected across queries']; |
| 22 | + if (process.env.NODE_TEST_WPT_QUERY_PROBE === 'flaky' || |
| 23 | + (process.env.NODE_TEST_WPT_QUERY_PROBE === 'mixed' && query === '?pass')) { |
| 24 | + spec.flakyTests = [...spec.failedTests]; |
| 25 | + } |
| 26 | + return spec; |
| 27 | + })); |
| 28 | + runner.setScriptModifier((script) => { |
| 29 | + if (!script.filename.endsWith('compression-bad-chunks.any.js')) return; |
| 30 | + script.code = `test(() => assert_true(${process.env.NODE_TEST_WPT_QUERY_PROBE === 'missing'} || |
| 31 | + location.search === '?pass'), 'expected across queries');`; |
| 32 | + }); |
| 33 | + runner.runJsTests(); |
| 34 | +} else { |
| 35 | + main(); |
| 36 | +} |
| 37 | + |
| 38 | +function main() { |
| 39 | + tmpdir.refresh(); |
| 40 | + const env = { ...process.env }; |
| 41 | + for (const key of ['NODE_TEST_WPT', 'WPT_REPORT', 'WPT_INSPECT']) delete env[key]; |
| 42 | + const driver = (name) => path.join(__dirname, '../wpt', `test-${name}.js`); |
| 43 | + function invoke(file, config, overrides = {}, status = 0) { |
| 44 | + const result = spawnSync(process.execPath, [file], { |
| 45 | + env: { ...env, ...overrides, NODE_TEST_WPT: JSON.stringify(config) }, |
| 46 | + encoding: 'utf8', timeout: common.platformTimeout(10_000), |
| 47 | + maxBuffer: 10 * 1024 * 1024, |
| 48 | + }); |
| 49 | + assert.ifError(result.error); |
| 50 | + assert.strictEqual(result.status, status, result.stdout + result.stderr); |
| 51 | + return result.stdout + result.stderr; |
| 52 | + } |
| 53 | + |
| 54 | + function discover(name, overrides, file = driver(name)) { |
| 55 | + const stdout = invoke(file, { mode: 'list' }, overrides); |
| 56 | + const lines = stdout.split('\n').filter((line) => line.startsWith('NODE_TEST_WPT_MANIFEST:')); |
| 57 | + assert.strictEqual(lines.length, 1); |
| 58 | + assert.doesNotMatch(stdout, /\[PASS\]/); |
| 59 | + const manifest = JSON.parse(lines[0].slice('NODE_TEST_WPT_MANIFEST:'.length)); |
| 60 | + assert.strictEqual(manifest.version, 1); |
| 61 | + assert.strictEqual(new Set(manifest.tests.map((test) => test.id)).size, manifest.tests.length); |
| 62 | + return manifest; |
| 63 | + } |
| 64 | + |
| 65 | + const atob = discover('atob'); |
| 66 | + assert.strictEqual(atob.serial, false); |
| 67 | + assert.deepStrictEqual(atob.tests.map((test) => test.id), ['base64.any.html', 'base64.any.worker.html']); |
| 68 | + const reportRoot = path.join(tmpdir.path, 'reports'); |
| 69 | + const canReport = ['darwin', 'linux', 'win32'].includes(process.platform); |
| 70 | + if (canReport) fs.mkdirSync(reportRoot, { recursive: true }); |
| 71 | + for (const [index, group] of atob.tests.entries()) { |
| 72 | + const serial = `group-probe-${process.pid}-${index}`; |
| 73 | + const reportPath = path.join(reportRoot, `report-html-webappapis-atob-${serial}.json`); |
| 74 | + try { |
| 75 | + const stdout = invoke(canReport ? __filename : driver('atob'), |
| 76 | + { mode: 'run', source: group.source, key: group.key, variant: group.variant }, canReport ? { |
| 77 | + WPT_REPORT: '1', TEST_SERIAL_ID: serial, NODE_TEST_WPT_REPORT_DIR: reportRoot, |
| 78 | + } : {}); |
| 79 | + const results = stdout.split('\n').filter((line) => line.startsWith('[PASS]')); |
| 80 | + assert.ok(results.length > 0); |
| 81 | + assert.ok(results.every((line) => line.includes(`${group.id}:`))); |
| 82 | + if (canReport) { |
| 83 | + const report = JSON.parse(fs.readFileSync(reportPath, 'utf8')); |
| 84 | + assert.deepStrictEqual(report.results.map((result) => result.test), |
| 85 | + [`/html/webappapis/atob/${group.id}`]); |
| 86 | + } |
| 87 | + } finally { |
| 88 | + fs.rmSync(reportPath, { force: true }); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + const encoding = discover('encoding'); |
| 93 | + const queryGroups = encoding.tests.filter((test) => test.source === 'api-invalid-label.any.js'); |
| 94 | + assert.strictEqual(queryGroups.length, 8); |
| 95 | + assert.deepStrictEqual([...new Set(queryGroups.map((test) => test.key))], |
| 96 | + ['api-invalid-label.any.html', 'api-invalid-label.any.worker.html']); |
| 97 | + const timers = discover('timers'); |
| 98 | + assert.strictEqual(timers.serial, true); |
| 99 | + const skipped = timers.tests.find((test) => test.source === 'negative-settimeout.any.js'); |
| 100 | + assert.ok(skipped); |
| 101 | + const skippedOutput = invoke(driver('timers'), { mode: 'run', source: skipped.source, key: skipped.key }); |
| 102 | + assert.match(skippedOutput, /\[SKIPPED\].*unreliable in Node\.js/); |
| 103 | + assert.match(skippedOutput, /1\.\.0 # SKIP/); |
| 104 | + assert.doesNotMatch(skippedOutput, /\[PASS\]/); |
| 105 | + |
| 106 | + if (common.hasSQLite) { |
| 107 | + const root = path.join(tmpdir.path, 'discovery'); |
| 108 | + const directory = path.join(root, '.tmp.probe'); |
| 109 | + fs.mkdirSync(directory, { recursive: true }); |
| 110 | + const sentinel = path.join(directory, 'sentinel'); |
| 111 | + fs.writeFileSync(sentinel, 'preserved'); |
| 112 | + assert.strictEqual(discover('webstorage', { NODE_TEST_DIR: root, TEST_SERIAL_ID: 'probe' }).serial, true); |
| 113 | + assert.strictEqual(fs.readFileSync(sentinel, 'utf8'), 'preserved'); |
| 114 | + } |
| 115 | + |
| 116 | + const config = { mode: 'run', source: 'compression-bad-chunks.any.js', key: 'compression-bad-chunks.any.html' }; |
| 117 | + for (const probe of ['combined', 'mixed']) { |
| 118 | + const strict = discover('compression', { NODE_TEST_WPT_QUERY_PROBE: probe }, __filename); |
| 119 | + assert.deepStrictEqual(strict.tests, [{ |
| 120 | + source: config.source, key: config.key, id: config.key, selector: `compression/${config.key}`, |
| 121 | + }]); |
| 122 | + } |
| 123 | + const flaky = discover('compression', { NODE_TEST_WPT_QUERY_PROBE: 'flaky' }, __filename); |
| 124 | + assert.deepStrictEqual(flaky.tests.map((test) => test.variant).sort(), ['?fail', '?pass']); |
| 125 | + assert.deepStrictEqual(flaky.tests.map((test) => test.id).sort(), |
| 126 | + [`${config.key}?fail`, `${config.key}?pass`]); |
| 127 | + const single = invoke(__filename, { ...config, variant: '?pass' }, { NODE_TEST_WPT_QUERY_PROBE: 'flaky' }); |
| 128 | + assert.match(single, /\.any\.html\?pass:/); |
| 129 | + assert.doesNotMatch(single, /\.any\.html\?fail:/); |
| 130 | + const combined = invoke(__filename, config, { NODE_TEST_WPT_QUERY_PROBE: 'combined' }); |
| 131 | + assert.match(combined, /\.any\.html\?pass:/); |
| 132 | + assert.match(combined, /\.any\.html\?fail:/); |
| 133 | + const missing = invoke(__filename, config, { NODE_TEST_WPT_QUERY_PROBE: 'missing' }, 1); |
| 134 | + assert.match(missing, /Found 2 unexpected passes/); |
| 135 | + |
| 136 | + for (const query of ['', '?fail']) { |
| 137 | + const direct = spawnSync(process.execPath, [__filename, `compression/${config.key}${query}`], { |
| 138 | + env: { ...env, NODE_TEST_WPT_QUERY_PROBE: 'combined' }, |
| 139 | + encoding: 'utf8', timeout: common.platformTimeout(10_000), |
| 140 | + }); |
| 141 | + assert.ifError(direct.error); |
| 142 | + assert.strictEqual(direct.status, 0, direct.stdout + direct.stderr); |
| 143 | + assert.match(direct.stdout, /\.any\.html\?fail:/); |
| 144 | + if (query) assert.doesNotMatch(direct.stdout, /\.any\.html\?pass:/); |
| 145 | + else assert.match(direct.stdout, /\.any\.html\?pass:/); |
| 146 | + } |
| 147 | +} |
0 commit comments