diff --git a/server/pruef-chat-optik.mjs b/server/pruef-chat-optik.mjs index 9f4f2e40..5baaf6a7 100644 --- a/server/pruef-chat-optik.mjs +++ b/server/pruef-chat-optik.mjs @@ -957,6 +957,114 @@ melde("\n=== Die Schreibzeile auf dem Handy ==="); } finally { await laptop.ctx.close(); } } +/* ======================================================================= + WER HAT REAGIERT? -- AUCH OHNE MAUS (02.10.2026) + + VanVan: „Wenn man auf dem Handy auf die Reaktionen unter einer + Nachricht geht, dann sieht man nicht wer darauf reagiert hat. Auf + dem PC funktioniert es." + + Die Namen standen im `title` der Kachel. Ein `title` erscheint beim + UEBERFAHREN MIT DER MAUS -- auf einem Finger gibt es das nicht, und + das Antippen schaltet stattdessen die eigene Reaktion um. Die + Auskunft war nicht versteckt, sondern an ein Geraet gebunden. + + GEPRUEFT WIRD AUF BEIDEN GERAETEN, sonst beweist es nichts: Am + Handy MUSS die Namenszeile da sein, am Rechner MUSS sie fehlen und + der `title` die Namen tragen. Ohne die zweite Haelfte waere eine + Regel, die immer gilt, genauso gruen -- und wuerde am Rechner unter + jeder zweiten Nachricht eine Zeile anhaengen, die niemand bestellt + hat. + ======================================================================= */ +melde("\n=== Wer hat reagiert? ==="); +{ + /* DogFather schreibt, Patrick reagiert -- dann steht ein FREMDER + Name da. Mit der eigenen Reaktion waere „Du" zu sehen, und die + Pruefung haette den Fall nicht gemessen, um den es geht. */ + const dogi = await alsRolle("admin", "CODE-DOGI-0001", "chat.html", 1280); + let nid = null; + let raumId = null; + try { + const raum = await dogi.seite.evaluate(async (id) => { + const a = await fetch("/workspace/api/chat/direkt", { + method: "POST", credentials: "same-origin", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ mit: id }), + }); + return (await a.json())?.raum_id; + }, idPat); + raumId = raum; + nid = await dogi.seite.evaluate(async (r) => { + const a = await fetch(`/workspace/api/chat/raeume/${r}/nachrichten`, { + method: "POST", credentials: "same-origin", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text: "Woran reagiert ihr?" }), + }); + return (await a.json())?.nachricht?.id; + }, raum); + ok(Number.isInteger(nid), `eine Nachricht zum Reagieren da (#${nid})`); + + const pat = await alsRolle("scout", "CODE-SCOU-0001", "chat.html", 1280); + try { + const code = await pat.seite.evaluate(async (n) => { + const a = await fetch(`/workspace/api/chat/nachrichten/${n}/reaktion`, { + method: "PUT", credentials: "same-origin", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ zeichen: "👍" }), + }); + return a.status; + }, nid); + ok(code === 200 || code === 201, `Patrick reagiert mit 👍 (HTTP ${code})`); + } finally { await pat.ctx.close(); } + } finally { await dogi.ctx.close(); } + + /** Was auf einem Geraet wirklich zu sehen ist. */ + const ansehen = async (breite) => { + /* MIT DEM RAUM IN DER ADRESSE. Ohne ihn steht die Seite auf der + Gespraechsliste, es ist keine Nachricht offen -- und die + Pruefung wartet zehn Sekunden auf eine Kachel, die es dort + gar nicht geben kann. */ + const wer = await alsRolle("admin", "CODE-DOGI-0001", + `chat.html?raum=${raumId}`, breite); + try { + await wer.seite.waitForSelector(".reaktionen__stueck", { timeout: 10000 }); + await wer.seite.waitForTimeout(500); + return await wer.seite.evaluate(() => { + const z = document.querySelector(".reaktionen__wer"); + const k = document.querySelector(".reaktionen__stueck"); + const r = z ? z.getBoundingClientRect() : null; + return { + zeileDa: !!z, + sichtbar: !!z && getComputedStyle(z).display !== "none" + && !!r && r.height > 0, + text: (z?.textContent || "").trim(), + titel: k?.getAttribute("title") || "", + vorlesewort: k?.getAttribute("aria-label") || "", + fuerVorleser: z?.getAttribute("aria-hidden") || "", + }; + }); + } finally { await wer.ctx.close(); } + }; + + const handy = await ansehen(390); + ok(handy.sichtbar, `auf dem Handy steht die Zeile da (${handy.sichtbar})`); + ok(/Patrick/.test(handy.text), + ` und sie nennt den Namen: „${handy.text}"`); + ok(/👍/.test(handy.text), " mit dem Zeichen davor, damit klar ist, worauf"); + /* Jede Kachel traegt ihre Namen schon im `aria-label`. Ohne + `aria-hidden` hoerte ein Vorleseprogramm alles doppelt. */ + ok(handy.fuerVorleser === "true", + " und ein Vorleseprogramm hoert sie nicht doppelt (aria-hidden)"); + + const rechner = await ansehen(1280); + ok(rechner.zeileDa && !rechner.sichtbar, + "am Rechner bleibt sie weg — dort funktioniert das Überfahren"); + ok(/Patrick/.test(rechner.titel), + ` und die Namen stehen wie bisher im Titel („${rechner.titel.slice(0, 40)}…")`); + ok(/Patrick/.test(rechner.vorlesewort), + " das Vorlesewort der Kachel nennt sie auf beiden Geräten"); +} + await browser.close(); try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ } diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index 44db2211..b7ecf886 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`. --> - - + + - +