"""De logica van het invulmenu, uitgevoerd zoals de browser het doet. De stapindeling, de geavanceerd-schakelaar en het blokkeren van 'Volgende' zitten in JavaScript. Een Python-test kan daar niets over zeggen, dus draaien we de echte component uit index.html in Node. Zonder Node slaat dit zichzelf over. """ import shutil import subprocess from pathlib import Path import pytest WORTEL = Path(__file__).resolve().parent.parent SCRIPT = WORTEL / "tests" / "js" / "menu.test.js" @pytest.mark.skipif(not shutil.which("node"), reason="node ontbreekt") def test_invulmenu_logica(): r = subprocess.run(["node", str(SCRIPT)], capture_output=True, text=True, timeout=60, cwd=str(WORTEL)) assert r.returncode == 0, r.stdout + r.stderr @pytest.mark.skipif(not shutil.which("node"), reason="node ontbreekt") def test_installatiemodal_in_een_echte_dom(): """Rendert de modal met Alpine en klikt op Volgende. Losse logica zegt niets over de binding: `:disabled="lijst.length"` gaf bij een lege lijst 0, en Alpine haalt een boolean-attribuut alleen weg bij null, undefined of false — dus de knop stond juist uit. """ r = subprocess.run(["node", str(WORTEL / "tests" / "js" / "modal.dom.test.js")], capture_output=True, text=True, timeout=90, cwd=str(WORTEL)) if r.returncode == 2: pytest.skip(r.stdout.strip() or "jsdom ontbreekt") assert r.returncode == 0, r.stdout + r.stderr @pytest.mark.skipif(not shutil.which("node"), reason="node ontbreekt") def test_javascript_van_de_pagina_parseert(): """Een typefout in de component maakt de hele interface blanco; dat wil je niet pas in de browser ontdekken.""" import re html = (WORTEL / "server-up" / "templates" / "index.html").read_text(encoding="utf-8") blokken = re.findall(r"]*>(.*?)", html, re.S) grootste = max(blokken, key=len) r = subprocess.run(["node", "--check", "-"], input=grootste, capture_output=True, text=True, timeout=30) assert r.returncode == 0, r.stderr