Oregami
Repositories/oxedyne/daimond

oxedyne/daimond/dev/verify_tilering.mjs

5.3 KiB, 1 run

created by r2519314175:743, 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// The selected chat tile under the Breathe spacing: is its ring inside the box
2// the list is entitled to clip?
3//
4// It counted its own reds all along and then exited 0, so the count reached
5// nobody: `run_all.sh` reads the exit code. It exits on the count now.
6//
7// PROVED AGAINST TWO BREAKS FIRST, both applied as a stylesheet over the app's
8// own — nothing on disk is touched:
9// --break outerring the selected tile's ring is painted OUTSIDE its box,
10// which is the defect this file is named for.
11// --break flush the tiles are pushed flush to the list's edges, so the
12// ring has nowhere to sit and the clip eats it.
13//
14// node dev/verify_tilering.mjs --break outerring # expected to FAIL
15// node dev/verify_tilering.mjs --break flush # expected to FAIL
16// node dev/verify_tilering.mjs # and then, clean
17import { open, shot, newChat, errors } from './harness.mjs';
18
19const ok = [], bad = [];
20const check = (name, pass, detail) => {
21 (pass ? ok : bad).push(name + (detail ? ' — ' + detail : ''));
22 console.log((pass ? ' ok ' : ' FAIL ') + name + (detail ? ' — ' + detail : ''));
23};
24
25const BREAK = (() => {
26 const i = process.argv.indexOf('--break');
27 return i > 0 ? String(process.argv[i + 1] || '') : '';
28})();
29const BREAKS = {
30 outerring: '#session-list .session-box.active, #session-list .session-box.active:hover'
31 + '{ box-shadow: 0 0 0 2px rgb(210,96,79) !important; }',
32 flush: '#session-list { padding-left: 0 !important; padding-right: 0 !important; }'
33 + '#session-list .session-box { margin-left: 0 !important; margin-right: 0 !important; }',
34};
35if (BREAK && !BREAKS[BREAK]) {
36 console.error(`unknown break '${BREAK}'; known: ${Object.keys(BREAKS).join(', ')}`);
37 process.exit(2);
38}
39
40const SP = new URL('shots/', import.meta.url).pathname;
41const s = await open({ name: 'tile' });
42const { page } = s;
43if (BREAK) console.log(`\n*** RUNNING UNDER --break ${BREAK}: failures below are the point ***\n`);
44
45// A chat first, while the app is in the state open() left it in, then the
46// Breathe spacing applied in place -- a reload here loses the mock connection
47// and the chat input never appears.
48await newChat(s);
49await page.waitForTimeout(400);
50await page.evaluate(() => {
51 localStorage.setItem('daimond-skin', 'warm');
52 document.documentElement.setAttribute('data-skin', 'warm');
53});
54await page.waitForTimeout(500);
55if (BREAK) await page.addStyleTag({ content: BREAKS[BREAK] });
56// A CHAT tile, named by its list. `boxes[0]` was the first `.session-box` in the
57// document, and the Diamonds rail is above the chats — so on any account with a
58// Diamond this selected a Diamond tile, whose `closest('.session-list')` is null,
59// and every measurement below came back null. It has been failing that way, on a
60// file whose first line says "the selected chat tile".
61await page.waitForSelector('#session-list .session-box', { timeout: 8000 }).catch(() => {});
62const boxes = await page.$$('#session-list .session-box');
63if (boxes.length) { await boxes[0].click({ force: true }); await page.waitForTimeout(500); }
64
65const m = await page.evaluate(() => {
66 const box = document.querySelector('#session-list .session-box.active')
67 || document.querySelector('#session-list .session-box');
68 if (!box) return { err: 'no session box' };
69 const list = box.closest('.session-list');
70 const cs = getComputedStyle(box);
71 const b = box.getBoundingClientRect();
72 const l = list ? list.getBoundingClientRect() : null;
73 const lcs = list ? getComputedStyle(list) : null;
74 return {
75 skin: document.documentElement.getAttribute('data-skin'),
76 shadow: cs.boxShadow,
77 // An inset ring paints within these edges; an outer one does not.
78 inset: cs.boxShadow.includes('inset'),
79 boxLeft: +b.left.toFixed(2), boxRight: +b.right.toFixed(2),
80 listLeft: l ? +l.left.toFixed(2) : null, listRight: l ? +l.right.toFixed(2) : null,
81 overflowX: lcs ? lcs.overflowX : null,
82 leftRoom: l ? +(b.left - l.left).toFixed(2) : null,
83 rightRoom: l ? +(l.right - b.right).toFixed(2) : null,
84 active: box.classList.contains('active'),
85 };
86});
87console.log(JSON.stringify(m, null, 1));
88
89// Without a tile in the CHAT list there is nothing under test, and every
90// measurement below would be `undefined` — which is not a pass.
91check('there is a chat tile in the chat list to measure', !m.err && m.listLeft !== null,
92 m.err || `list ${m.listLeft}..${m.listRight}, tile ${m.boxLeft}..${m.boxRight}`);
93check('the tile the ring belongs to is the selected one', !!m.active, `active=${m.active}`);
94check('the Breathe spacing is on', m.skin === 'warm', `data-skin=${m.skin}`);
95check('THE SELECTED TILE\'S RING IS DRAWN INSIDE ITS BOX', !!m.inset, m.shadow);
96check('and the tiles have room for their lift either side',
97 m.leftRoom >= 2 && m.rightRoom >= 2, `left ${m.leftRoom}, right ${m.rightRoom}, list clips ${m.overflowX}`);
98
99const box = await page.$('.session-box.active') || (await page.$('.session-box'));
100if (box) await box.screenshot({ path: `${SP}/tile-after.png` });
101await shot(s, 'tile-warm');
102
103const errs = errors(s).filter(e => !/502|Bad Gateway/.test(e));
104check('nothing threw', errs.length === 0, errs.slice(0, 2).join(' | '));
105
106await s.close();
107console.log(`\n${ok.length} passed, ${bad.length} failed`);
108if (bad.length) { bad.forEach(x => console.log(' FAILED: ' + x)); process.exit(1); }