Prüft, was die öffentlichen Seiten laden: Bilder, og:image/twitter:image, Favicon, Manifest. Eine fehlende Datei zeigt sich als leerer Kasten oder kaputte Teilen-Vorschau, oft unbemerkt. Ergebnis: 67 eigene Ressourcen, alle vorhanden, 0 fehlen. Co-Authored-By: Claude Opus 5 <[email protected]>
91 lines
3.8 KiB
JavaScript
91 lines
3.8 KiB
JavaScript
/* =====================================================================
|
|
Fehlt irgendein Bild oder eine eingebundene Datei?
|
|
|
|
Der Link-Test (pruef-links.mjs) prüft <a href>. Dieser hier prüft, was
|
|
die Seite selbst LÄDT: Bilder (<img>, CSS-Hintergründe über inline
|
|
style), das Social-Preview-Bild (og:image, twitter:image), Favicon und
|
|
das PWA-Manifest. Eine fehlende Datei zeigt sich als leerer Kasten,
|
|
kaputtes Vorschaubild beim Teilen oder fehlendem App-Symbol -- oft
|
|
unbemerkt, weil die Seite sonst funktioniert.
|
|
|
|
Gegen die echte Domain.
|
|
===================================================================== */
|
|
import { chromium } from "playwright";
|
|
|
|
const BASIS = "https://dogfather-universe.com";
|
|
const SEITEN = [
|
|
"/", "/dogfather.html", "/hasidog.html", "/manager.html", "/casper.html",
|
|
"/vanvan.html", "/tt-muddi.html", "/zeitreise.html", "/streamer.html",
|
|
"/community.html", "/stimmen.html", "/streamplan.html", "/team-modis.html",
|
|
"/team-scouts.html", "/creator.html", "/werte.html", "/bewerben.html",
|
|
"/kontakt.html", "/links.html", "/supporter.html", "/abonnieren.html",
|
|
"/medien-dogfather.html", "/medien-hasidog.html", "/medien-casper.html",
|
|
];
|
|
|
|
const browser = await chromium.launch();
|
|
|
|
const ziele = new Map(); // url -> { typ, seiten:Set }
|
|
const merke = (url, typ, seite) => {
|
|
if (!ziele.has(url)) ziele.set(url, { typ, seiten: new Set() });
|
|
ziele.get(url).seiten.add(seite);
|
|
};
|
|
|
|
for (const pfad of SEITEN) {
|
|
const seite = await browser.newPage();
|
|
try {
|
|
await seite.goto(BASIS + pfad, { waitUntil: "networkidle", timeout: 30000 });
|
|
const funde = await seite.evaluate(() => {
|
|
const raus = [];
|
|
/* Sichtbare Bilder (currentSrc löst srcset/lazy korrekt auf). */
|
|
for (const im of document.querySelectorAll("img")) {
|
|
const s = im.currentSrc || im.src;
|
|
if (s && !s.startsWith("data:")) raus.push({ url: s, typ: "img" });
|
|
}
|
|
/* Social-Preview + Favicon + Manifest aus dem <head>. */
|
|
const meta = (sel, attr) => document.querySelector(sel)?.getAttribute(attr);
|
|
const og = meta('meta[property="og:image"]', "content");
|
|
if (og) raus.push({ url: og, typ: "og:image" });
|
|
const tw = meta('meta[name="twitter:image"]', "content");
|
|
if (tw) raus.push({ url: tw, typ: "twitter:image" });
|
|
const fav = meta('link[rel="icon"]', "href");
|
|
if (fav) raus.push({ url: fav, typ: "favicon" });
|
|
const man = meta('link[rel="manifest"]', "href");
|
|
if (man) raus.push({ url: man, typ: "manifest" });
|
|
return raus;
|
|
});
|
|
for (const f of funde) {
|
|
let url;
|
|
try { url = new URL(f.url, BASIS + pfad); } catch { continue; }
|
|
if (url.origin !== BASIS) continue; // nur eigene Assets
|
|
merke(url.pathname, f.typ, pfad);
|
|
}
|
|
} catch (e) {
|
|
console.log(` (Seite ${pfad} nicht ladbar: ${String(e.message).slice(0, 40)})`);
|
|
}
|
|
await seite.close();
|
|
}
|
|
|
|
console.log(`\n${ziele.size} verschiedene eigene Ressourcen gesammelt. Jede einmal geprüft:\n`);
|
|
|
|
const pruef = await browser.newPage();
|
|
let ok = 0;
|
|
const fehlt = [];
|
|
for (const [url, info] of [...ziele].sort()) {
|
|
try {
|
|
const a = await pruef.goto(BASIS + url, { waitUntil: "commit", timeout: 20000 });
|
|
const code = a ? a.status() : 0;
|
|
if (code < 400) ok++;
|
|
else fehlt.push({ url, typ: info.typ, code, seiten: [...info.seiten] });
|
|
} catch (e) {
|
|
fehlt.push({ url, typ: info.typ, code: String(e.message).slice(0, 24), seiten: [...info.seiten] });
|
|
}
|
|
}
|
|
await browser.close();
|
|
|
|
console.log(`===== ${ok} Ressourcen vorhanden, ${fehlt.length} fehlen =====`);
|
|
if (fehlt.length) {
|
|
console.log("\nFehlende Dateien (Typ, Adresse -> Code, benutzt auf):");
|
|
for (const f of fehlt) console.log(` - [${f.typ}] ${f.url} -> ${f.code} (${f.seiten.slice(0, 3).join(", ")}${f.seiten.length > 3 ? " …" : ""})`);
|
|
}
|
|
process.exitCode = fehlt.length ? 1 : 0;
|