Regelwerk, Agenten, Skills und Werkzeuge veröffentlichen
Erster Stand des öffentlichen Ausschnitts aus dem Vault. Die .gitignore arbeitet als Positivliste: ausgeschlossen ist alles, eingeschlossen nur, was ausdrücklich wieder aufgenommen wird. Notizen, Projekte, Finanzen, das Sitzungsgedächtnis und settings.local.json bleiben damit außen vor. Der Kundenname in AI/Regelwerk/seo.md ist durch eine neutrale Bezeichnung ersetzt; die Regeln selbst sind unverändert. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
commit
2c9a4475fc
97 files changed
+14627
No files matched your search
@@ -0,0 +1,115 @@
|
||||
"""Wiederaufbau-Test im Browser: Backend weg, Backend wieder da -- ohne Neuladen der Seite.
|
||||
|
||||
Koordinator-Pruefskript (Windows-Python mit Playwright), nicht fuers Repo.
|
||||
Frage: Zeigt die Kopfzeile "Backend getrennt", wenn das Backend stirbt, und von selbst wieder
|
||||
"Backend verbunden", wenn es zurueck ist? Herkunft: Projektvorgabe (Spec, Abschnitt Frontend).
|
||||
Statustexte aus dashboard/src/components/Kopfzeile.tsx (abgeschrieben am 2026-09-17).
|
||||
Was es nicht sieht: die Wartezeiten 1/2/5/10 s im Einzelnen (dafuer api.test.ts), andere Browser als Chromium.
|
||||
Regressionsnachweis: --ohne-neustart laesst das Backend unten; der Lauf muss dann mit Exit 2 am Schritt
|
||||
"wieder verbunden" enden.
|
||||
Aufruf: python -X utf8 wiederaufbau.py [--ohne-neustart]
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
from playwright.sync_api import TimeoutError as PlaywrightTimeout
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
PORT = 8146
|
||||
BASIS = f"http://localhost:{PORT}"
|
||||
HIER = Path(__file__).parent
|
||||
|
||||
|
||||
def starte_backend() -> subprocess.Popen:
|
||||
skript = open(HIER / "start_probe.sh", "rb")
|
||||
return subprocess.Popen(
|
||||
["wsl", "-d", "Debian", "--", "bash", "-s", str(PORT), "1.0"],
|
||||
stdin=skript, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||
)
|
||||
|
||||
|
||||
def beende_backend() -> None:
|
||||
subprocess.run(["wsl", "-d", "Debian", "--", "pkill", "-f", f"start_probe_backend.py {PORT}"],
|
||||
stdin=subprocess.DEVNULL, capture_output=True)
|
||||
|
||||
|
||||
def warte_auf_backend(sekunden: float) -> bool:
|
||||
ende = time.time() + sekunden
|
||||
while time.time() < ende:
|
||||
try:
|
||||
with urllib.request.urlopen(BASIS + "/api/uebersicht", timeout=1) as antwort:
|
||||
if antwort.status == 200:
|
||||
return True
|
||||
except OSError:
|
||||
time.sleep(0.5)
|
||||
return False
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ohne_neustart = "--ohne-neustart" in sys.argv
|
||||
beende_backend()
|
||||
prozess = starte_backend()
|
||||
schritte: list[str] = []
|
||||
try:
|
||||
if not warte_auf_backend(40):
|
||||
print("BEFUND: Probe-Backend kommt nicht hoch -- der Lauf misst nichts")
|
||||
return 2
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch()
|
||||
seite = browser.new_page(viewport={"width": 1280, "height": 800})
|
||||
fehler: list[str] = []
|
||||
seite.on("pageerror", lambda e: fehler.append(str(e)))
|
||||
seite.goto(BASIS + "/", wait_until="domcontentloaded")
|
||||
seite.evaluate("() => { window.__marke = 'nicht neu geladen'; }")
|
||||
|
||||
def erwarte(text: str, sekunden: float, name: str) -> bool:
|
||||
start = time.time()
|
||||
try:
|
||||
seite.get_by_text(text, exact=True).first.wait_for(timeout=sekunden * 1000)
|
||||
except PlaywrightTimeout:
|
||||
print(f"BEFUND: Schritt '{name}': '{text}' erscheint nicht binnen {sekunden} s")
|
||||
return False
|
||||
schritte.append(f"{name}: '{text}' nach {time.time() - start:.1f} s")
|
||||
return True
|
||||
|
||||
if not erwarte("Backend verbunden", 20, "erste Verbindung"):
|
||||
return 2
|
||||
beende_backend()
|
||||
prozess.wait(timeout=20)
|
||||
if not erwarte("Backend getrennt", 20, "nach dem Ende des Backends"):
|
||||
return 2
|
||||
if not ohne_neustart:
|
||||
prozess = starte_backend()
|
||||
if not warte_auf_backend(40):
|
||||
print("BEFUND: Probe-Backend kommt nach dem Neustart nicht hoch")
|
||||
return 2
|
||||
if not erwarte("Backend verbunden", 30, "wieder verbunden"):
|
||||
return 2
|
||||
marke = seite.evaluate("() => window.__marke")
|
||||
if marke != "nicht neu geladen":
|
||||
print(f"BEFUND: Die Seite wurde neu geladen (Marke {marke!r})")
|
||||
return 2
|
||||
if fehler:
|
||||
print(f"BEFUND: Seitenfehler: {fehler[:3]}")
|
||||
return 2
|
||||
browser.close()
|
||||
for schritt in schritte:
|
||||
print("ok " + schritt)
|
||||
print("Kein Befund: Wiederaufbau ohne Neuladen.")
|
||||
return 0
|
||||
finally:
|
||||
for schritt in schritte:
|
||||
pass
|
||||
beende_backend()
|
||||
try:
|
||||
prozess.wait(timeout=10)
|
||||
except subprocess.TimeoutExpired:
|
||||
prozess.kill()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user