diff --git a/server/mess-support-runde.mjs b/server/mess-support-runde.mjs index 220d62a0..dbedf9b2 100644 --- a/server/mess-support-runde.mjs +++ b/server/mess-support-runde.mjs @@ -118,6 +118,41 @@ const anfrage = (pfad, art, koerper, keks) => new Promise((fertig, schief) => { if (koerper) a.write(JSON.stringify(koerper)); a.end(); }); +/** Eine Rueckmeldung des Melders -- UEBER DEN KOPF, nicht als JSON. + * + * ==== DIESE MESSUNG HAT ZWEI TAGE LANG NICHTS GEMESSEN =========== + * + * Am 02.10.2026 ist `/rueckmeldung` auf den Weg umgestellt worden, + * den auch das Melden nimmt: Urteil und Text reisen im KOPF + * (`x-geht`, `x-text`, prozentkodiert), der Rumpf ist fuer die + * Bilder da. Diese Datei schickte weiter JSON -- der Server fand + * also kein Urteil und keinen Text und antwortete mit 400. + * + * GEMERKT HAT ES NIEMAND, weil die Messung keine Rueckgabewerte + * prueft: Sie macht Bilder. Auf dem Bild stand danach eine Runde + * statt vier, und das sieht aus wie ein Ergebnis. Aufgefallen ist + * es erst, als die Bilder vier Rundenfarben zeigen sollten. + * + * Eine Messung, die nach einem Umbau stillschweigend etwas anderes + * misst, ist schlimmer als keine -- man glaubt ihr. */ +const rueckmelden = (id, geht, satz, keks) => new Promise((fertig, schief) => { + const a = httpAnfrage({ + host: "127.0.0.1", port: PORT, path: `/workspace/api/support/${id}/rueckmeldung`, + method: "POST", + headers: { + Host: CREW, Cookie: keks, + "Content-Type": "application/octet-stream", + "x-geht": geht ? "ja" : "nein", + "x-text": encodeURIComponent(satz || ""), + }, + }, (r) => { + let t = ""; r.on("data", (x) => { t += x; }); + r.on("end", () => fertig({ code: r.statusCode, text: t })); + }); + a.on("error", schief); + a.end(); +}); + const anmelden = async (rolle, code) => { const an = await anfrage("/workspace/api/anmelden", "POST", { rolle, code }); if (an.code !== 200) { console.log(`ABBRUCH: Anmeldung ${rolle} ${an.code}`); process.exit(2); } @@ -200,12 +235,34 @@ try { await blicken("melder-handy", kModi, 412, 915); /* --- Runde 2: „noch nicht", dann behoben, dann bestaetigt --------- */ - await anfrage(`/workspace/api/support/${dran}/rueckmeldung`, "POST", - { geht: false, text: "Der Knopf ja – aber jetzt springt die Seite nach oben." }, kModi); + const r2 = await rueckmelden(dran, false, + "Der Knopf ja – aber jetzt springt die Seite nach oben.", kModi); + if (r2.code !== 200) console.log(` !! Rueckmeldung ging nicht: ${r2.code} ${r2.text}`); await anfrage(`/workspace/api/support/${dran}`, "PATCH", { stand: "erledigt", antwort: "Das Springen kam vom Nachladen. Ist raus." }, kHand); await blicken("melder-runde2", kModi, 1280, 1000); + /* ==== VIER RUNDEN -- WEIL ES VIER FARBEN SIND (03.10.2026) ======= + + Filipe: „jede runde soll auch immer eine spezielle farbe haben … + damit man einen viel besseren und krasseren ueberblick hat." + + Mit zwei Runden sieht man zwei Toene und kann nicht sagen, ob es + eine Reihe ist. Vier ist die Zahl, nach der sich die Farben + wiederholen (siehe `rundenTon` in support.js) -- also genau die + Zahl, bei der man die Regel sieht statt sie zu glauben. */ + for (const [wort, satz] of [ + ["Jetzt laedt die Liste nicht mehr nach.", "Und jetzt ist der Knopf doppelt."], + ["Der doppelte Knopf ist raus.", "Jetzt stimmt die Reihenfolge nicht."], + ]) { + const rr = await rueckmelden(dran, false, satz, kModi); + if (rr.code !== 200) console.log(` !! Rueckmeldung ging nicht: ${rr.code} ${rr.text}`); + await anfrage(`/workspace/api/support/${dran}`, "PATCH", + { stand: "erledigt", antwort: wort }, kHand); + } + await blicken("melder-vierrunden", kModi, 1280, 1100); + await blicken("melder-vierrunden-handy", kModi, 412, 915); + console.log(`\n(Die offene Meldung #${offen} bleibt unangetastet stehen –` + " so sieht man beide Sorten nebeneinander.)"); } finally { diff --git a/server/pruef-support-bilder.mjs b/server/pruef-support-bilder.mjs index 2e67a482..b44ae93b 100644 --- a/server/pruef-support-bilder.mjs +++ b/server/pruef-support-bilder.mjs @@ -489,6 +489,146 @@ melde("\n=== Die zweite Spalte nur mit eigenem Bild ==="); await kontext.close(); } +/* ===================================================================== + 6. DER VERLAUF: EINE FARBE JE RUNDE (03.10.2026) + ===================================================================== + + Filipe: „ich will diese komplette seite vom support viel + uebersichtlicher, profissioneller, jede runde soll auch immer eine + spezielle farbe haben und anders aufgestellt aufgeteilt sein damit + man einen viel besseren und krasseren ueberblick hat." + + WARUM DAS GEPRUEFT WERDEN MUSS und nicht nur auf einem Bild steht: + Die Farbe kommt aus einer Rechnung (`rundenTon` in support.js) und + wird im CSS zu `hsl()`. Zwischen diesen beiden Stellen kann sie + verlorengehen, ohne dass etwas abstuerzt -- dann sind alle Runden + gleich grau, und auf dem Bildschirm sieht das aus wie Absicht. + + GEMESSEN WIRD DIE ANGEZEIGTE FARBE, nicht die Zahl: `--ton` kann + gesetzt sein und das CSS sie trotzdem nicht benutzen. + ===================================================================== */ +melde("\n=== Eine Farbe je Runde ==="); +{ + /* Eine Meldung mit VIER Runden -- so viele, wie es Toene gibt. + Mit zwei saehe man zwei Farben und wueste nicht, ob es eine + Reihe ist. */ + /* UEBER `fetch` MIT KEKS -- diese Datei hat keinen `hol`-Helfer wie + pruef-support.mjs. Mein erster Anlauf rief ihn trotzdem auf und + stuerzte ab; die Pruefung hat es in derselben Minute gesagt. */ + const ruf = (pfad, keks, o = {}) => fetch(BASIS + pfad, + { ...o, headers: { cookie: keks, ...(o.headers || {}) } }); + const neu = await ruf("/workspace/api/support", keksModi, { + method: "POST", headers: { "Content-Type": "text/plain", + "x-text": encodeURIComponent("Probe fuer die Rundenfarben.") }, + }); + const vId = (await neu.json())?.meldung?.id; + for (let i = 0; i < 4; i++) { + await ruf(`/workspace/api/support/${vId}`, keksHand, { + method: "PATCH", headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ stand: "erledigt", antwort: `Versuch ${i + 1}.` }), + }); + await ruf(`/workspace/api/support/${vId}/rueckmeldung`, keksModi, { + method: "POST", + headers: { "x-geht": "nein", + "x-text": encodeURIComponent(`Ging noch nicht, Versuch ${i + 1}.`) }, + }); + } + /* Noch einmal zurueckgeben, damit die letzte Runde eine Antwort + hat und der Melder wieder dran ist. */ + await ruf(`/workspace/api/support/${vId}`, keksHand, { + method: "PATCH", headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ stand: "erledigt", antwort: "Jetzt aber." }), + }); + + const { kontext, seite } = await neueSeite(1280, keksModi); + const karte = `#meldung-${vId}`; + await seite.locator(karte).waitFor({ timeout: 8000 }); + + const bild = await seite.evaluate((wahl) => { + const k = document.querySelector(wahl); + const punkte = [...k.querySelectorAll(".s-rundenleiste__punkt")]; + const offen = [...k.querySelectorAll(".s-runde")]; + const farbe = (e) => getComputedStyle(e).backgroundColor; + return { + punkte: punkte.length, + punktFarben: punkte.map((p) => farbe(p)), + nummern: punkte.map((p) => p.textContent.trim()), + /* Die Farbe der Rundennummer -- sie muss sich mit der Runde + aendern, sonst ist die Achse farbig und die Schrift nicht. */ + nrFarben: offen.map((r) => + getComputedStyle(r.querySelector(".s-runde__nr")).color), + offene: offen.length, + mehr: (k.querySelector(".s-verlauf__mehr")?.innerText || "") + .replace(/\s+/g, " ").trim(), + /* Zwei Sprechrichtungen: Wer geantwortet hat und was daraus + wurde, muessen verschieden aussehen. */ + schilder: [...k.querySelectorAll(".s-schritt__schild")] + .map((x) => x.textContent.trim()), + hoch: Math.round(k.getBoundingClientRect().height), + }; + }, karte); + + ok(bild.punkte === 5, `die Leiste zeigt jede Runde (${bild.punkte} Punkte)`); + ok(bild.nummern.join(",") === "1,2,3,4,5", + `mit ihrer Nummer (${bild.nummern.join(", ")})`); + /* DER EIGENTLICHE PUNKT: vier verschiedene Farben. Die fuenfte + wiederholt die erste -- so ist die Formel gebaut, und das steht + hier als Aussage, damit es niemand fuer einen Fehler haelt. */ + const verschieden = new Set(bild.punktFarben.slice(0, 4)).size; + ok(verschieden === 4, + `die ersten vier Runden haben vier verschiedene Farben (${verschieden})`); + ok(bild.punktFarben[4] === bild.punktFarben[0], + "und die fuenfte faengt die Reihe wieder von vorn an — so ist die Formel"); + /* GEGENPROBE: Waere `--ton` nicht angekommen, waeren ALLE gleich. + Diese Zeile unterscheidet „vier Farben" von „viermal dieselbe". */ + ok(new Set(bild.punktFarben).size > 1, + `Gegenprobe: sie sind nicht alle gleich (${new Set(bild.punktFarben).size} Farben)`); + + ok(new Set(bild.nrFarben).size === bild.offene, + `auch die Rundennummern tragen ihre Farbe (${new Set(bild.nrFarben).size} ` + + `von ${bild.offene})`); + + ok(bild.offene === 2, `offen stehen die letzten zwei Runden (${bild.offene})`); + ok(/3 frühere Runden/.test(bild.mehr), + `und die aelteren sind einen Griff entfernt („${bild.mehr}")`); + + ok(bild.schilder.includes("Geantwortet") + && bild.schilder.some((t) => /Ging noch nicht|Wartet/.test(t)), + `jede Runde zeigt beide Seiten (${[...new Set(bild.schilder)].join(" / ")})`); + + /* AUFKLAPPEN UND WIEDER ZU. */ + await seite.locator(`${karte} .s-verlauf__mehr`).click(); + await seite.waitForTimeout(400); + const ganz = await seite.evaluate((wahl) => ({ + offene: document.querySelectorAll(`${wahl} .s-runde`).length, + mehr: (document.querySelector(`${wahl} .s-verlauf__mehr`)?.innerText || "") + .replace(/\s+/g, " ").trim(), + }), karte); + ok(ganz.offene === 5, `aufgeklappt stehen alle da (${ganz.offene})`); + await seite.locator(`${karte} .s-verlauf__mehr`).click(); + await seite.waitForTimeout(400); + ok(await seite.locator(`${karte} .s-runde`).count() === 2, + "und wieder zu — der Knopf geht in beide Richtungen"); + + /* UND NICHTS RAGT HERAUS, auch nicht auf dem Handy. */ + await kontext.close(); + const h = await neueSeite(390, keksModi); + await h.seite.locator(karte).waitFor({ timeout: 8000 }); + const ueber = await h.seite.evaluate(() => + document.documentElement.scrollWidth - document.documentElement.clientWidth); + ok(ueber <= 0, `auf 390 px ragt nichts heraus (${ueber} px)`); + /* GEGENPROBE ZUR LEISTE: Bei EINER Runde gibt es sie nicht -- ein + Punkt neben keinem Punkt sagt nichts. */ + const einzeln = await h.seite.evaluate(() => { + const k = [...document.querySelectorAll(".s-karte")] + .find((x) => x.querySelectorAll(".s-runde").length === 1); + return k ? k.querySelectorAll(".s-rundenleiste").length : -1; + }); + ok(einzeln === 0 || einzeln === -1, + `bei einer einzigen Runde gibt es keine Leiste (${einzeln})`); + await h.kontext.close(); +} + 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 aad7469b..265cf93e 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`. --> - - + + - +