diff --git a/server/pruef-start-ansicht.mjs b/server/pruef-start-ansicht.mjs
index 25ec7ece..ade37920 100644
--- a/server/pruef-start-ansicht.mjs
+++ b/server/pruef-start-ansicht.mjs
@@ -125,7 +125,9 @@ const lesen = (seite) => seite.evaluate(() => ({
name: k.querySelector(".kachel__name")?.textContent,
unter: k.querySelector(".kachel__unter")?.textContent,
ton: k.dataset.ton,
- farbe: getComputedStyle(k.querySelector(".kachel__svg")).stroke,
+ hatZeichen: !!k.querySelector(".kachel__svg"),
+ farbe: k.querySelector(".kachel__svg")
+ ? getComputedStyle(k.querySelector(".kachel__svg")).stroke : null,
pfade: k.querySelectorAll(".kachel__svg path").length,
zahl: k.querySelector(".kachel__zahl")?.textContent || null,
warn: k.querySelector(".kachel__zahl")?.dataset.warn === "ja",
@@ -147,9 +149,18 @@ const lesen = (seite) => seite.evaluate(() => ({
ton: z.dataset.ton || null,
stufe: z.dataset.stufe,
pfade: z.querySelectorAll(".dran__svg path").length,
- strich: getComputedStyle(z.querySelector(".dran__svg")).stroke,
+ /* KEIN ABSTURZ BEI EINEM FEHLENDEN TEIL (20.09.2026).
+ Hier stand `getComputedStyle(z.querySelector(".dran__svg"))` --
+ und als gestern ein Hinweis ohne Kachel dazukam, hatte die Zeile
+ kein Zeichen. Die Pruefung starb mit "parameter 1 is not of type
+ Element" und sagte damit gar nichts ueber die Seite. Ein
+ fehlendes Teil ist ein BEFUND, kein Absturz. */
+ hatZeichen: !!z.querySelector(".dran__svg"),
+ strich: z.querySelector(".dran__svg")
+ ? getComputedStyle(z.querySelector(".dran__svg")).stroke : null,
zahl: z.querySelector(".dran__zahl")?.textContent || null,
- zahlFarbe: getComputedStyle(z.querySelector(".dran__zahl")).color,
+ zahlFarbe: z.querySelector(".dran__zahl")
+ ? getComputedStyle(z.querySelector(".dran__zahl")).color : null,
text: z.querySelector(".dran__text")?.textContent || "",
label: z.querySelector(".dran__link")?.getAttribute("aria-label") || "",
})),
@@ -435,30 +446,63 @@ for (const [breite, wie] of [[1440, "Computer"], [390, "Handy"]]) {
ok(r.hinweise <= 4, `höchstens vier Hinweise sichtbar (${r.hinweise} von ${r.hinweiseGesamt})`);
/* --- Die Hinweiszeilen ------------------------------------------------
- Eine Zeile ohne Zeichen oder ohne Zahl waere ein halbes Bauteil und
- faellt beim Ueberfliegen sofort auf. */
+ Eine Zeile ohne Zeichen waere ein halbes Bauteil und faellt beim
+ Ueberfliegen sofort auf.
+
+ ZWEI SORTEN HINWEISE (20.09.2026). Bis gestern zaehlte jeder
+ Hinweis etwas -- "2 Aufgaben sind ueberfaellig". Seit es
+ "Bei dir klingelt nichts" gibt, stimmt das nicht mehr: Das ist
+ ein ZUSTAND, keine Menge. Eine erfundene "1" davor waere Rauschen,
+ und eine geborgte Kachelfarbe wuerde einen Bereich behaupten, zu
+ dem der Hinweis nicht gehoert.
+
+ Die Pruefung unterscheidet deshalb jetzt, statt einer Sorte alles
+ abzuverlangen. Das ist nicht die schwaechere Pruefung, sondern die
+ genauere: Sie sagt ausserdem, WIE VIELE von jeder Sorte da sind --
+ faellt eine Sorte ganz weg, sieht man es. */
ok(r.dranZeilen.length > 0, `es liegen Hinweise vor (${r.dranZeilen.length})`);
ok(r.dranZeilen.every((z) => z.pfade > 0),
- `jede Hinweiszeile trägt ihr Zeichen (${r.dranZeilen.filter((z) => !z.pfade).length} ohne)`);
- ok(r.dranZeilen.every((z) => /^[1-9]\d*$/.test(z.zahl || "")),
- `jede Hinweiszeile stellt ihre Zahl voran (${r.dranZeilen.map((z) => z.zahl).join(",")})`);
+ `JEDE Hinweiszeile trägt ihr Zeichen (${r.dranZeilen.filter((z) => !z.pfade).length} ohne)`);
+
+ const zaehlende = r.dranZeilen.filter((z) => z.zahl !== null);
+ const zustaende = r.dranZeilen.filter((z) => z.zahl === null);
+ ok(zaehlende.length > 0 && zaehlende.every((z) => /^[1-9]\d*$/.test(z.zahl)),
+ `jeder ZÄHLENDE Hinweis stellt seine Zahl voran `
+ + `(${zaehlende.length} zählend, ${zustaende.length} Zustand)`);
+ /* Und ein Zustand traegt dafuer einen Satz, der fuer sich steht. */
+ ok(zustaende.every((z) => z.text.length > 12),
+ `jeder ZUSTANDS-Hinweis sagt es in Worten `
+ + `(${zustaende.map((z) => z.text.slice(0, 32)).join(" | ") || "keiner"})`);
/* Die Zahl steht vorn -- im Satz darf sie nicht noch einmal stehen. */
ok(r.dranZeilen.every((z) => !/^\d/.test(z.text)),
`und keine Zahl steht doppelt (${r.dranZeilen.map((z) => z.text).find((t) => /^\d/.test(t)) || "keine"})`);
/* Vorleseprogramme bekommen den ganzen Satz, nicht "2" und "Aufgaben sind
überfällig" als zwei Bruchstuecke. */
- ok(r.dranZeilen.every((z) => z.label.includes(z.zahl) && z.label.length > 10),
- "und der ganze Satz steht für Vorleseprogramme dran");
+ ok(r.dranZeilen.every((z) => z.label.length > 10
+ && (z.zahl === null || z.label.includes(z.zahl))),
+ `und der ganze Satz steht für Vorleseprogramme dran `
+ + `(${r.dranZeilen.filter((z) => z.label.length <= 10).length} zu kurz)`);
/* Farbe folgt dem Bereich, nicht dem Bauteil: Der Ton der Zeile muss
der Ton einer wirklich vorhandenen Kachel sein. */
const kachelToene = new Set(r.kacheln.map((k) => k.ton));
- ok(r.dranZeilen.every((z) => z.ton && kachelToene.has(z.ton)),
- `jede Zeile trägt den Farbton ihrer Kachel (${r.dranZeilen.map((z) => z.ton).join(",")})`);
+ /* Ein Hinweis, der zu einem Bereich gehoert, traegt DESSEN Ton.
+ Einer, der zu keinem gehoert, traegt GAR KEINEN -- er soll keinen
+ Bereich behaupten. Beides wird geprueft; "hat irgendeinen Ton"
+ waere die schwaechere Aussage. */
+ const mitBereich = r.dranZeilen.filter((z) => z.ton !== null);
+ const ohneBereich = r.dranZeilen.filter((z) => z.ton === null);
+ ok(mitBereich.length > 0 && mitBereich.every((z) => kachelToene.has(z.ton)),
+ `jede Zeile MIT Bereich trägt dessen Farbton `
+ + `(${mitBereich.map((z) => z.ton).join(",")})`);
+ ok(ohneBereich.every((z) => z.pfade > 0),
+ `und eine Zeile OHNE Bereich hat trotzdem ihr Zeichen `
+ + `(${ohneBereich.length} solche)`);
/* Und zwar wirklich DIESELBE Farbe, an echten Bildpunkten gemessen --
"hat einen Ton" reicht nicht, sonst faellt nicht auf, wenn alle
Zeilen denselben tragen. */
const kachelFarbe = new Map(r.kacheln.map((k) => [k.ton, k.farbe]));
const falsch = r.dranZeilen.filter((z) => z.stufe !== "warnung")
+ .filter((z) => z.ton !== null && z.zahlFarbe !== null)
.filter((z) => z.zahlFarbe !== kachelFarbe.get(z.ton));
ok(falsch.length === 0,
`und die Farbe ist die der Kachel (${falsch.map((z) => `${z.ton}: ${z.zahlFarbe} statt ${kachelFarbe.get(z.ton)}`).join(" | ") || "alle"})`);
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index eac9bbc4..113be0f8 100644
--- a/workspace/anruf-probe.html
+++ b/workspace/anruf-probe.html
@@ -16,15 +16,15 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
-
-
+
+
-
+