/* UI-Integrationstest (jsdom) gegen einen echten Server-Subprozess. * * Lauf: node tests/test_ui.js (jsdom muss installierbar sein, z.B. * NODE_PATH=/pfad/zu/node_modules node tests/test_ui.js) * * Der Test laeuft im offenen Modus (frische DB ohne Benutzer). */ const path = require("path"); const BASE = path.join(__dirname, ".."); let jsdom; try { jsdom = require("jsdom"); } catch (_) { console.error("jsdom fehlt. Installieren: npm install jsdom@22.1.0 (z.B. in /tmp/tp_test) und mit NODE_PATH=/node_modules starten."); process.exit(2); } const { JSDOM } = jsdom; const { spawn } = require("child_process"); const fs = require("fs"); const http = require("http"); const STATE = "/tmp/tp_state_ui"; const PORT = 8233; const BASE_URL = `http://127.0.0.1:${PORT}`; let pass = 0, fail = 0; let jsErrors = []; function check(name, cond, detail = "") { if (cond) { pass++; console.log(" ok " + name); } else { fail++; console.log("FAIL " + name + " " + detail); } } const sleep = ms => new Promise(r => setTimeout(r, ms)); async function waitFor(dom, fn, timeout = 4000) { const t0 = Date.now(); while (Date.now() - t0 < timeout) { if (fn(dom)) return true; await sleep(80); } return false; } function apiGet(p) { return new Promise((resolve, reject) => { http.get(BASE_URL + p, res => { let d = ""; res.on("data", c => d += c); res.on("end", () => resolve(JSON.parse(d))); }).on("error", reject); }); } function cleanState() { fs.rmSync(STATE, { recursive: true, force: true }); fs.mkdirSync(STATE, { recursive: true }); } async function main() { cleanState(); const server = spawn("python3", [path.join(BASE, "server.py")], { env: { ...process.env, TRAINING_STATE_DIR: STATE, PORT: String(PORT) }, cwd: BASE, stdio: "ignore", }); let window; try { for (let i = 0; i < 60; i++) { try { await apiGet("/api/meta"); break; } catch (_) { await sleep(200); } } const html = fs.readFileSync(path.join(BASE, "index.html"), "utf8") .replace(/