Files
dogfather-universe/pruef-blickfang.mjs
T
DogFatherGitandClaude Opus 5 99b5dd4eb2 CRYONOVA Schritt 3: Feldfokus, Blickfaenge, Testkorrekturen
Der Feldfokus zeigt jetzt den Ion-Rand und den weichen Schein, den das
Design-System auf Seite 15 verlangt. Er fehlte, weil der allgemeine
Tastaturring seinen dunklen Innenring darueberlegte: Dessen Selektor hat
Spezifitaet 0,3,0, die Feldregel nur 0,2,1 -- und Spezifitaet schlaegt
Reihenfolge, egal wie weit unten die Regel steht. Eingabefelder sind
jetzt vom Innenring ausgenommen; sie brauchen ihn nicht, weil sie selbst
eine dunkle Flaeche sind. Der Aqua-Umriss bleibt fuer alle erhalten.

Die zwei Blickfang-Motive stehen jetzt auch wirklich auf einer Seite:
das Wappen auf "Ueber mich", direkt nach dem Absatz ueber die Herkunft
des Namens, der Monolith auf "Portfolio" zwischen Einleitung und den
echten Projekten. Beide als Zierbild ausgezeichnet -- ihre Aussage steht
schon im Text daneben. Auf dem Handy laedt automatisch die kleine
Fassung.

Vier Fehler steckten in der Pruefung selbst, nicht im Stilblatt:
- Sie griff das erste "input" der Anfrageseite. Das sind aber sechs
  optisch versteckte Auswahl-Radios, kein Textfeld.
- Sie mass ohne Fensterfokus. Ein Browser wendet :focus nur an, wenn das
  Fenster selbst den Fokus hat -- das DOM meldet trotzdem brav
  matches(":focus") === true, die Farbe bleibt die alte.
- Sie mass mitten im Uebergang, bevor die Animation stand.
- Und sie zaehlte Schattenebenen an "),", einem Muster, das in keinem
  Schattenwert je vorkommt. Geprueft wird jetzt die Anforderung selbst:
  Ion-Farbe und ein Weichzeichner ueber 0.

Geprueft: 334 Pruefungen gruen (CRYONOVA 53, Blickfang 13, Abmelden 16,
Angebot 54, Abbruch 42, System 5, Automatik 55, Angebote 56, Kette 40).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-24 23:03:27 +02:00

77 lines
2.9 KiB
JavaScript

/* Prueft, dass die beiden Blickfang-Motive wirklich ankommen: richtige
Datei je Geraet, sichtbare Groesse, und keine 404 auf dem Weg. */
import { chromium } from "playwright";
import http from "http";
import fs from "fs";
import path from "path";
const TYP = {
".html": "text/html", ".css": "text/css", ".js": "text/javascript",
".png": "image/png", ".svg": "image/svg+xml", ".webp": "image/webp",
".json": "application/json", ".ico": "image/x-icon", ".jpg": "image/jpeg",
};
const fehlt = [];
const srv = http.createServer((q, r) => {
const u = decodeURIComponent(q.url.split("?")[0]);
const p = path.join(process.cwd(), u);
if (fs.existsSync(p) && !p.endsWith("/")) {
r.writeHead(200, { "content-type": TYP[path.extname(p)] || "text/plain" });
return r.end(fs.readFileSync(p));
}
fehlt.push(u);
r.writeHead(404);
r.end("");
});
let ok = 0, fehl = 0;
const pruefe = (name, gut, info) => {
if (gut) { ok++; console.log(" ok " + name + (info ? " -> " + info : "")); }
else { fehl++; console.log(" FEHL " + name + (info ? " -> " + info : "")); }
};
srv.listen(4402, async () => {
const browser = await chromium.launch();
for (const [seite, kl] of [["ueber", "wappen"], ["portfolio", "monolith"]]) {
for (const [gr, vp] of [["pc", { width: 1440, height: 950 }],
["handy", { width: 390, height: 844 }]]) {
const s = await browser.newPage({ viewport: vp });
await s.goto(`http://127.0.0.1:4402/webdesign/${seite}.html`);
await s.waitForTimeout(1400);
const el = s.locator(".wd-blickfang--" + kl);
const r = await el.evaluate((e) => {
const c = getComputedStyle(e);
const b = e.getBoundingClientRect();
const treffer = c.backgroundImage.match(/img\/([a-z0-9-]+\.webp)/i);
return {
datei: treffer ? treffer[1] : "(keins)",
h: Math.round(b.height), w: Math.round(b.width),
versteckt: e.getAttribute("aria-hidden"),
};
});
/* Auf dem Handy MUSS die kleine Fassung kommen -- sonst laedt ein
Telefon ueber Mobilfunk die volle Datei fuer nichts. */
const richtig = gr === "handy" ? r.datei.includes("-klein") : !r.datei.includes("-klein");
pruefe(`${seite}/${gr}: richtige Bilddatei`, richtig, r.datei);
pruefe(`${seite}/${gr}: sichtbar gross`, r.h > 80 && r.w > 200, `${r.w}x${r.h}`);
pruefe(`${seite}/${gr}: als Zierbild ausgezeichnet`, r.versteckt === "true", r.versteckt);
await el.scrollIntoViewIfNeeded();
await s.waitForTimeout(700);
await s.screenshot({ path: `blickfang-${seite}-${gr}.png` });
await s.close();
}
}
const verpasst = fehlt.filter((f) => /\.(webp|png|css|js|svg)$/.test(f));
pruefe("keine fehlenden Dateien", verpasst.length === 0, verpasst.join(", ") || "keine");
console.log(`\n===== ${ok} bestanden, ${fehl} fehlgeschlagen =====`);
await browser.close();
srv.close();
process.exit(fehl ? 1 : 0);
});