Der Handy-Rundgang ist zum ersten Mal bei null Befunden

SECHS SACHEN, UND KEINE DAVON WAR DAS, WONACH ICH GESUCHT HABE.

1. ZWEI NATIVE prompt() IN teamlage.js -- die letzten im Haus.
   Sie halten die ganze Seite an, sehen auf jedem Browser anders aus
   als der Rest und koennen nicht sagen, was BLEIBT, wenn man absagt.
   Genau das ist dort die Frage, die jemand vor dem Klicken hat. Jetzt
   derselbe Dialog wie an den 42 anderen Stellen.

2. UND DER GRUND, WARUM SIE NIEMAND GEFUNDEN HAT.
   pruef-nachfrage suchte mit `(?:^|[^.\w])(confirm|prompt)\s*\(`.
   Das `[^.\w]` sollte fremde Methoden ausschliessen -- `angebot
   .prompt()` ist die Installations-Aufforderung des Browsers und kein
   nativer Dialog. Nur trifft dieser Ausschluss ausgerechnet die
   HAEUFIGSTE Schreibweise: `window.prompt(` hat einen Punkt davor.
   Die Pruefung war gruen, waehrend zwei native prompt() dastanden.
   Genau das Muster, vor dem dieses Haus warnt: eine Pruefung, die
   laeuft, gruen ist und das Falsche prueft. Die Gegenprobe kennt
   jetzt beide Schreibweisen -- haette sie das vorher getan, waere es
   am selben Tag aufgefallen.

3. willkommen.html LUD nachfrage.js NICHT.
   Gefunden von der geschaerften Pruefung. kopf.js ruft `frageNach(`
   ohne Absicherung -- auf dieser einen Seite haette ABMELDEN einen
   Absturz ausgeloest. Die Seite ist vom 21.09., die Luecke also
   einen Tag alt.

4. ZWEI FEHLALARME IM HANDY-RUNDGANG ABGESTELLT.
   Er meldete bei JEDEM Lauf dieselben drei Befunde: `button.schnitt
   bis 481px`, die Rechtetafel `table bis 877px`, `a.k-pille 8x8`.
   Nachgemessen bei 390 px: Das Dokument ist exakt 390 px breit,
   NICHTS laeuft ueber -- beide stehen in einem Kasten mit
   `overflow-x: auto`, und der rollt absichtlich. Die Kalenderpunkte
   tragen `pointer-events: none`; der Tipp gehoert der Tageszelle.
   Eine Warnung, die immer kommt, ist keine Warnung mehr (Hausregel
   vom 03.09.). Beide Regeln sind SCHMAL: nur ausdrueckliches
   `overflow-x: auto|scroll` (nicht `hidden` -- dort ist der Inhalt
   wirklich weg), nur ausdrueckliches `pointer-events: none`.
   Die Gegenprobe hat jetzt vier Faelle statt zwei: zwei, die gemeldet
   werden MUESSEN, und zwei, die es NICHT duerfen. Eine engere Messung
   kann auch zu eng sein.

5. DER LETZTE ECHTE BEFUND: 404 BEI JEDEM MODI.
   Der Rundgang meldete "404 (Not Found)" ohne Adresse -- eine
   Pruefung, die einen Fehler findet, ihn aber nicht auffindbar macht,
   kostet mehr Zeit als sie spart. Sie nennt jetzt die Adresse, und
   damit war es in einer Minute klar: `/workspace/api/werdegang/liste`.
   Der Code BEHANDELTE den 404 richtig, der Browser protokolliert ihn
   trotzdem -- derselbe Fall wie am 19.09. bei /anruf/adressen.
   Jetzt sagt der Server in /api/ich, ob jemand Team Dogi fuehrt.
   EIGENES FELD, kein Stellvertreter: `darf_verteilen` sieht aehnlich
   aus, ist aber nicht dasselbe -- ein Manager darf verteilen und
   fuehrt Team Dogi nicht.

   Dabei EINE Wartestelle statt zwei: `window.wennIchDaBin()`.
   `window.__ich` kommt ueber das Netz; zwei Seiten hatten dafuer
   jeweils ein eigenes setInterval. Zwei Fassungen desselben Wartens
   altern unterschiedlich.

6. pruef-werdegang MASS AUF DER FALSCHEN ADRESSE.
   Drei Pruefungen waren dauerhaft rot (`data-ton=null`) -- an einer
   Seite, die in Ordnung ist. Sie oeffnete `127.0.0.1`, also die
   Adresse der AGENTUR; dort ist `person.haus` nicht "crew" und die
   Kachelliste eine andere. Nachgemessen: Alle vier Rollen HABEN die
   Kachel, sobald das Haus stimmt. Jetzt derselbe https-Vorbau wie in
   pruef-willkommen und pruef-zuteilung.

   Beinahe haette ich hier etwas "repariert", das nicht kaputt war:
   Meine erste Messung rief `bereicheFuer(p, "crew")` auf -- das Haus
   wird aber aus `person.haus` gelesen, nicht als Argument. Sie sagte
   "DogFather hat keine Kachel". Eine plausible Herleitung ersetzt
   keine Messung, und eine falsch aufgesetzte Messung auch nicht.

GEMESSEN: pruef-handy-teamdogi 214 Seitenaufrufe, 108.564 Elemente,
4.126 Bedienelemente -- 0 Befunde. Alle vier Rollen, beide Breiten.
Zum ersten Mal.

pruef-werdegang 103/0 (war 100/3), pruef-nachfrage 51/0 (war 49),
pruef-stelle 15/0, pruef-entwicklung 48/0, pruef-start-ansicht 153/0,
pruef-wege-nach-draussen 67/0, pruef-tippziele 11/0, pruef-treff 80/0,
pruef-willkommen 67/0, pruef-sackgassen 13/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-22 10:14:25 +02:00
co-authored by Claude Opus 5
parent af56f97f4c
commit 65d278a18e
47 changed files with 830 additions and 558 deletions
+55 -4
View File
@@ -600,8 +600,58 @@ melde("=== 11. Im Browser ===");
{
const { chromium } = await import(
"file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs");
const browser = await chromium.launch();
const kontext = await browser.newContext({ viewport: { width: 1280, height: 1000 } });
/* AUF DER ECHTEN ADRESSE MESSEN (berichtigt 22.09.2026).
==================================================================
Bis heute oeffnete dieser Abschnitt `http://127.0.0.1/...` -- also
die ADRESSE DER AGENTUR. Auf der ist `person.haus` nicht "crew",
und `bereicheFuer()` liefert eine andere Kachelliste. Die Kachel
zu dieser Seite steht dort nicht drin, also fand `kopf.js` keine
Farbe: `data-ton=null`.
Drei Pruefungen waren deshalb rot, und zwar dauerhaft -- an einer
Seite, die in Wirklichkeit in Ordnung ist. Nachgemessen: Alle vier
Rollen (admin, hand, linke, modi) HABEN die Kachel, sobald das
Haus stimmt.
Genau dieselbe Falle wie am 21.09.2026 bei pruef-rueckmeldung.
Dort ging es ueber `node:http` mit Host-Kopf; ein Browser kann das
nicht (Chromium verbietet den Host-Kopf). Der Weg im Haus ist ein
selbst unterschriebener Vorbau plus `--host-resolver-rules` --
derselbe wie in pruef-willkommen und pruef-zuteilung. */
const { createServer: httpsServer } = await import("node:https");
const { request: httpWeiter } = await import("node:http");
const { execFileSync } = await import("node:child_process");
const { mkdtempSync: tempOrdner, readFileSync: liesDatei } = await import("node:fs");
const { tmpdir: tempWurzel } = await import("node:os");
const { join: pfad } = await import("node:path");
const zOrdner = tempOrdner(pfad(tempWurzel(), "wg-zeugnis-"));
const zKey = pfad(zOrdner, "k.pem"), zCrt = pfad(zOrdner, "z.pem");
execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes",
"-keyout", zKey, "-out", zCrt, "-days", "2", "-subj", `/CN=${CREW}`,
"-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" });
const HTTPS_PORT = PORT + 1;
const vorbau = httpsServer(
{ key: liesDatei(zKey), cert: liesDatei(zCrt) },
(von, an) => {
const weiter = httpWeiter({
host: "127.0.0.1", port: PORT, path: von.url, method: von.method,
headers: { ...von.headers, host: CREW },
}, (antwort) => { an.writeHead(antwort.statusCode, antwort.headers); antwort.pipe(an); });
weiter.on("error", () => { try { an.destroy(); } catch { /* Zugabe */ } });
von.on("error", () => {});
von.pipe(weiter);
});
await new Promise((r) => vorbau.listen(HTTPS_PORT, "127.0.0.1", r));
const SEITE = `https://${CREW}:${HTTPS_PORT}`;
const browser = await chromium.launch({
args: [`--host-resolver-rules=MAP ${CREW} 127.0.0.1`, "--ignore-certificate-errors"],
ignoreHTTPSErrors: true,
});
const kontext = await browser.newContext({
viewport: { width: 1280, height: 1000 }, ignoreHTTPSErrors: true });
const seite = await kontext.newPage();
const konsole = [];
seite.on("console", (m) => { if (m.type() === "error" && !/favicon|ERR_/i.test(m.text())) konsole.push(m.text()); });
@@ -609,10 +659,10 @@ melde("=== 11. Im Browser ===");
await kontext.addCookies(kDogi.split("; ").filter(Boolean).map((teil) => {
const i = teil.indexOf("=");
return { name: teil.slice(0, i), value: teil.slice(i + 1), domain: "127.0.0.1", path: "/" };
return { name: teil.slice(0, i), value: teil.slice(i + 1), domain: CREW, path: "/" };
}));
await seite.goto(`http://127.0.0.1:${PORT}/workspace/werdegang.html`, { waitUntil: "networkidle" });
await seite.goto(`${SEITE}/workspace/werdegang.html`, { waitUntil: "networkidle" });
await seite.waitForTimeout(900);
const liste = await seite.evaluate(() => ({
@@ -741,6 +791,7 @@ melde("=== 11. Im Browser ===");
ok(konsole.length === 0,
konsole.length ? "Fehler im Browser: " + konsole[0].slice(0, 120) : "keine Fehler im Browser");
await browser.close();
await new Promise((r) => vorbau.close(r));
}
/* =======================================================================