Auf dem Brett steht jetzt Deutsch, nicht ASCII
Unter jeder Kategorie stand eine Erklaerung ohne Umlaute: "Was im Livechat passiert, waehrend gesendet wird. Loeschen, stummschalten, begruessen, deeskalieren." Elf der vierzehn Kategorien und alle drei Stufen waren betroffen, dazu vier Stellen mit zwei Bindestrichen statt eines Gedankenstrichs. Entstanden ist es beim Schreiben ueber Hilfsskripte, die an Umlauten scheitern -- fuer einen Kommentar gleichgueltig, fuer einen Satz, den ein Mensch liest, ein Fehler. Gesehen hat es keine Pruefung: Der Text war inhaltlich richtig, der Katalog vollstaendig, alles gruen. Aufgefallen ist es auf einem Bildschirmfoto. NEU: pruef-deutsche-texte (9 Pruefungen) Sieht 174 Katalogtexte und 28 ausgelieferte Seiten durch. Bewusst eine Liste von Wortstuecken statt eines Musters aus Buchstabenfolgen: "ue" ist in "Feuer" und "neue" richtig, "ss" in jedem zweiten Wort. Die Liste ist ein Netz, kein Beweis, und der Kopf der Datei sagt das. Die Skripte bleiben absichtlich aussen vor. Ausprobiert: Dieselbe Liste schlaegt dort 71 Mal an und kein einziges Mal zu Recht -- es sind Feldnamen, Stilklassen und Adressen, die ASCII sein MUESSEN. Eine Warnung, die immer kommt, ist keine Warnung mehr. Ihr sichtbarer Text wird deshalb am fertigen Bildschirm geprueft, ueber innerText. AUSSERDEM, auf demselben Bildschirmfoto gefunden: Die Fusszeile der Vorlagenkarten war eine starre Flex-Zeile. Bei einer schon uebernommenen Aufgabe stehen dort drei Dinge statt zwei, und "Frist: in 2 Tagen" brach mitten im Wort auf drei Zeilen um. Keine neue feste Breite dagegen, sondern flex-wrap plus nowrap -- eine Regel, die misst, statt einer Zahl, die beim naechsten Element wieder faellig waere. UND EINE LEHRE ZUM MESSEN: Die erste Fassung dieser Pruefung zaehlte element.getClientRects(). Sie blieb gruen, auch mit dem Fehler wieder eingebaut -- ein Flex-Kind wird zum Block und liefert immer genau ein Rechteck. Gefunden hat das nur die Gegenprobe. Gemessen wird jetzt ueber einen Bereich um den Textknoten. Das Bildschirmfoto landet ausserdem dort, wo die Zeile darunter es ansagt (server/), nicht im Arbeitsverzeichnis. pruef-modi-katalog 49 (vorher 45), pruef-deutsche-texte 9, pruef-css-klassen, pruef-struktur, pruef-vorlagen, pruef-aufgaben-vorlagen: alle ohne Fehler. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -31,6 +31,8 @@ const express = (await import("express")).default;
|
||||
const ec = express.response.cookie;
|
||||
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
|
||||
import { notbremse } from "./helfer-notbremse.mjs";
|
||||
import { ersatzschreibungen } from "./helfer-deutsch.mjs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
await import("./index.js");
|
||||
notbremse(180_000, "pruef-modi-katalog");
|
||||
await new Promise((r) => setTimeout(r, 700));
|
||||
@@ -304,12 +306,41 @@ console.log("\n=== 6. Das Brett im echten Browser ===\n");
|
||||
/* ZWEI REIHEN SEIT DEM 16.09.2026: oben die Kategorien, darunter
|
||||
die Stufen. Getrennt gezaehlt -- eine gemeinsame Zahl haette
|
||||
nicht gesagt, WELCHE der beiden fehlt. */
|
||||
/* UEBER DIE BESCHRIFTUNG UNTERSCHIEDEN, nicht ueber eine
|
||||
Hilfsklasse (16.09.2026). Seit die Stufenreihe genauso aussieht
|
||||
wie die Kategorienreihe -- so wollte Filipe es -- gibt es im
|
||||
Aussehen keinen Unterschied mehr. Den gibt es aber im SINN, und
|
||||
der steht ohnehin da: in dem Wort, das ein Vorleseprogramm
|
||||
ansagt. Eine Klasse nur zum Wiederfinden waere eine zweite
|
||||
Wahrheit ueber dieselbe Sache. */
|
||||
kategorien: [...document.querySelectorAll(
|
||||
".stufenleiter:not(.stufenleiter--fein) .stufenleiter__name")]
|
||||
'[aria-label="Kategorie wählen"] .stufenleiter__name')]
|
||||
.map((z) => z.textContent.trim()),
|
||||
stufen: [...document.querySelectorAll(
|
||||
".stufenleiter--fein .stufenleiter__name")].map((z) => z.textContent.trim()),
|
||||
'[aria-label="Stufe wählen"] .stufenleiter__name')]
|
||||
.map((z) => z.textContent.trim()),
|
||||
karten: document.querySelectorAll(".vorlagenbrett__karte").length,
|
||||
/* WIE VIELE ZEILEN BRAUCHT DIE FRIST? Gemessen ueber einen
|
||||
Bereich um den TEXT, nicht ueber das Element.
|
||||
|
||||
ERST FALSCH GEMESSEN, und die Gegenprobe hat es verraten:
|
||||
`element.getClientRects()` liefert hier IMMER genau ein
|
||||
Rechteck, weil ein Flex-Kind zu einem Block wird -- die
|
||||
Pruefung blieb gruen, auch mit dem Fehler wieder eingebaut.
|
||||
Ein Bereich ueber den Textknoten dagegen gibt pro Zeilenkasten
|
||||
ein Rechteck, und genau das ist die Frage: Steht "in 2 Tagen"
|
||||
auf einer Zeile oder als "in / 2 / Tagen" untereinander? */
|
||||
fristZeilen: [...document.querySelectorAll(".vorlagenbrett__frist")]
|
||||
.map((z) => {
|
||||
const b = document.createRange();
|
||||
b.selectNodeContents(z);
|
||||
return b.getClientRects().length;
|
||||
}),
|
||||
/* Und wie viele Karten tragen ueberhaupt den DRITTEN Eintrag, an
|
||||
dem es eng wurde. Ohne diese Zahl wuerde die Zeile darueber
|
||||
auch dann gruen, wenn der enge Fall gar nicht auf dem Schirm
|
||||
war. */
|
||||
engeKarten: document.querySelectorAll(".vorlagenbrett__schon").length,
|
||||
text: document.body.innerText,
|
||||
kopf: (document.querySelector(".kopfleiste .marke__text") || {}).textContent || "",
|
||||
}));
|
||||
@@ -334,9 +365,49 @@ console.log("\n=== 6. Das Brett im echten Browser ===\n");
|
||||
/* Und der Seitenname dahinter steht noch da -- ihn beim Austausch
|
||||
zu verlieren waere lautlos passiert. */
|
||||
ok(/Aufgaben/.test(bild.kopf), "der Seitenname dahinter blieb erhalten");
|
||||
/* DIE FUSSZEILE DER KARTEN (16.09.2026, auf dem Bildschirmfoto
|
||||
gefunden). Bei einer schon uebernommenen Aufgabe stehen dort
|
||||
drei Dinge statt zwei, und "Frist: in 2 Tagen" brach mitten im
|
||||
Wort auf drei Zeilen um. Die Karten sind alle gleich breit --
|
||||
eine einzige gequetschte reicht, um den Fehler zu zeigen. */
|
||||
ok(bild.engeKarten > 0,
|
||||
`${bild.engeKarten} Karten tragen den dritten Fusseintrag (der enge Fall)`);
|
||||
const zuViel = bild.fristZeilen.filter((n) => n !== 1).length;
|
||||
ok(bild.fristZeilen.length > 0 && zuViel === 0,
|
||||
`jede der ${bild.fristZeilen.length} Fristangaben steht auf einer Zeile`
|
||||
+ (zuViel ? ` -- ${zuViel} umgebrochen` : ""));
|
||||
|
||||
/* UMLAUTE AUF DEM FERTIGEN BILDSCHIRM (16.09.2026).
|
||||
Am 16.09. stand unter jeder Kategorie eine Erklaerung in ASCII:
|
||||
"Was im Livechat passiert, waehrend gesendet wird. Loeschen,
|
||||
stummschalten, begruessen". Alles gruen, niemand hat es gemerkt.
|
||||
|
||||
HIER und nicht im Quelltext, weil hier der Unterschied sichtbar
|
||||
wird, auf den es ankommt: `innerText` ist, was ein Mensch liest.
|
||||
Feldnamen, Stilklassen und Adressen -- die ASCII sein MUESSEN --
|
||||
stehen nicht drin. Im Quelltext derselben Skripte schlaegt
|
||||
dieselbe Liste 71 Mal an, und kein einziges Mal zu Recht.
|
||||
|
||||
Die Kataloge und die festen Seitentexte prueft
|
||||
pruef-deutsche-texte, ohne Browser. */
|
||||
const ersatz = ersatzschreibungen(bild.text);
|
||||
ok(bild.text.length > 400 && ersatz.length === 0,
|
||||
ersatz.length
|
||||
? `Ersatzschreibungen auf dem Brett: ${ersatz.join(", ")}`
|
||||
: `der Text auf dem Brett traegt Umlaute (${bild.text.length} Zeichen geprueft)`);
|
||||
/* GEGENPROBE, sonst hiesse "nichts gefunden" nur, dass nichts
|
||||
gesucht wurde -- etwa wenn `innerText` leer bliebe. */
|
||||
ok(ersatzschreibungen(`${bild.text} waehrend`).length === 1,
|
||||
"und ein eingeschmuggeltes waehrend wuerde auffallen");
|
||||
ok(konsole.length === 0,
|
||||
konsole.length ? `Fehler in der Konsole: ${konsole[0]}` : "keine Fehler in der Konsole");
|
||||
await seite.screenshot({ path: "pruef-modi-katalog.png", fullPage: false });
|
||||
/* DER PFAD GEHOERT AN DIESE DATEI, nicht ans Arbeitsverzeichnis.
|
||||
Vorher stand hier ein blosser Dateiname: Das Bild landete dort,
|
||||
von wo aus gestartet wurde, waehrend die Zeile darunter
|
||||
"server/..." meldete. Man sucht es dann an der falschen Stelle
|
||||
-- oder findet ein altes und haelt es fuer das neue. */
|
||||
const bildPfad = fileURLToPath(new URL("pruef-modi-katalog.png", import.meta.url));
|
||||
await seite.screenshot({ path: bildPfad, fullPage: false });
|
||||
console.log(" -- Bildschirmfoto: server/pruef-modi-katalog.png");
|
||||
await kontext.close();
|
||||
} finally {
|
||||
@@ -388,8 +459,8 @@ console.log("");
|
||||
}
|
||||
|
||||
const wahl = await seite.evaluate(() => {
|
||||
const reihen = [...document.querySelectorAll(".stufenleiter--fein")];
|
||||
const letzte = reihen[reihen.length - 1];
|
||||
const reihen = [...document.querySelectorAll(".stufenleiter")];
|
||||
const letzte = document.querySelector('[aria-label="Person wählen"]');
|
||||
const zahl = /^[0-9]+$/;
|
||||
return {
|
||||
reihen: reihen.length,
|
||||
@@ -399,14 +470,19 @@ console.log("");
|
||||
.every((z) => zahl.test(z.textContent.trim())),
|
||||
zahlen: [...(letzte?.querySelectorAll(".stufenleiter__zahl") || [])]
|
||||
.map((z) => z.textContent.trim()),
|
||||
satz: [...document.querySelectorAll(".vorlagenbrett__stand")]
|
||||
/* Der Satz steht seit dem 16.09.2026 in `stufenleiter__hilfe`
|
||||
-- derselbe Baustein wie beim anderen Brett. Vorher war es
|
||||
`vorlagenbrett__stand`, und das ist die Zeile fuer Zahlen. */
|
||||
satz: [...document.querySelectorAll(".stufenleiter__hilfe")]
|
||||
.map((z) => z.textContent.trim())
|
||||
.find((t) => t.includes("Formular oben") || t.includes("gehen an")) || "",
|
||||
};
|
||||
});
|
||||
/* ZWEI FEINE REIHEN: die Stufen und die Personen. Eine einzelne
|
||||
Zahl haette nicht gesagt, welche der beiden fehlt. */
|
||||
ok(wahl.reihen === 2, "zwei Auswahlreihen (Stufen und Personen): " + wahl.reihen);
|
||||
/* DREI REIHEN: Kategorie, Stufe, Person. Die ersten beiden sehen
|
||||
jetzt aus wie drueben beim anderen Brett. */
|
||||
ok(wahl.reihen === 3, "drei Auswahlreihen (Kategorie, Stufe, Person): " + wahl.reihen);
|
||||
ok(wahl.namen.includes("Marina"),
|
||||
"der Modi steht zur Auswahl (" + wahl.namen.join(", ") + ")");
|
||||
ok(!wahl.namen.includes("Tili") && !wahl.namen.includes("Schulle"),
|
||||
@@ -420,14 +496,14 @@ console.log("");
|
||||
DIESEM Menschen landet. Ein Knopf, den niemand betaetigt hat,
|
||||
ist kein geprueter Knopf. */
|
||||
await seite.evaluate(() => {
|
||||
const reihen = [...document.querySelectorAll(".stufenleiter--fein")];
|
||||
const letzte = reihen[reihen.length - 1];
|
||||
const reihen = [...document.querySelectorAll(".stufenleiter")];
|
||||
const letzte = document.querySelector('[aria-label="Person wählen"]');
|
||||
[...letzte.querySelectorAll(".stufenleiter__knopf")]
|
||||
.find((k) => k.textContent.includes("Marina"))?.click();
|
||||
});
|
||||
await seite.waitForTimeout(600);
|
||||
const nachWahl = await seite.evaluate(() =>
|
||||
[...document.querySelectorAll(".vorlagenbrett__stand")]
|
||||
[...document.querySelectorAll(".stufenleiter__hilfe")]
|
||||
.map((z) => z.textContent.trim()).find((t) => t.includes("gehen an")) || "");
|
||||
ok(nachWahl.includes("Marina"), "nach dem Klick steht es da: " + nachWahl);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user