← back to Dw Domain Fleet
scripts/boot-test.js
59 lines
#!/usr/bin/env node
/**
* boot-test.js — load every site config, build its niche pool, render its
* home + catalog + about pages in-process. Catches per-site render failures
* WITHOUT needing 65 ports. No HTTP — direct function calls.
*/
const fs = require('fs');
const path = require('path');
const catalog = require('../shared/catalog');
const { sortProducts } = require('../shared/sort');
const render = require('../shared/render');
const sites = fs.readdirSync(path.join(__dirname, '..', 'sites')).filter(f => f.endsWith('.json'));
let pass = 0, fail = 0;
const thin = [];
for (const f of sites) {
const cfg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'sites', f), 'utf8'));
try {
const niche = catalog.nicheSlice({
pos: cfg.niche.pos || [], neg: cfg.niche.neg || [], types: cfg.niche.types || [], limit: 6000
});
const pool = niche.length >= 24 ? niche
: catalog.nicheSlice({ pos: [], neg: cfg.niche.neg || [], types: ['Wallcovering'], limit: 6000 });
const heroImgs = sortProducts(pool, 'newest').slice(0, 14).map(p => p.image_url).filter(Boolean);
const featured = sortProducts(pool, 'newest').slice(0, 20);
const home = render.homePage(cfg, heroImgs, featured);
const cat = render.catalogPage(cfg, pool.slice(0, 60), '', 'newest', 1, 5, pool.length);
const about = render.aboutPage(cfg);
// sanity assertions
if (!/<!doctype html>/i.test(home)) throw new Error('home: no doctype');
// Banned-word check: "wallpaper" must NOT appear in EDITORIAL copy
// (tagline / about / meta-desc / hero-sub). It IS allowed in the brand
// wordmark + <title> when the registered domain stem itself contains it
// (e.g. wallpaperny.com) — the domain is the SEO asset, per Steve's rule.
for (const [k, v] of Object.entries({ tagline: cfg.tagline, heroSub: cfg.heroSub,
metaDesc: cfg.metaDesc, aboutCopy: cfg.aboutCopy })) {
if (/wallpaper/i.test(render.clean(String(v)))) {
throw new Error(`banned word "wallpaper" in editorial field ${k}`);
}
}
if (!/id="sortSel"/.test(cat)) throw new Error('catalog: no sort select');
if (!/id="densSel"/.test(cat)) throw new Error('catalog: no density slider');
if (!/gucci-menu/.test(home)) throw new Error('home: no gucci menu');
pass++;
if (niche.length < 60) thin.push(`${cfg.slug}: niche=${niche.length} (using ${pool.length})`);
process.stdout.write(`. `);
} catch (e) {
fail++;
console.log(`\nFAIL ${cfg.slug}: ${e.message}`);
}
}
console.log(`\n\n${pass} pass · ${fail} fail · ${sites.length} total`);
if (thin.length) {
console.log(`\nThin niches (fell back to broad wallcovering pool):`);
thin.forEach(t => console.log(' ' + t));
}
process.exit(fail ? 1 : 0);