diff --git a/server/pruef-chatkachel.mjs b/server/pruef-chatkachel.mjs
index c803895d..1417356f 100644
--- a/server/pruef-chatkachel.mjs
+++ b/server/pruef-chatkachel.mjs
@@ -475,12 +475,69 @@ try {
/* Mitten in der Kachel -- nicht am Rand, dort liegen Kante und
abgerundete Ecke. */
kachel: { x: Math.round(rb.left + rb.width / 2), y: Math.round(rb.top + rb.height / 2) },
- /* Und ein Fleck im Verlauf, auf dem sicher keine Kachel liegt:
- ganz rechts aussen, wo die eigenen Nachrichten nicht hinreichen. */
- frei: { x: Math.round(rv.right - 6), y: Math.round(rv.top + rv.height / 2) },
+ /* Die freie Stelle steht weiter unten -- sie wird GESUCHT. */
+ frei: null,
};
});
- ok(!!punkte, "Kachel und freie Fläche gefunden");
+
+ /* ==== DIE FREIE STELLE WIRD GESUCHT, NICHT GERATEN ================
+ (nachgebessert 25.09.2026, nach zwei Fehlalarmen an einem Abend)
+
+ Hier stand ein fester Punkt: „6 Pixel vom rechten Rand, auf halber
+ Hoehe". Das hat zweimal dasselbe Ergebnis gehabt -- rot, ohne dass
+ an der Sache etwas war:
+
+ 1. `rect.right` schliesst den ROLLBALKEN ein. Sobald der Verlauf
+ laenger wird als das Fenster, liegt der Punkt auf ihm: eine
+ deckende Flaeche, die sich nicht aendert, wenn man das
+ Buehnenbild abschaltet.
+ 2. Auch ohne Balken ist „halbe Hoehe" nicht frei. Eigene
+ Nachrichten stehen rechtsbuendig und reichen bis an die
+ Polsterung; wird eine Blase um ein paar Pixel hoeher (heute:
+ die Handgriffe sitzen jetzt in einer Mulde), liegt auf halber
+ Hoehe ploetzlich eine Kachel. Die Pruefung meldet dann „das
+ Buehnenbild ist gar nicht da", und der Fehler steht an einer
+ Stelle, die niemand im Verdacht hat.
+
+ Der Punkt ist also nicht die Sache -- die Sache ist „eine Stelle
+ im Verlauf, auf der KEINE Kachel liegt". Genau das laesst sich
+ fragen, statt es auszurechnen: `elementFromPoint` sagt, was an
+ einer Stelle obenauf liegt. Gesucht wird von oben nach unten, bis
+ dort keine Nachricht mehr ist.
+
+ UND WENN ES KEINE GIBT, wird das gesagt und nicht geschwiegen --
+ der dritte Ausgang: Eine Messung, die ihre Voraussetzung nicht
+ findet, muss scheitern, nicht bestaetigen. */
+ const freiePunkte = await s.evaluate(() => {
+ const v = document.querySelector(".chat__verlauf");
+ if (!v) return null;
+ const rv = v.getBoundingClientRect();
+ /* `clientWidth` laesst den Rollbalken aussen vor, die 6 px liegen
+ damit immer in der 18-px-Polsterung des Verlaufs. */
+ const x = Math.round(rv.left + v.clientWidth - 6);
+ for (let y = Math.round(rv.top) + 10; y < rv.bottom - 10; y += 6) {
+ const e = document.elementFromPoint(x, y);
+ /* Nicht nur „ist keine Blase", sondern „gehoert zu gar keiner
+ Nachricht": Reaktionen, Zitate und Anhaenge sind ebenfalls
+ deckend und haengen an derselben Zeile. */
+ if (e && !e.closest(".chat-nachricht") && v.contains(e)) {
+ return { x, y, gefunden: true };
+ }
+ }
+ /* KEIN `null`. Die Pruefung soll scheitern und trotzdem
+ weiterlaufen -- mit `null` wuerde die naechste Aufnahme
+ abstuerzen, und ein Absturz sagt weniger als ein roter Punkt
+ mit Begruendung. Der Ersatzpunkt liegt oben in der Polsterung;
+ er misst dann eben nichts Aussagekraeftiges, und genau das
+ steht in der Zeile darueber. */
+ return { x, y: Math.round(rv.top) + 10, gefunden: false };
+ });
+ ok(!!punkte && !!freiePunkte && freiePunkte.gefunden,
+ freiePunkte && freiePunkte.gefunden
+ ? `Kachel und freie Fläche gefunden (frei bei y ${freiePunkte.y})`
+ : "ABBRUCH: im Verlauf ist keine Stelle ohne Kachel zu finden — "
+ + "ohne sie lässt sich nicht nachweisen, dass das Bühnenbild da ist");
+ if (punkte && freiePunkte) punkte.frei = freiePunkte;
/* Playwright kann einen Ausschnitt aufnehmen -- ein Bildpunkt reicht. */
const punktFarbe = async (pkt) => {
diff --git a/server/pruef-erwaehnung.mjs b/server/pruef-erwaehnung.mjs
index f58fd179..ec8ea69c 100644
--- a/server/pruef-erwaehnung.mjs
+++ b/server/pruef-erwaehnung.mjs
@@ -754,11 +754,43 @@ try {
Jetzt der Fall, um den es wirklich geht: Sie ist woanders, und es
kommt etwas für sie herein. */
+ /* ==== DIE LISTE HAT SEIT DEM 25.09.2026 DREI FAECHER =============
+
+ Filipe: „ich will 3 kategorien haben. chats mit einzelnen
+ personen, gruppen chats und kanäle."
+
+ Diese Erwaehnung liegt in einer GRUPPE („Testgruppe", weiter
+ oben), das voreingestellte Fach ist „Personen" -- die Zeile mit
+ dem @ steht also nicht in der Liste, bevor man das Fach wechselt.
+ Die Pruefung ist daran rot geworden, und das war RICHTIG: Sie hat
+ eine echte Luecke gefunden, keine Aeusserlichkeit. Ein Ruf, den
+ ein geschlossenes Fach verschluckt, ist schlimmer als gar keiner.
+
+ GEBAUT WURDE DARAUFHIN das @ AM FACH (`.chat-art__at`). Die
+ Pruefung misst jetzt beides und sagt damit mehr als vorher:
+
+ 1. Das Fach „Gruppen" traegt das Zeichen, OHNE dass man es
+ oeffnet -- man sieht, dass etwas wartet.
+ 2. Im Fach „Personen" steht die Zeile dabei NICHT (Gegenprobe:
+ das Fach filtert wirklich, das Zeichen ist keine Dekoration).
+ 3. Nach dem Wechsel steht die Zeile mit ihrem @ da.
+
+ EIN HELFER STATT DREI ABSCHRIFTEN: Jede Stelle, die ein Fach
+ waehlt, tut es hier gleich -- sonst waere die dritte die, die
+ auf das Warten verzichtet. */
+ const fachWaehlen = async (seite, art) => {
+ await seite.click(`.chat-art[data-art="${art}"]`);
+ await seite.waitForTimeout(400);
+ };
+
await vs.goto(`${BASIS}/workspace/chat.html`, { waitUntil: "networkidle" });
await vs.waitForTimeout(900);
+ await fachWaehlen(vs, "gruppe");
const vorSchon = await vs.locator(".chat-raum__erwaehnt").count();
ok(vorSchon === 0,
`solange nichts Neues da ist, leuchtet auch nichts (${vorSchon})`);
+ const vorFach = await vs.locator(".chat-art__at").count();
+ ok(vorFach === 0, ` und auch an keinem der drei Fächer (${vorFach})`);
await s.click("#text");
await s.type("#text", "@VanVan noch eine Sache", { delay: 15 });
@@ -767,6 +799,32 @@ try {
await vs.reload({ waitUntil: "networkidle" });
await vs.waitForTimeout(1200);
+ /* ERST ZURUECK AUF „Personen". Der erste Anlauf verliess sich
+ darauf, dass das Neuladen dort landet -- tat es nicht, und die
+ Gegenprobe war rot: Die Wahl des Fachs UEBERLEBT das Neuladen
+ (localStorage, Absicht seit dem 25.09.2026 -- wer im Kanal
+ arbeitet, arbeitet meist den ganzen Tag im Kanal).
+
+ Das ist ein Fund und kein Aergernis: Die Pruefung hat damit
+ nebenbei belegt, dass das Merken wirklich greift. Der Fall, um
+ den es hier geht, muss aber ausdruecklich hergestellt werden --
+ sie steht in einem ANDEREN Fach, und der Ruf liegt woanders. */
+ await fachWaehlen(vs, "direkt");
+ const fachAt = vs.locator(".chat-art__at");
+ ok(await fachAt.count() === 1,
+ `das Fach mit der Erwähnung trägt das @-Zeichen, ungeöffnet (${await fachAt.count()})`);
+ const amFach = await vs.locator('.chat-art[data-art="gruppe"] .chat-art__at').count();
+ ok(amFach === 1, ` und zwar genau an „Gruppen" (${amFach})`);
+ ok((await fachAt.first().getAttribute("aria-label") || "").includes("erwähnt"),
+ " mit einem Satz für Vorleseprogramme statt eines nackten Zeichens");
+ /* GEGENPROBE: Im falschen Fach steht die Zeile nicht -- das Fach
+ filtert wirklich. Ohne diese Zeile koennte das @ am Fach auch
+ dann gruen sein, wenn die Liste gar nicht filtert. */
+ const zeileFalschesFach = await vs.locator(".chat-raum__erwaehnt").count();
+ ok(zeileFalschesFach === 0,
+ `Gegenprobe: im Fach „Personen" steht die Zeile nicht (${zeileFalschesFach}) — das Fach filtert wirklich`);
+
+ await fachWaehlen(vs, "gruppe");
const zeichen = vs.locator(".chat-raum__erwaehnt");
ok(await zeichen.count() === 1, `in ihrer Gesprächsliste steht das @-Zeichen (${await zeichen.count()})`);
ok((await zeichen.first().getAttribute("aria-label") || "").includes("erwähnt"),
@@ -778,8 +836,16 @@ try {
der Antwort des Servers. */
const funny = await alsRolle("scout", "CODE-SCOU-0002", 1280, "chat.html");
await funny.seite.waitForTimeout(1200);
+ /* AUCH HIER INS RICHTIGE FACH. Im Fach „Personen" waere bei Funny
+ ohnehin nichts zu sehen -- die Gegenprobe waere dann gruen, ohne
+ die Gruppe je angesehen zu haben. Genau die Sorte Haken, die
+ nichts bestaetigt. */
+ await fachWaehlen(funny.seite, "gruppe");
const beiFunny = await funny.seite.locator(".chat-raum__erwaehnt").count();
+ const beiFunnyFach = await funny.seite.locator(".chat-art__at").count();
const zahlFunny = await funny.seite.locator(".chat-raum__zahl").count();
+ ok(beiFunnyFach === 0,
+ `Gegenprobe: bei Funny trägt auch kein Fach das @ (${beiFunnyFach})`);
ok(beiFunny === 0, `Gegenprobe: bei Funny leuchtet nichts (${beiFunny})`);
ok(zahlFunny >= 1,
` obwohl sie Ungelesenes hat (${zahlFunny} Gespräch(e) mit Zahl) — es liegt nicht daran`);
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index b365a0fc..707d05dc 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`. -->
-
-
+
+
-
+