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]>
77 lines
2.9 KiB
JavaScript
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);
|
|
});
|