Die Grundlinie der Fingerwache sinkt von 6 auf 1.
DIE SCHWEREN FAELLE
pruef-notizen, pruef-teamlage-karten, pruef-terminregel,
pruef-werdegang, pruef-befinden.
Bei diesen fuenf stand mitten im Ablauf ein
`setViewportSize({ width: 390 })`. Das aendert nur die Groesse --
`hasTouch` gehoert zum KONTEXT und ist beim Anlegen entschieden.
Nachtragen geht nicht; es braucht ein zweites Fenster.
DAS MUSTER, DAS FUER ALLE FUENF GETRAGEN HAT
const handyKontext = await browser.newContext({
viewport: { width: 390, height: 844 }, hasTouch: true, isMobile: true });
await handyKontext.addCookies(await kontext.cookies());
const handy = await handyKontext.newPage();
await handy.goto(seite.url(), { waitUntil: "networkidle" });
Drei Entscheidungen darin:
- Die Anmeldung wandert als Keks mit, statt sie zu wiederholen.
Eine zweite Anmeldung waere eine zweite Stelle, die veralten
kann.
- Die Adresse kommt von `seite.url()`. Sie ein zweites Mal
hinzuschreiben waere eine zweite Wahrheit darueber, welche
Seite gemessen wird.
- Das fruehere Zuruecksetzen auf 1280 px faellt weg. Die breite
Seite war nie schmal -- es gibt nichts zurueckzustellen.
Bei pruef-terminregel liessen sich die vier Schritte, die den
schwebenden Hinweis erzeugen, nicht uebernehmen: Sie werden im
neuen Kontext nachgefahren (oeffnen, "Neu", Datum eintragen).
ALLE FUENF DANACH GRUEN
pruef-notizen EXIT 0
pruef-teamlage-karten EXIT 0 (39 geprueft)
pruef-terminregel EXIT 0 (35 Pruefungen)
pruef-werdegang EXIT 0
pruef-befinden EXIT 0
Diese Seiten halten die Fingerregeln also schon ein. Es hatte nur
nie jemand nachgesehen.
EINES BLEIBT: pruef-grosscheck
Die Datei zu aendern waere ein Zweizeiler. Sie zu PRUEFEN hiesse,
206 Seiten ueber vier Rollen und zwei Bildschirmgroessen laufen zu
lassen -- das braucht Filipes Zusage. Eine Aenderung, die ich nicht
pruefen darf, liefere ich nicht aus. Die Grundlinie steht deshalb
auf 1 und nicht auf 0.
GEPRUEFT
pruef-fingermass 3 / 0, neun Gegenproben, Grundlinie 1
235 lines
11 KiB
JavaScript
235 lines
11 KiB
JavaScript
/* =====================================================================
|
|
pruef-fingermass.mjs — Wer am Handy misst, braucht einen Finger
|
|
|
|
WAS HIER SCHIEFGING (29.09.2026 gemessen):
|
|
In chat.css stand neben den 44-Pixel-Knoepfen der Nachrichten-
|
|
fusszeile eine Rechnung: „Fuenf mal 44 plus vier Abstaende sind
|
|
236 px — eine Blase hat auf 412 px innen 251 px. Die Reihe bleibt
|
|
damit einzeilig." Sie vergisst die Uhrzeit (57 px), und 236 + 57
|
|
sind 293. Gemessen waren es drei Zeilen, 96 Pixel hoch, unter
|
|
JEDER einzelnen Nachricht.
|
|
|
|
WARUM DAS VIER TAGE UNBEMERKT BLIEB: Die Regel ist nie gelaufen.
|
|
`page.setViewportSize({ width: 412 })` aendert nur die Groesse.
|
|
`hasTouch` gehoert zum KONTEXT und laesst sich danach nicht mehr
|
|
setzen — ohne ihn meldet der Browser `pointer: fine`, und KEINE
|
|
einzige Regel aus `@media (pointer: coarse)` greift. Dort stehen
|
|
im ganzen Haus die 44-Pixel-Beruehrziele.
|
|
|
|
Eine Messung mit Mauszeiger auf 412 Pixeln vermisst also eine
|
|
Seite, die es auf keinem Telefon gibt — und meldet dabei „in
|
|
Ordnung". Das ist die dritte Sorte falscher Haken: nicht
|
|
uebersprungen, nicht rot, sondern gruen und wertlos.
|
|
|
|
WAS DIESE PRUEFUNG SICHERT: Dass die Zahl solcher Messungen nur
|
|
noch SINKT. Sie meldet nicht 18 Fehler auf einmal — eine Warnung,
|
|
die immer kommt, wird weggeklickt und nimmt den echten Fund mit.
|
|
Sie haelt eine Grundlinie und schlaegt an, sobald eine NEUE
|
|
dazukommt.
|
|
|
|
UND SIE SCHLAEGT AUCH AN, WENN DIE ZAHL SINKT. Wer eine Messung
|
|
repariert und die Grundlinie stehen laesst, deckt damit Platz fuer
|
|
die naechste Suende. Das kostet eine Zeile und haelt die Wache
|
|
scharf.
|
|
===================================================================== */
|
|
|
|
import { readdirSync, readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
let ok_ = 0, fehl = 0;
|
|
const ok = (b, text) => { if (b) { ok_++; console.log(" ok " + text); }
|
|
else { fehl++; console.log(" FEHL " + text); } };
|
|
|
|
const ORDNER = new URL(".", import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1");
|
|
|
|
/* GRUNDLINIE, gemessen am 29.09.2026. Diese Zahl darf nur kleiner
|
|
werden. Wird sie kleiner, gehoert sie hier angepasst — die
|
|
Pruefung sagt es dann selbst.
|
|
|
|
DREI ANLAEUFE, DREI ZAHLEN. Ein grep ueber die Dateien fand 18;
|
|
zwei davon waren Zahlen in Kommentaren („gemessen bei 412 px"),
|
|
keine Fenster. Die erste Fassung dieser Wache zaehlte dann DATEIEN
|
|
und kam auf 16 — aber `pruef-kalender.mjs` allein hat sieben
|
|
Fenster, davon drei schmale, und ein einziges `hasTouch` irgendwo
|
|
in der Datei haette alle drei freigesprochen. Gezaehlt wird
|
|
deshalb je FENSTER.
|
|
|
|
Die geschaerfte Fassung fand dann prompt zwei Dateien, welche die
|
|
grobe freigesprochen hatte — `pruef-chat-optik` und
|
|
`pruef-handy-teamdogi`, beide mit EINEM Finger und einem blinden
|
|
Fenster daneben. Beim Nachmessen war die erste ein Fehlalarm (ihr
|
|
`setViewportSize` sitzt auf einer Seite, die den Finger schon
|
|
hat), die zweite ein echter Fund und sofort repariert.
|
|
|
|
Die erste Zahl, die eine Wache liefert, ist selten die richtige.
|
|
|
|
29.09.2026, nachmittags: 17 -> 6 -> 1. Sechzehn Fenster bekamen
|
|
einen Finger, eines fiel weg. JEDE der umgestellten Pruefungen
|
|
lief danach gruen -- diese Seiten halten die Fingerregeln also
|
|
schon ein, es hatte nur nie jemand nachgesehen. Gefunden wurde
|
|
dabei trotzdem etwas: eine Zeitbombe in pruef-kalender (dort
|
|
steht die Erklaerung).
|
|
|
|
DIE SCHWEREN FAELLE brauchten je einen Umbau: Wo mitten im Ablauf
|
|
`setViewportSize` stand, kann der Finger nicht nachgetragen
|
|
werden. Das Muster, das fuer alle fuenf getragen hat: einen
|
|
eigenen Kontext anlegen, `addCookies(await kontext.cookies())`,
|
|
und die Adresse von `seite.url()` nehmen statt sie ein zweites
|
|
Mal hinzuschreiben. Danach ist das fruehere Zuruecksetzen auf
|
|
1280 px hinfaellig -- die breite Seite war nie schmal.
|
|
|
|
ES BLEIBT EINES: `pruef-grosscheck`. Die Datei zu aendern waere
|
|
ein Zweizeiler; sie zu pruefen hiesse, 206 Seiten ueber vier
|
|
Rollen laufen zu lassen, und das braucht Filipes Zusage. Eine
|
|
Aenderung, die ich nicht pruefen darf, liefere ich nicht aus. */
|
|
const GRUNDLINIE = 1;
|
|
|
|
/* Ab wann ist ein Fenster ein Telefon? 860 ist die Grenze, die im
|
|
Haus schon in mess-reaktion und mess-chat-optik steht. Darueber
|
|
hat ein Geraet mit hoher Wahrscheinlichkeit einen Zeiger. */
|
|
const SCHMAL = 860;
|
|
const MISST = /getBoundingClientRect|offsetWidth|offsetHeight|clientWidth|clientHeight|scrollWidth|scrollHeight|boundingBox/;
|
|
|
|
const ohneKommentare = (text) => text
|
|
.replace(/\/\*[\s\S]*?\*\//g, " ")
|
|
.replace(/^\s*\/\/.*$/gm, " ");
|
|
|
|
/* NUR DIE STELLE, DIE EIN FENSTER AUFMACHT — nicht jede Zahl im
|
|
Text. `width: 412` in einem Kommentar ueber eine Messung von
|
|
gestern ist keine Messung.
|
|
|
|
UND JE FENSTER, NICHT JE DATEI. Eine Wache, die eine Datei als
|
|
Ganzes abhakt, uebersieht genau die Mischung, die im Haus die
|
|
Regel ist: ein Fenster mit Finger, drei ohne. */
|
|
export const fensterStellen = (text) => {
|
|
const raus = [];
|
|
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;
|
|
raus.push({ schmal: br.some((x) => x <= SCHMAL), finger: /hasTouch/.test(m[0]) });
|
|
}
|
|
/* `setViewportSize` KANN `hasTouch` nicht nachtragen — es gehoert
|
|
zum Kontext und ist beim Anlegen entschieden.
|
|
|
|
ABER ES KANN IHN AUCH NICHT WEGNEHMEN. Die erste Fassung zaehlte
|
|
jede solche Stelle als blind und meldete daraufhin
|
|
`pruef-chat-optik.mjs` — zu Unrecht: Deren Kontext traegt
|
|
`hasTouch: breite < 900`, und wer danach nur die Groesse
|
|
aendert, behaelt den Finger. Ein Fehlalarm, gefunden beim
|
|
Nachmessen des ersten Laufs.
|
|
|
|
Gezaehlt wird die Stelle deshalb nur, wenn in der ganzen Datei
|
|
KEIN einziges `hasTouch` steht — dann stammt die Seite sicher
|
|
aus einem fingerlosen Kontext. Wo ich raten muesste, zaehle ich
|
|
nicht: Eine Wache, die im Zweifel meldet, wird weggeklickt. */
|
|
if (!/hasTouch/.test(rein)) {
|
|
for (const m of rein.matchAll(/setViewportSize\s*\(\s*\{[^}]{0,150}\}/g)) {
|
|
const br = [...m[0].matchAll(/width\s*:\s*(\d{3,4})\b/g)].map((z) => Number(z[1]));
|
|
if (!br.length) continue;
|
|
raus.push({ schmal: br.some((x) => x <= SCHMAL), finger: false });
|
|
}
|
|
}
|
|
return raus;
|
|
};
|
|
|
|
/* Ein Fenster ist nur dann ein Befund, wenn die Datei ueberhaupt
|
|
MISST. Wer bei 390 px nachsieht, ob ein Text dasteht, braucht
|
|
keinen Finger. */
|
|
export const blindeStellen = (text) => (MISST.test(text)
|
|
? fensterStellen(text).filter((f) => f.schmal && !f.finger).length : 0);
|
|
export const fingerlos = (text) => blindeStellen(text) > 0;
|
|
|
|
console.log("\n=== 1. Wer misst am Telefon ohne Finger? ===");
|
|
const dateien = readdirSync(ORDNER)
|
|
.filter((n) => /^(pruef|mess)-.*\.mjs$/.test(n) && n !== "pruef-fingermass.mjs");
|
|
|
|
/* DRITTER AUSGANG: Findet sie nichts zum Ansehen, ist das kein
|
|
„alles in Ordnung", sondern „konnte nicht nachsehen". */
|
|
if (dateien.length < 50) {
|
|
console.log(` FEHL Nur ${dateien.length} Pruefdateien gefunden — der Ordner stimmt nicht.`);
|
|
console.log(" Erwartet werden ueber 150 in " + ORDNER);
|
|
process.exit(2);
|
|
}
|
|
|
|
const funde = [];
|
|
let blind = 0, mitFinger = 0, amTelefon = 0;
|
|
for (const name of dateien) {
|
|
const text = readFileSync(join(ORDNER, name), "utf8");
|
|
const schmale = fensterStellen(text).filter((f) => f.schmal);
|
|
if (!schmale.length) continue;
|
|
amTelefon++;
|
|
mitFinger += schmale.filter((f) => f.finger).length;
|
|
const b = blindeStellen(text);
|
|
if (b) { blind += b; funde.push(`${name} (${b})`); }
|
|
}
|
|
|
|
console.log(` ${amTelefon} Dateien oeffnen ein Telefonformat, `
|
|
+ `${mitFinger} dieser Fenster haben einen Finger.`);
|
|
if (funde.length) console.log(" blinde Fenster mit Massband: " + funde.join(", "));
|
|
|
|
ok(amTelefon > 20, `${amTelefon} Dateien messen am Telefon — die Suche findet ueberhaupt etwas`);
|
|
|
|
if (blind > GRUNDLINIE) {
|
|
ok(false, `${blind} blinde Fenster — das sind ${blind - GRUNDLINIE} MEHR als die `
|
|
+ `Grundlinie ${GRUNDLINIE}. Neu dazugekommen ist eine Messung, die auf einem `
|
|
+ "Telefonformat eine Seite vermisst, die es auf keinem Telefon gibt. "
|
|
+ "`hasTouch: true` gehoert in den newContext-Aufruf — setViewportSize kann es "
|
|
+ "nicht nachtragen.");
|
|
} else if (blind < GRUNDLINIE) {
|
|
ok(false, `Nur noch ${blind} blinde Fenster — die Grundlinie steht auf ${GRUNDLINIE}. `
|
|
+ `Bitte in pruef-fingermass.mjs auf ${blind} senken, sonst deckt sie Platz fuer `
|
|
+ "die naechste.");
|
|
} else {
|
|
ok(true, `${blind} blinde Fenster mit Massband — unveraendert zur Grundlinie ${GRUNDLINIE}`);
|
|
}
|
|
|
|
console.log("\n=== 2. Gegenprobe: kann sie auch NICHT IN ORDNUNG sagen? ===");
|
|
const faelle = [
|
|
["der Fall vom 29.09. (schmal, misst, kein Finger)",
|
|
'const s = await b.newContext({ viewport: { width: 412, height: 900 } });\n'
|
|
+ 'el.getBoundingClientRect()', 1],
|
|
["mit Finger",
|
|
'const s = await b.newContext({ viewport: { width: 412, height: 900 }, hasTouch: true });\n'
|
|
+ 'el.getBoundingClientRect()', 0],
|
|
["nur ein Laptopfenster",
|
|
'const s = await b.newContext({ viewport: { width: 1280, height: 900 } });\n'
|
|
+ 'el.getBoundingClientRect()', 0],
|
|
["schmal, misst aber nichts",
|
|
'const s = await b.newContext({ viewport: { width: 390, height: 844 } });\n'
|
|
+ 'await p.textContent("h1")', 0],
|
|
["eine Breite, die nur im Kommentar steht",
|
|
'/* gemessen bei width: 412 -- drei Zeilen */\n'
|
|
+ 'const s = await b.newContext({ viewport: { width: 1440, height: 900 } });\n'
|
|
+ 'el.getBoundingClientRect()', 0],
|
|
["setViewportSize statt newContext — kann hasTouch gar nicht setzen",
|
|
'await p.setViewportSize({ width: 390, height: 844 });\nel.offsetWidth', 1],
|
|
/* DER FEHLALARM AUS DEM ERSTEN LAUF: Wer einen Finger-Kontext
|
|
anlegt und danach nur die Groesse aendert, behaelt den Finger. */
|
|
["Groesse aendern an einer Seite, die schon einen Finger hat",
|
|
'const c = await b.newContext({ viewport: { width: 900, height: 900 },\n'
|
|
+ ' hasTouch: breite < 900 });\n'
|
|
+ 'await p.setViewportSize({ width: 390, height: 844 });\nel.offsetWidth', 0],
|
|
/* DER FALL, AN DEM DIE ERSTE FASSUNG SCHEITERTE: Ein Finger in der
|
|
Datei, drei blinde Fenster daneben. Sie sprach die ganze Datei
|
|
frei. */
|
|
["ein Finger spricht nicht die ganze Datei frei",
|
|
'const a = await b.newContext({ viewport: { width: 390, height: 844 }, hasTouch: true });\n'
|
|
+ 'const c = await b.newContext({ viewport: { width: 412, height: 900 } });\n'
|
|
+ 'el.getBoundingClientRect()', 1],
|
|
["zwei blinde Fenster sind zwei Befunde, nicht einer",
|
|
'const a = await b.newContext({ viewport: { width: 390, height: 844 } });\n'
|
|
+ 'const c = await b.newContext({ viewport: { width: 412, height: 900 } });\n'
|
|
+ 'el.getBoundingClientRect()', 2],
|
|
];
|
|
const daneben = faelle
|
|
.filter(([, text, soll]) => blindeStellen(text) !== soll)
|
|
.map(([n, text, soll]) => `${n} (${blindeStellen(text)} statt ${soll})`);
|
|
ok(daneben.length === 0,
|
|
daneben.length ? `Gegenprobe daneben bei: ${daneben.join(", ")}`
|
|
: `Gegenprobe: alle ${faelle.length} Faelle richtig eingeordnet`);
|
|
|
|
console.log(`\n${ok_} Pruefungen, ${fehl} Fehler`);
|
|
console.log(fehl ? "NICHT IN ORDNUNG\n" : "ALLES IN ORDNUNG\n");
|
|
process.exit(fehl ? 1 : 0);
|