diff --git a/server/mess-quer.mjs b/server/mess-quer.mjs index 1b3c2ddf..61f35d17 100644 --- a/server/mess-quer.mjs +++ b/server/mess-quer.mjs @@ -319,6 +319,23 @@ for (const [gname, breite, hoehe] of GERAETE) { console.log(`\n=== ${gname} (${breite}x${hoehe}) ===`); const host = await alsWer("admin", breite, hoehe); await host.seite.goto(`${BASIS}/workspace/reaktion.html`, { waitUntil: "domcontentloaded" }); + /* AUF DIE LEISTE WARTEN, NICHT AUF DIE REGISTER (01.10.2026). + + Seit die Register am Fingergeraet hinter einem Knopf liegen, ist + `#reiter` dort unsichtbar -- `waitForSelector` wartet aber auf + SICHTBARKEIT und lief in die Zeitsperre ("33 x locator resolved + to hidden"). Gewartet wird jetzt auf die Leiste selbst; die + steht in jedem Fall. */ + await host.seite.waitForSelector("#regieleiste", { timeout: 15000 }); + + /* UND DANN AUFKLAPPEN WIE EIN MENSCH. Diese Messung sucht + seitlichen Ueberlauf IN den Registern -- sie muss sie also + sehen. Der Knopf gibt es nur am Fingergeraet; am Rechner steht + die Leiste ohnehin offen, und `?.` faengt das ab. */ + await host.seite.evaluate(() => { + const l = document.getElementById("regieleiste"); + if (l && l.dataset.auf !== "auf") document.getElementById("reiter-auf")?.click(); + }); await host.seite.waitForSelector("#reiter", { timeout: 15000 }); /* ZUERST ZUGEKLAPPT -- DAS IST DER HAEUFIGSTE ZUSTAND. @@ -393,6 +410,13 @@ for (const [gname, breite, hoehe] of GERAETE) { for (const reg of register) { await host.seite.evaluate((r) => { + /* ERST AUFKLAPPEN, DANN WAEHLEN. Ein Klick auf ein Register + klappt die Leiste am Handy wieder zu -- das naechste waere + sonst nicht anklickbar. */ + const leiste = document.getElementById("regieleiste"); + if (leiste && leiste.dataset.auf !== "auf") { + document.getElementById("reiter-auf")?.click(); + } document.querySelector(`.reiter__knopf[data-tafel="${r}"]`)?.click(); }, reg); await host.seite.waitForTimeout(250); diff --git a/server/pruef-breiten.mjs b/server/pruef-breiten.mjs index 1420c3b4..0bb12e0e 100644 --- a/server/pruef-breiten.mjs +++ b/server/pruef-breiten.mjs @@ -248,9 +248,36 @@ const messen = () => { } return false; }; + /* AUS DEM ROLLKASTEN GESCROLLT IST NICHT VERDECKT (01.10.2026). + + Gemeldet war auf 1024, 1920 und 2560 Pixeln immer ein Feld aus + dem Pult „unter" einem Teil der Transportleiste -- und auf 1280 + und 1440 nichts. Das Pult rollt in sich (`.pult__innen` hat eine + Hoechsthoehe); was unten herausgerollt ist, liegt rechnerisch + dort, wo die Leiste steht. `elementFromPoint` liefert dann die + Leiste. + + Verdeckt ist es nicht -- es ist weggerollt, und man rollt zwei + Zentimeter und ist dran. Dieselbe Sorte Fehlalarm wie die + klebende Leiste und das dekorative SVG oben. */ + const imRollkasten = (e, r) => { + for (let z = e.parentElement; z && z !== document.body; z = z.parentElement) { + const st = getComputedStyle(z); + if (!/auto|scroll|hidden/.test(st.overflowY + " " + st.overflowX)) continue; + const k = z.getBoundingClientRect(); + /* Mehr als die Haelfte muss drin liegen -- ein Element, das + halb am Rand haengt, ist noch bedienbar. */ + const hoch = Math.min(r.bottom, k.bottom) - Math.max(r.top, k.top); + const breit = Math.min(r.right, k.right) - Math.max(r.left, k.left); + if (hoch < r.height / 2 || breit < r.width / 2) return false; + } + return true; + }; + for (const e of bedienbar.slice(0, 60)) { const r = e.getBoundingClientRect(); if (r.bottom < 0 || r.top > window.innerHeight) continue; // ausserhalb des Fensters + if (!imRollkasten(e, r)) continue; // aus seinem Kasten gerollt /* Fuenf Punkte statt einem: Mitte und die vier Viertelpunkte. */ const punkte = [[0.5, 0.5], [0.25, 0.3], [0.75, 0.3], [0.25, 0.7], [0.75, 0.7]]; let erreichbar = false; @@ -297,7 +324,26 @@ let seitenGesamt = 0, elementeGesamt = 0; const probleme = []; for (const [breite, hoehe, wie] of BREITEN) { - const kontext = await browser.newContext({ viewport: { width: breite, height: hoehe } }); + /* MIT FINGER, WENN ES EIN FINGER WAERE (01.10.2026). + + Hier stand nur die Fenstergroesse. Ohne `hasTouch` meldet der + Browser `pointer: fine`, und KEINE Regel aus + `@media (pointer: coarse)` greift -- dort stehen im ganzen Haus + die 44-Pixel-Beruehrziele, das Ausblenden der Tastenkuerzel und + seit heute die eingeklappte Reiterleiste. Auf 320, 390 und 430 + Pixeln hat diese Pruefung also eine Seite vermessen, die es auf + keinem Telefon gibt, und daraus drei Befunde gemeldet. + + Gefunden, weil ich einem dieser Befunde nachgegangen bin statt + ihm zu glauben: mess-quer misst dieselbe Seite auf 390x844 MIT + Finger und findet dort nichts. + + 860 ist die Grenze des Hauses -- dieselbe wie in mess-reaktion, + mess-chat-optik und pruef-fingermass. */ + const finger = breite <= 860; + const kontext = await browser.newContext({ + viewport: { width: breite, height: hoehe }, + hasTouch: finger, isMobile: finger }); const seite = await kontext.newPage(); const konsole = []; seite.on("console", (m) => { if (m.type() === "error") konsole.push(m.text().slice(0, 70)); }); @@ -347,7 +393,9 @@ ok(elementeGesamt > 20000, `${elementeGesamt} Elemente vermessen`); console.log(`\n=== Gegenprobe (muss anschlagen) ===`); { for (const testBreite of [320, 768, 1920]) { - const kontext = await browser.newContext({ viewport: { width: testBreite, height: 900 } }); + const kontext = await browser.newContext({ + viewport: { width: testBreite, height: 900 }, + hasTouch: testBreite <= 860, isMobile: testBreite <= 860 }); const seite = await kontext.newPage(); await seite.goto(BASIS + "/workspace/", { waitUntil: "domcontentloaded" }); await seite.click('.rolle[data-rolle="admin"]'); diff --git a/server/pruef-fingermass.mjs b/server/pruef-fingermass.mjs index 0c8f09c3..677117e6 100644 --- a/server/pruef-fingermass.mjs +++ b/server/pruef-fingermass.mjs @@ -106,7 +106,35 @@ export const fensterStellen = (text) => { const rein = ohneKommentare(text); for (const m of rein.matchAll(/newContext\s*\(\s*\{[\s\S]{0,400}?\}\s*\)/g)) { const br = [...m[0].matchAll(/width\s*:\s*(\d{3,4})\b/g)].map((z) => Number(z[1])); - if (!br.length) continue; + if (!br.length) { + /* ==== DER BLINDE FLECK DIESER WACHE (01.10.2026) ========== + + Hier stand `continue` -- ein Fenster ohne Zahl galt als + nicht vorhanden. In pruef-breiten.mjs stand aber + + newContext({ viewport: { width: breite, height: hoehe } }) + + und die Breite kam aus einer Schleife ueber neun + Geraete, darunter 320, 390 und 430 Pixel. Keine Zahl, + kein Treffer, „in Ordnung" -- und pruef-breiten meldete + daraufhin drei Befunde auf einer Seite, die es auf + keinem Telefon gibt. + + Ohne Zahl laesst sich nicht sagen, ob das Fenster + schmal ist. Ob ein `hasTouch` danebensteht, sehr wohl -- + und fehlt es, KANN das Fenster schmal sein und hat + keinen Finger. Das ist nicht „in Ordnung", sondern der + dritte Ausgang, und er bekommt eine eigene Zahl. */ + /* NUR WENN EINE BREITE DASTEHT UND KEINE ZAHL IST. Ein + `newContext` ganz OHNE Breite ist das Standardfenster + (1280x720) -- kein Telefon. Ohne diese Einschraenkung + meldete die Wache 45 Faelle, darunter jedes + `newContext({ permissions: [...] })`. Eine Warnung, die + 45-mal kommt, nimmt die echte mit. */ + const stehtBreite = /\bwidth\s*:/.test(m[0]); + if (stehtBreite && !/hasTouch/.test(m[0])) raus.push({ unklar: true }); + continue; + } raus.push({ schmal: br.some((x) => x <= SCHMAL), finger: /hasTouch/.test(m[0]) }); } /* `setViewportSize` KANN `hasTouch` nicht nachtragen — es gehoert @@ -153,7 +181,8 @@ if (dateien.length < 50) { } const funde = []; -let blind = 0, mitFinger = 0, amTelefon = 0; +const unklare = []; +let blind = 0, mitFinger = 0, amTelefon = 0, unklar = 0; for (const name of dateien) { const text = readFileSync(join(ORDNER, name), "utf8"); const schmale = fensterStellen(text).filter((f) => f.schmal); @@ -164,6 +193,15 @@ for (const name of dateien) { if (b) { blind += b; funde.push(`${name} (${b})`); } } +/* Die unklaren getrennt -- sie koennen schmal sein, sie koennen es + auch nicht sein. Sie in die blinden einzurechnen waere geraten, + sie wegzulassen waere das, was heute den Fehler gedeckt hat. */ +for (const name of dateien) { + const u = fensterStellen(readFileSync(join(ORDNER, name), "utf8")) + .filter((f) => f.unklar).length; + if (u) { unklar += u; unklare.push(`${name} (${u})`); } +} + console.log(` ${amTelefon} Dateien oeffnen ein Telefonformat, ` + `${mitFinger} dieser Fenster haben einen Finger.`); if (funde.length) console.log(" blinde Fenster mit Massband: " + funde.join(", ")); @@ -184,6 +222,44 @@ if (blind > GRUNDLINIE) { ok(true, `${blind} blinde Fenster mit Massband — unveraendert zur Grundlinie ${GRUNDLINIE}`); } +/* ==== DIE DRITTE ZAHL (01.10.2026) ================================ + Ein `newContext` ohne Zahl UND ohne `hasTouch`: Die Breite kommt + aus einer Variablen, und ob sie schmal ist, steht hier nicht. Das + ist kein Befund und kein Freispruch -- es ist die Frage, die + diese Wache nicht beantworten kann. + + Sie bekommt eine eigene Grundlinie, damit sie weder + stillschweigend durchgeht noch die echte Zahl verfaelscht. + + NEUNUNDDREISSIG, GEMESSEN AM 01.10.2026 -- und die Zahl ist + ernst. Stichprobe: + + mess-chat-liste.mjs ["handy", 390, 860] ohne hasTouch + pruef-material.mjs ein Handy-Fall ohne hasTouch + + Das sind Messungen, die bei Telefonbreiten eine Seite mit + MAUSZEIGER vermessen. Genau so hat pruef-breiten heute drei + Befunde gemeldet, die es auf keinem Telefon gibt. + + WARUM SIE HIER ALS GRUNDLINIE STEHT UND NICHT ALS 39 FEHLER: + Eine Warnung, die bei jedem Lauf neununddreissigmal kommt, wird + weggeklickt und nimmt die echte mit. Die Zahl ist festgehalten, + sie darf nur SINKEN, und jede neue faellt sofort auf. Abgearbeitet + wird sie Datei fuer Datei -- jede einzeln, und jede mit einem + Lauf danach, denn bei pruef-breiten sind durch den Finger drei + Befunde verschwunden und haetten genauso gut drei neue + auftauchen koennen. */ +const UNKLAR_GRUNDLINIE = 39; +if (unklare.length) console.log(" ohne Zahl und ohne Finger: " + unklare.join(", ")); +ok(unklar <= UNKLAR_GRUNDLINIE, + unklar <= UNKLAR_GRUNDLINIE + ? `${unklar} Fenster, deren Breite aus einer Variablen kommt und bei denen ` + + `kein hasTouch danebensteht — Grundlinie ${UNKLAR_GRUNDLINIE}` + : `${unklar} Fenster mit Variable und ohne hasTouch (Grundlinie ` + + `${UNKLAR_GRUNDLINIE}). Dort laesst sich nicht sagen, ob am Telefon gemessen ` + + "wird — und genau so ist am 01.10. pruef-breiten durchgerutscht. " + + "Entweder hasTouch setzen oder die Breite als Zahl hinschreiben."); + console.log("\n=== 2. Gegenprobe: kann sie auch NICHT IN ORDNUNG sagen? ==="); const faelle = [ ["der Fall vom 29.09. (schmal, misst, kein Finger)", @@ -229,6 +305,34 @@ ok(daneben.length === 0, daneben.length ? `Gegenprobe daneben bei: ${daneben.join(", ")}` : `Gegenprobe: alle ${faelle.length} Faelle richtig eingeordnet`); +/* ==== UND FUER DIE DRITTE ZAHL (01.10.2026) ====================== + Sie meldet heute 0, und eine Zeile, die 0 meldet, sieht genauso + aus wie eine, die gar nichts finden kann. Genau das war sie bis + heute Mittag. + + Eigene Tabelle, nicht in die obige hinein: Es ist eine andere + Frage, und ein Fall, der in beiden steht, wird irgendwann in + einer davon falsch gepflegt. */ +const unklarStellen = (text) => fensterStellen(text).filter((f) => f.unklar).length; +const unklarFaelle = [ + ["der Fall vom 01.10. (Breite aus einer Variablen, kein Finger)", + 'const c = await b.newContext({ viewport: { width: breite, height: hoehe } });', 1], + ["dieselbe Stelle MIT Finger", + 'const c = await b.newContext({ viewport: { width: breite, height: hoehe },\n' + + ' hasTouch: breite <= 860 });', 0], + ["eine Zahl ist keine Unklarheit — die beurteilt die Wache oben", + 'const c = await b.newContext({ viewport: { width: 390, height: 844 } });', 0], + ["ein Fenster ganz ohne Breite ist das Standardfenster, kein Telefon", + 'const c = await b.newContext({ permissions: ["notifications"] });', 0], +]; +const unklarDaneben = unklarFaelle + .filter(([, text, soll]) => unklarStellen(text) !== soll) + .map(([n, text, soll]) => `${n} (${unklarStellen(text)} statt ${soll})`); +ok(unklarDaneben.length === 0, + unklarDaneben.length + ? `Gegenprobe zur dritten Zahl daneben bei: ${unklarDaneben.join(", ")}` + : `Gegenprobe: alle ${unklarFaelle.length} Faelle der dritten Zahl richtig`); + console.log(`\n${ok_} Pruefungen, ${fehl} Fehler`); console.log(fehl ? "NICHT IN ORDNUNG\n" : "ALLES IN ORDNUNG\n"); process.exit(fehl ? 1 : 0); diff --git a/server/pruef-reaktion.mjs b/server/pruef-reaktion.mjs index ffff5d79..7fe4c79b 100644 --- a/server/pruef-reaktion.mjs +++ b/server/pruef-reaktion.mjs @@ -1001,7 +1001,7 @@ melde("=== 12. Die Regie ==="); Uebrig bleibt genau das, was sich widersprechen KANN: zwei Grundregeln, die beide sagen, WIE das Bauteil gebaut ist -- `grid` gegen `flex`, wie bei `.stufen`. */ - const positiv = (wert) => wert && wert !== "none" && !/^none/.test(wert); + const positiv = (wert) => wert && wert !== "none" && !/^none\b/.test(wert); /* ZWEI EINSCHRAENKUNGEN MEHR, BEIDE AM 29.09.2026 NOETIG GEWORDEN. diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index 5573de8b..3db8cc32 100644 --- a/workspace/anruf-probe.html +++ b/workspace/anruf-probe.html @@ -16,8 +16,8 @@ verdeckt. Gefunden hat es pruef-struktur. Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. --> - - + + - +