83 lines
3.8 KiB
JavaScript
83 lines
3.8 KiB
JavaScript
|
|
// Electron render harness — loads a bns:// name through the REAL serveBns handler
|
||
|
|
// (imported from main.js), lets its JS execute, then reports what actually
|
||
|
|
// rendered: title, image load status, stylesheet/script counts, visible text
|
||
|
|
// length, and any failed resource loads. Also writes render.html + render.png.
|
||
|
|
// This is the full-fidelity version of manual test #2/#3 — it runs the same
|
||
|
|
// resolver + gateway path the shipped app uses.
|
||
|
|
//
|
||
|
|
// Usage: npx electron dev/selftest.js <name> e.g. hello.bch / coinspectrum.deviant.bch
|
||
|
|
process.env.THESEUS_NO_AUTOSTART = "1";
|
||
|
|
const { app, BrowserWindow, protocol } = require("electron");
|
||
|
|
const { serveBns, nativeTld, registryOf } = require("../main.js");
|
||
|
|
const fs = require("fs");
|
||
|
|
const path = require("path");
|
||
|
|
|
||
|
|
app.disableHardwareAcceleration();
|
||
|
|
app.commandLine.appendSwitch("disable-gpu");
|
||
|
|
app.commandLine.appendSwitch("no-sandbox");
|
||
|
|
|
||
|
|
const name = (process.argv[2] || "coinspectrum.deviant.bch").toLowerCase();
|
||
|
|
const settleMs = Number(process.env.THESEUS_SETTLE || 5000);
|
||
|
|
const outDir = path.join(__dirname, "..", "dev-out");
|
||
|
|
|
||
|
|
// hard watchdog so the harness can never hang a CI/agent run
|
||
|
|
const watchdog = setTimeout(() => { console.log("WATCHDOG: timed out"); try { app.exit(3); } catch {} }, 45000);
|
||
|
|
|
||
|
|
app.whenReady().then(async () => {
|
||
|
|
protocol.handle("bns", serveBns);
|
||
|
|
const win = new BrowserWindow({ width: 1200, height: 900, show: false, webPreferences: { offscreen: true } });
|
||
|
|
const wc = win.webContents;
|
||
|
|
const failed = [];
|
||
|
|
wc.on("did-fail-load", (_e, code, desc, url, isMainFrame) => { if (code !== -3) failed.push({ code, desc, url, isMainFrame }); });
|
||
|
|
|
||
|
|
const tld = nativeTld(name);
|
||
|
|
const report = { name, url: `bns://${name}/`, badge: tld ? `${registryOf(tld)} · .${tld}` : null };
|
||
|
|
try {
|
||
|
|
await wc.loadURL(`bns://${name}/`);
|
||
|
|
} catch (e) { report.loadError = e.message; }
|
||
|
|
|
||
|
|
await new Promise((r) => setTimeout(r, settleMs)); // let JS build the DOM + fetch data
|
||
|
|
|
||
|
|
try {
|
||
|
|
Object.assign(report, await wc.executeJavaScript(`(() => {
|
||
|
|
const imgs = [...document.images].map(i => {
|
||
|
|
const src = i.currentSrc || i.src || '';
|
||
|
|
return { src: src.slice(0, 90), ok: i.complete && i.naturalWidth > 0, local: src.startsWith('bns:') };
|
||
|
|
});
|
||
|
|
const brokenLocal = imgs.filter(i => !i.ok && i.local);
|
||
|
|
return {
|
||
|
|
title: document.title,
|
||
|
|
stylesheets: document.styleSheets.length,
|
||
|
|
scripts: document.scripts.length,
|
||
|
|
imgTotal: imgs.length,
|
||
|
|
imgBrokenLocal: brokenLocal.length, // served by us (bns://) — a real failure
|
||
|
|
imgBrokenExternal: imgs.filter(i => !i.ok && !i.local).length, // 3rd-party CDN — informational
|
||
|
|
brokenLocalImgs: brokenLocal.map(i => i.src),
|
||
|
|
textLen: (document.body ? document.body.innerText : '').trim().length,
|
||
|
|
h1: (document.querySelector('h1,h2') || {}).innerText || null,
|
||
|
|
};
|
||
|
|
})()`));
|
||
|
|
} catch (e) { report.evalError = e.message; }
|
||
|
|
|
||
|
|
report.failedLoads = failed;
|
||
|
|
|
||
|
|
fs.mkdirSync(outDir, { recursive: true });
|
||
|
|
try {
|
||
|
|
const html = await wc.executeJavaScript("document.documentElement.outerHTML");
|
||
|
|
fs.writeFileSync(path.join(outDir, "render.html"), html);
|
||
|
|
} catch {}
|
||
|
|
try {
|
||
|
|
const img = await wc.capturePage();
|
||
|
|
const png = img.toPNG();
|
||
|
|
if (png && png.length > 0) { fs.writeFileSync(path.join(outDir, "render.png"), png); report.screenshot = `dev-out/render.png (${png.length} bytes)`; }
|
||
|
|
else report.screenshot = "empty (offscreen not compositing)";
|
||
|
|
} catch (e) { report.screenshot = "error: " + e.message; }
|
||
|
|
|
||
|
|
console.log("\n===== SELFTEST REPORT =====");
|
||
|
|
console.log(JSON.stringify(report, null, 2));
|
||
|
|
// Verdict ignores external CDN images — only our own (bns://) assets + page loads count.
|
||
|
|
report.verdict = (!report.loadError && !report.imgBrokenLocal && report.textLen > 0) ? "PASS" : "FAIL";
|
||
|
|
clearTimeout(watchdog);
|
||
|
|
app.exit(report.verdict === "PASS" ? 0 : 2);
|
||
|
|
});
|