/* ===================================================================== test-webdesign-sitzung.mjs — "Beim Schließen der Seite wieder fragen" Wunsch 22.08.2026: "ich will das ich jedes mal den code gefragt werde wenn man die seite zu macht." Das laesst sich nur in einem echten Browser pruefen, weil genau der Punkt der schwierige ist: Browser stellen Sitzungs-Cookies beim Wiederherstellen von Tabs zurueck. Playwright bildet das nach: - neue Seite im GLEICHEN Kontext = neuer Tab, Cookie noch da, sessionStorage leer -> muss erneut fragen - gleiche Seite weiternavigieren = laufende Sitzung -> darf NICHT fragen Voraussetzung: lokaler Testserver auf 4199 laeuft. ===================================================================== */ import { chromium } from "playwright"; const BASIS = "http://127.0.0.1:4199"; const CODE = "DOGI-TEST-1"; let ok = 0, schlecht = 0; const pruefe = (name, b, zusatz = "") => { if (b) { ok++; console.log(" ok " + name); } else { schlecht++; console.log(" FEHLT " + name + " " + zusatz); } }; const browser = await chromium.launch(); console.log("\n=== Zugang bei jedem Schliessen ===\n"); /* ---------- 1. Anmelden und normal weiterklicken ---------- */ console.log("1. Laufende Sitzung"); const kontext = await browser.newContext(); const seite = await kontext.newPage(); await seite.goto(BASIS + "/webdesign/zugang.html", { waitUntil: "networkidle" }); await seite.fill("#zg-code-dogfather", CODE); await Promise.all([ seite.waitForURL((u) => !u.pathname.endsWith("zugang.html"), { timeout: 15000 }), seite.click("#zg-form-dogfather button[type=submit]"), ]); pruefe("Anmeldung fuehrt in den Bereich", seite.url().endsWith("/webdesign/"), seite.url()); await seite.goto(BASIS + "/webdesign/preise.html", { waitUntil: "networkidle" }); await seite.waitForTimeout(400); pruefe("Weiterklicken fragt NICHT erneut", !seite.url().includes("zugang.html"), seite.url()); await seite.reload({ waitUntil: "networkidle" }); await seite.waitForTimeout(400); pruefe("Neuladen fragt NICHT erneut", !seite.url().includes("zugang.html"), seite.url()); const markeDa = await seite.evaluate(() => sessionStorage.getItem("wd-sitzung-aktiv")); pruefe("Sitzungsmarke ist gesetzt", markeDa === "1"); /* ---------- 2. Seite zu, Cookie bleibt (Tab-Wiederherstellung) ---------- */ console.log("\n2. Seite geschlossen, Cookie vom Browser wiederhergestellt"); { const kekse = await kontext.cookies(); const sitzungsKeks = kekse.find((c) => c.name === "dogiwd_session"); pruefe("Sitzungs-Cookie hat KEIN Ablaufdatum", !sitzungsKeks || sitzungsKeks.expires === -1, "-> der Browser wirft es beim Schliessen selbst weg"); /* Neuer Tab im selben Kontext: Cookies bleiben (wie bei "Tabs wiederherstellen"), sessionStorage ist aber leer. Genau der Fall, in dem das Cookie allein NICHT reichen wuerde. */ const neuerTab = await kontext.newPage(); await neuerTab.goto(BASIS + "/webdesign/preise.html", { waitUntil: "networkidle" }); await neuerTab.waitForTimeout(1200); pruefe("neuer Tab verlangt den Code erneut", neuerTab.url().includes("zugang.html"), "war " + neuerTab.url()); const nachher = await kontext.cookies(); const nochDa = nachher.find((c) => c.name === "dogiwd_session"); pruefe("die alte Sitzung wurde serverseitig beendet", !nochDa, "-> nicht nur weggeklickt, sondern wirklich abgemeldet"); await neuerTab.close(); } /* ---------- 3. Komplett neuer Browser ---------- */ console.log("\n3. Browser komplett neu gestartet"); { const frisch = await browser.newContext(); const s = await frisch.newPage(); await s.goto(BASIS + "/webdesign/", { waitUntil: "networkidle" }); pruefe("frischer Browser landet auf der Zugangswand", s.url().includes("zugang.html"), s.url()); await frisch.close(); } /* ---------- 4. Keine Endlosschleife ---------- */ console.log("\n4. Keine Endlosschleife nach dem Anmelden"); { const k = await browser.newContext(); const s = await k.newPage(); let umleitungen = 0; s.on("framenavigated", (f) => { if (f === s.mainFrame()) umleitungen++; }); await s.goto(BASIS + "/webdesign/zugang.html", { waitUntil: "networkidle" }); await s.fill("#zg-code-dogfather", CODE); await Promise.all([ s.waitForURL((u) => !u.pathname.endsWith("zugang.html"), { timeout: 15000 }), s.click("#zg-form-dogfather button[type=submit]"), ]); await s.waitForTimeout(1500); pruefe("bleibt nach der Anmeldung im Bereich", !s.url().includes("zugang.html"), s.url()); pruefe("keine auffaellige Umleitungsschleife", umleitungen < 8, umleitungen + " Navigationen"); await k.close(); } /* ---------- 5. Knopf-Lesbarkeit (der gemeldete Fehler) ---------- */ console.log("\n5. Lesbarkeit des Hauptknopfs"); { /* Frischer Kontext mit eigener Anmeldung: Schritt 2 hat die Sitzung von `seite` absichtlich beendet -- dort wuerde jetzt die Zugangswand stehen und der Knopf gar nicht existieren. */ const k5 = await browser.newContext(); const seite5 = await k5.newPage(); await seite5.goto(BASIS + "/webdesign/zugang.html", { waitUntil: "networkidle" }); await seite5.fill("#zg-code-dogfather", CODE); await Promise.all([ seite5.waitForURL((u) => !u.pathname.endsWith("zugang.html"), { timeout: 15000 }), seite5.click("#zg-form-dogfather button[type=submit]"), ]); await seite5.waitForLoadState("networkidle"); const skip = seite5.locator("#wd-intro-skip"); if (await skip.isVisible().catch(() => false)) await skip.click(); await seite5.waitForTimeout(300); const befund = await seite5.evaluate(() => { const knopf = document.querySelector(".wd-hero .wd-btn--haupt"); if (!knopf) return null; const s = getComputedStyle(knopf); const zahl = (f) => (f.match(/[\d.]+/g) || []).slice(0, 3).map(Number); return { farbe: zahl(s.color), radius: s.borderRadius, text: knopf.textContent.trim() }; }); pruefe("Hauptknopf gefunden", !!befund); if (befund) { /* Relative Helligkeit nach WCAG. Der Knopfgrund ist hellblau (~0.55) -- eine helle Schrift darauf waere der gemeldete Fehler. */ const [r, g, b] = befund.farbe; const lin = (v) => { const x = v / 255; return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); }; const hell = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b); pruefe("Schrift auf dem Hauptknopf ist DUNKEL", hell < 0.1, `Helligkeit ${hell.toFixed(3)}, Farbe rgb(${befund.farbe.join(",")})`); pruefe("Knopf ist kein Pillen-Oval mehr", !/999/.test(befund.radius) && parseInt(befund.radius, 10) <= 20, befund.radius); } await k5.close(); } await browser.close(); console.log(`\n=== ${ok} bestanden, ${schlecht} gescheitert ===\n`); process.exit(schlecht === 0 ? 0 : 1);