// Minimal-DOM und Fake-fetch fuer Tests des Portal-Clients (public/termine*.js, public/funktion-bestellen.js) ohne Browser. Nicht Teil von npm test. // // const fx = installFakeDom({ antworten: [{ status: 400, body: { fehler: {...} } }] }) // try { ...Client-Code bauen, fx.klick(knopf), fx.fetchLog pruefen... } finally { fx.restore() } // // installFakeDom stellt `document`, `window` (nur location mit href, pathname, search, hash und history.replaceState), `CSS.escape` und `fetch` auf globalThis, restore() stellt den // alten Zustand wieder her. `h` aus public/termine-dom.js liest `document` bei jedem Aufruf: der Client braucht keine Einhaengepunkte. // Wurzeln, die `isConnected` brauchen (neuerSpeicher.nochHier), haengt der Test selbst an `document.body`. // // Elemente: createElement, setAttribute/getAttribute/hasAttribute/removeAttribute, append/prepend/appendChild/insertBefore/replaceChildren/remove, // children/childNodes/parentNode/parentElement/firstChild/lastChild/firstElementChild/lastElementChild, className/classList/id/dataset/hidden/ // disabled/tabIndex/type/name, value/checked/selected (Eigenschaft ueberdeckt das Attribut wie im Browser; select.value ist die gewaehlte // Option, ohne Wahl die erste), textContent, isConnected, closest/matches/querySelector/querySelectorAll, focus (document.activeElement)/blur/ // select/scrollIntoView, addEventListener/dispatchEvent (Ereignisse steigen zu den Eltern auf, preventDefault/stopPropagation). // Selektoren: Tag, *, #id, .klasse, [attr], [attr="wert"], :not(…), :disabled, :enabled, :checked, Komma, Leerzeichen und >. // // Der Fake-fetch schreibt jeden Aufruf als { method, url, body } (body = geparstes JSON oder undefined) in fetchLog und antwortet mit dem naechsten // Eintrag aus `antworten` ({ status, body } oder eine Funktion (aufruf) => { status, body }); ohne Eintrag 200 mit {}. // klick, setze, sende und ruhe liefern ein Promise: die Wirkung der Ereignisse (auch von async-Handlern) ist erst danach da, also `await fx.klick(…)`. // klick wirkt wie ein Klick im Browser (Haken und Radio schalten, „submit“-Knopf sendet das Formular, gesperrte Elemente tun nichts); ein Klick auf ein //