/* ===================================================================== pruef-abmelden.mjs — meldet "Abmelden" wirklich ab? Rückmeldung vom 23.08.2026: "der abmelde button klappt auch nicht auf dem handy". Er tat scheinbar nichts. Die Ursache war nicht das Handy: Der Knopf beendete die Team-Sitzung und lud neu -- das Merkmal der Zugangswand blieb aber stehen, und beim Neuladen holte sich die Seite sofort wieder einen Ausweis. Man war nach einer Zehntelsekunde erneut angemeldet. Auf dem Handy sieht man das Aufblitzen eher, deshalb fiel es dort auf. Geprüft wird deshalb, was TATSÄCHLICH hinausgeht -- nicht, ob sich etwas auf dem Schirm bewegt. ===================================================================== */ import { chromium, devices } from "playwright"; import { createServer } from "node:http"; import { readFileSync, existsSync } from "node:fs"; import { join, extname } from "node:path"; const W = process.cwd(); const T = { ".html": "text/html", ".css": "text/css", ".js": "text/javascript", ".png": "image/png", ".jpg": "image/jpeg", ".svg": "image/svg+xml", ".webp": "image/webp", ".ico": "image/x-icon", ".json": "application/json" }; const srv = createServer((q, r) => { const p = join(W, decodeURIComponent(q.url.split("?")[0])); if (existsSync(p) && !p.endsWith("/")) { r.writeHead(200, { "content-type": T[extname(p)] || "text/plain" }); return r.end(readFileSync(p)); } r.writeHead(404).end(""); }); await new Promise((r) => srv.listen(4357, r)); const ergebnisse = []; const pruefe = (n, ok, z) => { ergebnisse.push({ n, ok }); console.log((ok ? " ok " : " FEHL ") + n + (z !== undefined ? " -> " + z : "")); }; for (const [wo, angaben] of [ ["Computer", { viewport: { width: 1440, height: 950 } }], ["Handy", { ...devices["iPhone 14 Pro"] }], ]) { const browser = await chromium.launch(); const kontext = await browser.newContext(angaben); const seite = await kontext.newPage(); const protokoll = []; seite.on("pageerror", (e) => protokoll.push(e.message)); const gerufen = []; await seite.route("**/*", async (route) => { const u = new URL(route.request().url()); const m = route.request().method(); if (m === "POST") gerufen.push(u.pathname); if (u.pathname === "/webdesign/zugang-beenden") return route.fulfill({ json: { ok: true } }); if (u.pathname.startsWith("/auth/")) return route.fulfill({ json: { ok: true } }); if (u.pathname.includes("/webdesign/admin/uebersicht")) { return route.fulfill({ json: { ok: true, beiMir: { anfragen: { n: 0 }, nachrichten: { n: 0 }, wuensche: { n: 0 }, widerrufe: { n: 0 }, projekte: 0 }, beiKunde: { projekte: 0, aufgaben: 0, zahlungen: { n: 0, summe: 0 }, zahlungenText: "0,00 €" }, geld: { monat: { n: 0, brutto: 0, netto: 0, bruttoText: "0,00 €", nettoText: "0,00 €" }, gesamt: { n: 0, bruttoText: "0,00 €" }, gebuehrenText: "0,00 €" }, projekte: [], verlauf: [], bestand: {} } }); } if (u.pathname.includes("/webdesign/admin/")) { return route.fulfill({ json: { ok: true, anfragen: [], kunden: [], projekte: [], zahlungen: [], verlaeufe: [] } }); } return route.continue(); }); /* Nur auf der VERWALTUNGSSEITE vorbelegen. addInitScript laeuft bei jeder Navigation erneut. Ohne diese Einschraenkung setzte es den Schluessel auf der Zugangswand sofort wieder -- und die Pruefung "der Schluessel ist weg" mass dann das eigene Vorbereitungsskript statt des Abmeldens. Erst beim Nachsehen aufgefallen: Zwei Zeilen meldeten Fehler, obwohl das Abmelden voellig richtig funktionierte. */ await seite.addInitScript(() => { if (!location.pathname.includes("verwaltung")) return; sessionStorage.setItem("wd-vw-token", "t"); sessionStorage.setItem("wd-vw-token-quelle", "ausweis"); sessionStorage.setItem("wd-sitzung-aktiv", "1"); }); await seite.goto("http://127.0.0.1:4357/webdesign/verwaltung.html"); await seite.waitForTimeout(700); console.log("\n=== " + wo + " ==="); const knopf = seite.locator("#vw-abmelden"); pruefe(wo + ": der Abmelden-Knopf ist sichtbar", await knopf.isVisible()); const kasten = await knopf.boundingBox(); pruefe(wo + ": er ist gross genug zum Antippen", kasten && kasten.height >= 44, kasten && Math.round(kasten.height) + "px"); await knopf.click(); await seite.waitForTimeout(900); /* Das Entscheidende: Beide Sitzungen muessen beendet werden. Vorher ging nur der erste Aufruf hinaus -- und genau deshalb war man sofort wieder drin. */ pruefe(wo + ": die Team-Sitzung wird beendet", gerufen.some((x) => x.includes("/auth/logout")), gerufen.join(", ")); pruefe(wo + ": die ZUGANGSWAND wird ebenfalls beendet", gerufen.some((x) => x === "/webdesign/zugang-beenden"), gerufen.join(", ")); pruefe(wo + ": der gespeicherte Schluessel ist weg", await seite.evaluate(() => !sessionStorage.getItem("wd-vw-token"))); pruefe(wo + ": auch dessen Herkunft", await seite.evaluate(() => !sessionStorage.getItem("wd-vw-token-quelle"))); /* Und man landet an der Zugangswand, nicht wieder in der Verwaltung. */ pruefe(wo + ": man landet an der Zugangswand", /zugang\.html/.test(seite.url()), seite.url()); pruefe(wo + ": kein Skriptfehler", protokoll.length === 0, protokoll.join(" | ")); await browser.close(); } srv.close(); const f = ergebnisse.filter((e) => !e.ok).length; console.log(`\n===== ${ergebnisse.length - f} bestanden, ${f} fehlgeschlagen =====`); process.exitCode = f ? 1 : 0;