"""Prueft die Struktur der Oberflaechen ohne Browser.
Faengt genau die Fehler, die eine Syntaxpruefung durchlaesst. Ein onclick, das
auf eine nicht vorhandene Methode zeigt. Ein Feld, das das Skript sucht, das
im Dokument aber fehlt. Eine ID, die zweimal vergeben ist. Ein vergessener
Cache-Buster.
Aufruf aus dem Projektstamm:
python3 tests/test_studio_struktur.py
"""
import os
import re
import sys
STAMM = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC = os.path.join(STAMM, "src", "static")
ok = 0
fehl = 0
def pruefe(name, bedingung, extra=None):
global ok, fehl
if bedingung:
ok += 1
print(f" OK {name}")
else:
fehl += 1
print(f" FEHL {name}" + (f" {extra}" if extra is not None else ""))
def lies(*teile):
with open(os.path.join(STATIC, *teile), encoding="utf-8") as f:
return f.read()
studio_html = lies("studio.html")
studio_js = lies("js", "studio.js")
dash_html = lies("dashboard.html")
app_js = lies("js", "app.js")
comp_js = lies("js", "components.js")
style = lies("css", "style.css")
studio_css = lies("css", "studio.css")
def ids(html):
return re.findall(r'\bid="([^"]+)"', html)
def doppelte(liste):
gesehen, doppelt = set(), []
for x in liste:
if x in gesehen:
doppelt.append(x)
gesehen.add(x)
return doppelt
print("\nA) IDs sind eindeutig")
for name, html in [("studio.html", studio_html), ("dashboard.html", dash_html)]:
d = doppelte(ids(html))
pruefe(f"A keine doppelte ID in {name}", not d, d)
print("\nB) Der Einstellungen-Reiter ist vollstaendig verdrahtet")
# Alle Felder, die die Logik anfasst, muessen im Dokument stehen.
gesucht = sorted(set(re.findall(r"_setEl\('([^']+)'\)", studio_js)))
vorhanden = set(ids(studio_html))
fehlend = [f for f in gesucht if f not in vorhanden]
pruefe("B1 jedes angesprochene Feld existiert", not fehlend, fehlend)
pruefe("B2 es sind auch wirklich welche geprueft", len(gesucht) >= 15, len(gesucht))
# Panel und Navigationsknopf haengen am selben Schluessel.
pruefe("B3 Navigationsknopf vorhanden",
'data-art="settings" onclick="Studio.openTab(\'settings\')"' in studio_html)
pruefe("B4 Panel vorhanden", '
' in studio_html)
pruefe("B5 activateTab kennt den Reiter",
"if (key === 'settings') this.loadSettings();" in studio_js)
print("\nC) Jedes onclick zeigt auf eine vorhandene Methode")
for name, html, js, praefix in [
("studio", studio_html, studio_js, "Studio"),
("dashboard", dash_html, app_js + comp_js, "App"),
]:
aufgerufen = sorted(set(re.findall(praefix + r"\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\(", html)))
fehlend = []
for m in aufgerufen:
# Methoden stehen als " name(" oder " async name(" im Objektliteral
if not re.search(r"^\s+(async\s+)?" + re.escape(m) + r"\s*\(", js, re.M):
fehlend.append(m)
pruefe(f"C {name}.html ruft nur vorhandene Methoden ({len(aufgerufen)} geprueft)",
not fehlend, fehlend)
print("\nD) Der KI-Weg ist in beiden Ansichten gleich angeboten")
for name, html, feld in [("studio.html", studio_html, "set-ai-backend"),
("studio.html anlegen", studio_html, "inc-ai-backend"),
("dashboard.html", dash_html, "inc-ai-backend")]:
block = re.search(r'