import { test } from 'node:test'; import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import vm from 'node:vm'; import { fileURLToPath } from 'node:url'; import { SCENARIO_RECIPES, startPromptsFor } from '../recipes/scenarios.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const skillRoot = path.resolve(__dirname, '..'); const repoRoot = path.resolve(skillRoot, '..'); class FakeElement { constructor({ id = '', textContent = '', dataset = {} } = {}) { this.id = id; this.textContent = textContent; this.dataset = dataset; this.style = {}; this.attributes = {}; this.listeners = {}; this.tabIndex = 0; } setAttribute(name, value) { this.attributes[name] = String(value); } getAttribute(name) { return this.attributes[name]; } addEventListener(name, listener) { this.listeners[name] = listener; } replaceChildren(...children) { this.children = children; } appendChild() {} remove() {} select() {} focus() { this.focused = true; } click() { return this.listeners.click?.({ preventDefault() {} }); } dispatchKey(key) { return this.listeners.keydown?.({ key, preventDefault() {} }); } } function executeStartPage(html) { const dataMatch = html.match(/