Hinweisliste "Was ist dran": Zeichen, Zahl und Farbe der Zielkachel
Die Zeilen waren die letzten schmucklosen Elemente der Startseite. Jetzt
traegt jede das Zeichen UND die Farbe der Kachel, zu der sie fuehrt --
Hinweis und Ziel gehoeren dadurch sichtbar zusammen, ohne dass die
Zuordnung ein zweites Mal irgendwo steht (sie kommt aus derselben
Tabelle wie die Zahl auf der Kachel). Die Anzahl steht vorn, getrennt vom
Satz und in gleicher Zeichenbreite; beim Ueberfliegen von sieben Zeilen
liest man genau sie zuerst. Ueberfaellig schlaegt Bereichsfarbe und
bleibt rot -- wenn etwas brennt, zaehlt zuerst, DASS es brennt.
Dabei gefunden und behoben: Die Farbtoene hingen an .kachel[data-ton=n].
Um sie fuer die Hinweiszeilen mitzunutzen, wurde .kachel entfernt --
damit gewann aber die Voreinstellung ".kachel { --ton: var(--akzent) }"
weiter unten in der Datei den Wettstreit der Regeln, und alle siebzehn
Kacheln waeren blau gewesen. Die Voreinstellung steht jetzt in :where()
und zaehlt dabei als nicht vorhanden. Die Browserpruefung hat das
gemeldet ("1 Farbe auf 17 Kacheln"), nicht das Auge.
"Nichts offen" ist kein gestrichelter Kasten mehr, sondern eine gute
Nachricht mit ruhigem Gruen und Haken. Weil er jetzt display:flex hat,
war er staerker als das hidden des Browsers und haette IMMER dagestanden
-- eigene Regel dafuer plus eine Pruefung, die beide Richtungen misst.
Neue Pruefungen (pruef-start-ansicht): Zeichen, vorangestellte Zahl,
keine doppelte Zahl im Satz, ganzer Satz fuer Vorleseprogramme, Farbe
gleich der Kachelfarbe an echten Bildpunkten, rot nur bei ueberfaellig.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -98,6 +98,19 @@ const lesen = (seite) => seite.evaluate(() => ({
|
||||
hinweise: [...document.querySelectorAll("#dran .dran__punkt")]
|
||||
.filter((z) => z.offsetParent !== null).length,
|
||||
hinweiseGesamt: document.querySelectorAll("#dran .dran__punkt").length,
|
||||
/* Jede Hinweiszeile traegt Zeichen und Farbe der Kachel, zu der sie
|
||||
fuehrt. Geprueft wird beides an den echten Bildpunkten, nicht an der
|
||||
Absicht im Quelltext. */
|
||||
dranZeilen: [...document.querySelectorAll("#dran .dran__punkt")].map((z) => ({
|
||||
ton: z.dataset.ton || null,
|
||||
stufe: z.dataset.stufe,
|
||||
pfade: z.querySelectorAll(".dran__svg path").length,
|
||||
strich: getComputedStyle(z.querySelector(".dran__svg")).stroke,
|
||||
zahl: z.querySelector(".dran__zahl")?.textContent || null,
|
||||
zahlFarbe: getComputedStyle(z.querySelector(".dran__zahl")).color,
|
||||
text: z.querySelector(".dran__text")?.textContent || "",
|
||||
label: z.querySelector(".dran__link")?.getAttribute("aria-label") || "",
|
||||
})),
|
||||
zeichenGroesse: Math.round(document.querySelector(".kachel__zeichen")?.getBoundingClientRect().width || 0),
|
||||
wasserzeichen: document.querySelectorAll(".kachel__wasserzeichen").length,
|
||||
wasserzeichenDeckung: getComputedStyle(document.querySelector(".kachel__wasserzeichen") || document.body).opacity,
|
||||
@@ -177,6 +190,44 @@ for (const [breite, wie] of [[1440, "Computer"], [390, "Handy"]]) {
|
||||
ok(r.abgeschnitten.length === 0,
|
||||
`kein Text wird abgeschnitten (${r.abgeschnitten.join(" | ") || "keiner"})`);
|
||||
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. */
|
||||
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(",")})`);
|
||||
/* 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");
|
||||
/* 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(",")})`);
|
||||
/* 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.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"})`);
|
||||
/* Ueberfaellig schlaegt Bereichsfarbe -- dort muss Rot stehen, sonst
|
||||
geht die Dringlichkeit in siebzehn Farben unter. */
|
||||
const warnZeilen = r.dranZeilen.filter((z) => z.stufe === "warnung");
|
||||
ok(warnZeilen.length > 0 && warnZeilen.every((z) => z.zahlFarbe === "rgb(255, 154, 162)"),
|
||||
`überfällige Zeilen sind rot (${warnZeilen.length} Stück, ${warnZeilen[0]?.zahlFarbe})`);
|
||||
/* Und die uebrigen eben NICHT rot -- sonst waere die Regel wertlos. */
|
||||
ok(r.dranZeilen.filter((z) => z.stufe !== "warnung")
|
||||
.every((z) => z.zahlFarbe !== "rgb(255, 154, 162)"),
|
||||
"und nur die");
|
||||
ok(r.zahlen === 6, `die Aufgabenzahlen stehen (${r.zahlen})`);
|
||||
ok(!r.zahlenLeer, "und nicht der Leer-Satz");
|
||||
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px, ${r.ueberstehend.join(", ")})`);
|
||||
@@ -217,6 +268,29 @@ console.log("\n=== Scout");
|
||||
await kontext.close();
|
||||
}
|
||||
|
||||
/* Der Satz "Nichts offen" ist ein Kasten mit display:flex geworden. Damit
|
||||
ist er staerker als das hidden des Browsers -- ohne eine eigene Regel
|
||||
stuende er IMMER da, auch wenn Arbeit offen ist. Genau das wird hier
|
||||
gemessen, in beide Richtungen. */
|
||||
console.log("\n=== Der Satz 'Nichts offen' erscheint nur, wenn nichts offen ist");
|
||||
{
|
||||
const kontext = await browser.newContext({ viewport: { width: 1440, height: 1200 } });
|
||||
const seite = await anmelden(kontext, "admin", "CODE-DOGI-0001");
|
||||
const r = await seite.evaluate(() => {
|
||||
const k = document.getElementById("zahlen-leer");
|
||||
const zu = getComputedStyle(k).display;
|
||||
k.hidden = false;
|
||||
const auf = getComputedStyle(k).display;
|
||||
const haken = k.querySelectorAll("svg path").length;
|
||||
k.hidden = true;
|
||||
return { zu, auf, haken };
|
||||
});
|
||||
ok(r.zu === "none", `versteckt heisst versteckt (${r.zu})`);
|
||||
ok(r.auf !== "none", `und sichtbar heisst sichtbar (${r.auf})`);
|
||||
ok(r.haken > 0, `der Haken ist da (${r.haken})`);
|
||||
await kontext.close();
|
||||
}
|
||||
|
||||
console.log("\n=== Weniger Bewegung: keine Animation");
|
||||
{
|
||||
const kontext = await browser.newContext({
|
||||
|
||||
Reference in New Issue
Block a user