Files
sow-nodebb-theme/prototype/shots.js
T
archvillainetteandClaude Opus 5 ea36116e62 prototype(#53): palette candidates as runtime token swaps
Throwaway. Tokenises the theme's literal colours so candidate palettes can be
swapped in the browser, adds three candidates (Plum Noir one-metal, two-metal
pewter, two-metal plus a champagne inset), a WCAG checker, a seeder and the
screenshots they are judged on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 16:31:41 +02:00

53 lines
2.0 KiB
JavaScript

// Throwaway screenshotter for #53. Logs in, then for each candidate injects the
// candidate's :root override at runtime and shoots the pages that matter.
// PLAYWRIGHT_BROWSERS_PATH=... nix shell nixpkgs#playwright-test -c node prototype/shots.js
const fs = require('fs');
const path = require('path');
const { chromium } = require('playwright');
const BASE = process.env.BASE || 'http://localhost:4567';
const OUT = process.env.OUT || path.join(__dirname, 'shots');
const read = (f) => fs.readFileSync(path.join(__dirname, f), 'utf8');
const base = read('_base-plumnoir.css');
const CANDIDATES = {
baseline: '',
a: base + read('candidate-a.css'),
b: base + read('candidate-b.css'),
c: base + read('candidate-b.css') + read('candidate-c.css'),
};
const PAGES = [
['topic', '/topic/2'],
['categories', '/categories'],
['cards', process.env.CARDS_URL || '/recent'],
];
(async () => {
fs.mkdirSync(OUT, { recursive: true });
const browser = await chromium.launch();
const ctx = await browser.newContext({ viewport: { width: 1600, height: 1000 }, deviceScaleFactor: 2 });
const page = await ctx.newPage();
await page.goto(BASE + '/login');
await page.fill('#username', 'admin');
await page.fill('#password', 'Admin12345!');
await page.click('#login');
await page.waitForLoadState('networkidle');
for (const [name, css] of Object.entries(CANDIDATES)) {
for (const [pname, url] of PAGES) {
await page.goto(BASE + url, { waitUntil: 'networkidle' });
if (css) await page.addStyleTag({ content: css });
await page.waitForTimeout(400);
const file = path.join(OUT, `${pname}-${name}.png`);
await page.screenshot({ path: file, fullPage: true });
// close crop: the same region every time, so candidates can be compared at real size
const crop = path.join(OUT, `${pname}-${name}-crop.png`);
await page.screenshot({ path: crop, clip: { x: 120, y: 60, width: 1060, height: 620 } });
console.log(file);
}
}
await browser.close();
})();