/** Reporting contracts only; all subprocess fixtures are offline, without model services. */ import assert from 'node:assert/strict' import { spawnSync } from 'node:child_process' import { mkdir, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises' import path from 'node:path' import test from 'node:test' import { build } from 'esbuild' const env = { ...process.env } delete env.YCODE_TEST_DOM_MODULE delete env.YCODE_TEST_REQUIRE_DOM delete env.YCODE_ARCHIFY_ZIP const run = (args, overrides = {}, cwd = process.cwd()) => { const result = spawnSync(process.execPath, args, { cwd, env: { ...env, ...overrides }, encoding: 'utf8', timeout: 180000 }) assert.ifError(result.error) return result } const reports = (stdout) => stdout.split('\n').filter(line => line.startsWith('{')).flatMap(line => { try { return [JSON.parse(line)] } catch { return [] } }) test('alignment reports absent optional DOM coverage explicitly', () => { const result = run(['scripts/run-alignment-regression.mjs']) assert.equal(result.status, 0, result.stdout + result.stderr) const summary = reports(result.stdout) assert.ok(summary.some(item => item.phase === 'alignment-offline' && item.result === 'PASS')) assert.deepEqual(summary.filter(item => item.phase === 'alignment-dom').map(item => item.result), ['SKIP']) assert.match(summary.find(item => item.phase === 'alignment-dom').reason, /YCODE_TEST_DOM_MODULE/) }) for (const strict of ['flag', 'environment']) { test(`alignment requires DOM when requested by ${strict}`, () => { const result = run(['scripts/run-alignment-regression.mjs', ...(strict === 'flag' ? ['--require-dom'] : [])], strict === 'environment' ? { YCODE_TEST_REQUIRE_DOM: '1' } : {}) assert.equal(result.status, 1) assert.match(result.stderr, /FAIL alignment DOM: set YCODE_TEST_DOM_MODULE/) assert.equal(reports(result.stdout).length, 0) }) } test('alignment rejects an unloadable configured DOM module instead of skipping', () => { const result = run(['scripts/run-alignment-regression.mjs'], { YCODE_TEST_DOM_MODULE: 'ycode-deliberately-missing-dom-fixture' }) assert.equal(result.status, 1) assert.match(result.stderr, /FAIL alignment DOM: cannot load YCODE_TEST_DOM_MODULE/) }) test('backend never reports a skipped real package as PASS', async () => { await mkdir('.tmp', { recursive: true }) const temp = await mkdtemp(path.resolve('.tmp/reporting-test-')) try { const outfile = path.join(temp, 'backend.mjs') await build({ entryPoints: ['scripts/recommended-skills-backend-regression.ts'], outfile, bundle: true, platform: 'node', format: 'esm', external: ['esbuild'], logLevel: 'warning' }) // Isolate the default cache without changing a developer's optional package. await mkdir(path.join(temp, '.tmp')) await symlink(path.resolve('src'), path.join(temp, 'src'), 'junction') const result = run([outfile], {}, temp) assert.equal(result.status, 0, result.stdout + result.stderr) const summary = reports(result.stdout) assert.ok(summary.some(item => item.phase === 'required-offline' && item.result === 'PASS' && item.checks > 0)) assert.deepEqual(summary.filter(item => item.phase === 'real-package').map(item => item.result), ['SKIP']) assert.equal(summary.find(item => item.phase === 'real-package').checks, 0) const badOverride = run([outfile], { YCODE_ARCHIFY_ZIP: path.join(temp, 'absent.zip') }, temp) assert.equal(badOverride.status, 1) assert.match(badOverride.stderr, /Cannot read real-package fixture/) assert.equal(reports(badOverride.stdout).filter(item => item.phase === 'real-package').length, 0) } finally { await rm(temp, { recursive: true, force: true }) } }) test('alignment rejects a configured module without a JSDOM export', async () => { await mkdir('.tmp', { recursive: true }) const temp = await mkdtemp(path.resolve('.tmp/reporting-dom-test-')) try { const module = path.join(temp, 'not-jsdom.cjs') await writeFile(module, 'module.exports = {}\n') const result = run(['scripts/run-alignment-regression.mjs', '--require-dom'], { YCODE_TEST_DOM_MODULE: module }) assert.equal(result.status, 1) assert.match(result.stderr, /module does not export JSDOM/) } finally { await rm(temp, { recursive: true, force: true }) } })