Oregami
Repositories/oxedyne/daimond

oxedyne/daimond/dev/shot_credits_block.mjs

3.1 KiB, 1 run

created by r2519314175:149, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1// shot_credits_block.mjs — the provider credit block, in every theme and both skins.
2//
3// The block (`.models-credit` and its line, form and input) is rendered by models.js inside each
4// expanded provider and had no CSS rules at all: an unstyled div, an unstyled full-width text
5// input at browser defaults, sitting inside a panel built entirely from tokens. It is a thing to
6// LOOK at rather than assert on, so this exists to be looked at.
7//
8// Every combination is shot because the block is styled from tokens alone -- no overrides -- and
9// the claim that makes is that it follows the theme and the skin for free. A picture per
10// combination is the only way to see whether that held.
11import { open } from './harness.mjs';
12import path from 'node:path';
13import fs from 'node:fs';
14
15const OUT = path.join(process.cwd(), 'dev', 'shots');
16fs.mkdirSync(OUT, { recursive: true });
17
18const s = await open({ name: 'creditshot' });
19const p = s.page;
20await p.waitForTimeout(1200);
21
22// Open the Models panel from the rail row that counts them, and expand the one provider there is.
23await p.evaluate(() => { document.getElementById('astat-model').click(); });
24await p.waitForTimeout(800);
25await p.evaluate(() => {
26 const h = document.querySelector('.models-prov-head');
27 if (h) h.click();
28});
29await p.waitForTimeout(600);
30
31// A manual base, so the block is in its wordiest state: the sentence that names the base, the
32// estimated spend since and the date it was stated, plus the field and the update button.
33await p.evaluate(() => {
34 const inp = document.querySelector('.models-credit-input');
35 if (!inp) return;
36 inp.value = '20';
37 const btn = inp.parentElement.querySelector('button');
38 if (btn) btn.click();
39});
40await p.waitForTimeout(700);
41
42const present = await p.evaluate(() => {
43 const w = document.querySelector('.models-credit');
44 if (!w) return null;
45 const cs = getComputedStyle(w);
46 const inp = document.querySelector('.models-credit-input');
47 return {
48 line: (w.querySelector('.models-credit-line') || {}).textContent || '',
49 border: cs.borderTopWidth + ' ' + cs.borderTopColor,
50 bg: cs.backgroundColor,
51 inputW: inp ? Math.round(inp.getBoundingClientRect().width) : 0,
52 inputFs: inp ? getComputedStyle(inp).fontSize : '',
53 };
54});
55console.log('credit block:', JSON.stringify(present));
56
57for (const skin of ['sharp', 'warm']) {
58 await p.evaluate((sk) => { if (window.DaimondSkin) DaimondSkin.set(sk); }, skin);
59 for (const theme of ['dark', 'light', 'lollypop']) {
60 await p.evaluate((th) => window.DaimondTheme.set(th), theme);
61 await p.waitForTimeout(350);
62 const box = await p.evaluate(() => {
63 const w = document.querySelector('.models-credit');
64 if (!w) return null;
65 const r = w.getBoundingClientRect();
66 return { x: Math.max(0, r.x - 12), y: Math.max(0, r.y - 12), width: r.width + 24, height: r.height + 24 };
67 });
68 const file = path.join(OUT, `credits-block-${skin}-${theme}.png`);
69 let err = '';
70 await p.screenshot({ path: file, clip: box || undefined, timeout: 8000 })
71 .catch((e) => { err = String(e && e.message ? e.message : e).split('\n')[0]; });
72 console.log(' →', file, err ? 'FAILED: ' + err : '');
73 }
74}
75
76await s.close();