This commit is contained in:
seb
2026-10-11 13:44:34 +02:00
parent e8b2ead83f
commit 1e2f57e941
37 changed files with 386 additions and 584 deletions

View File

@@ -190,7 +190,7 @@ async function main() {
await new Promise((resolve, reject) => {
const build = spawn('npx', ['vite', 'build'], {
cwd: FRONT_ROOT,
env: { ...process.env },
env: { ...process.env, NODE_ENV: 'production' },
stdio: ['ignore', 'pipe', 'pipe'],
});
build.stdout.on('data', () => process.stdout.write('[build] '));
@@ -208,7 +208,7 @@ async function main() {
const server = startProc(
'npx',
['vite', 'preview', '--port', String(VITE_PORT), '--strictPort'],
{ RIG_API_TARGET: `http://localhost:${DUMMY_PORT}` },
{ RIG_API_TARGET: `http://localhost:${DUMMY_PORT}`, NODE_ENV: 'production' },
'preview',
);
await waitForPort(VITE_PORT);
@@ -248,6 +248,7 @@ async function main() {
height: viewport.height,
settleMs: SETTLE_MS,
dialog: route.dialog,
icons: route.icons,
});
const kb = (buf.length / 1024).toFixed(0);

View File

@@ -161,7 +161,7 @@ async function httpJson(url, options = {}) {
* Opens a new page target on the browser, navigates, waits for the app root
* to contain content + network to quiet down, captures a PNG.
*/
export async function capturePage(debugPort, url, file, { width, height, settleMs = 6000, dialog }) {
export async function capturePage(debugPort, url, file, { width, height, settleMs = 6000, dialog, icons }) {
// Chrome ≥136 requires PUT for /json/new.
const target = await httpJson(`http://127.0.0.1:${debugPort}/json/new?${encodeURIComponent(url)}`, {
method: 'PUT',
@@ -257,6 +257,55 @@ export async function capturePage(debugPort, url, file, { width, height, settleM
}
}
// Icon sheet: replace the page by a white sheet with every distinct icon
// (inline SVG) found on it, drawn in black.
if (icons) {
await session.send('Runtime.evaluate', {
expression: `(() => {
const seen = new Map();
for (const svg of document.querySelectorAll('svg')) {
const r = svg.getBoundingClientRect();
if (r.width > 64 || r.height > 64) continue; // skip illustrations / spinners
if (svg.closest('[role="progressbar"]')) continue;
const key = svg.getAttribute('data-testid') || svg.innerHTML;
if (!svg.innerHTML || seen.has(key)) continue;
seen.set(key, svg);
}
const style = document.createElement('style');
style.textContent = \`
#icon-sheet{position:absolute;inset:0;background:#fff;color:#000;padding:24px;
display:flex;flex-wrap:wrap;gap:20px;align-content:flex-start;font:11px sans-serif}
#icon-sheet .cell{width:144px;display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;word-break:break-all}
#icon-sheet svg{width:144px;height:144px;color:#000;fill:#000}
#icon-sheet svg *{fill:#000;color:#000}
#icon-sheet svg [stroke]:not([stroke=none]){stroke:#000}
\`;
document.head.appendChild(style);
document.getElementById('root').style.display = 'none';
const sheet = document.createElement('div');
sheet.id = 'icon-sheet';
const sorted = [...seen.entries()].sort((a, b) => String(a[0]).localeCompare(String(b[0])));
for (const [key, svg] of sorted) {
const cell = document.createElement('div');
cell.className = 'cell';
const clone = svg.cloneNode(true);
clone.removeAttribute('class');
clone.removeAttribute('style');
clone.removeAttribute('width');
clone.removeAttribute('height');
cell.appendChild(clone);
const label = document.createElement('span');
label.textContent = svg.getAttribute('data-testid') || '';
cell.appendChild(label);
sheet.appendChild(cell);
}
document.body.style.background = '#fff';
document.body.appendChild(sheet);
})()`,
});
await wait(300);
}
// Determinism: hide carets and scrollbars.
await session.send('Runtime.evaluate', {
expression: `(() => { const s = document.createElement('style');

View File

@@ -20,6 +20,8 @@ export const ROUTES = [
{ name: 'vorlagen', path: '/artikel/vorlagen' },
{ name: 'merkmale', path: '/artikel/merkmale' },
{ name: 'artikel-detail', path: '/artikel/ART-000001' },
// Same page, but the shot is a white sheet with every icon on it in black.
{ name: 'artikel-detail-icons', path: '/artikel/ART-000001', icons: true },
{ name: 'lieferung', path: '/lieferung' },
{ name: 'lieferung-neu', path: '/lieferung/neu' },
{ name: 'lieferanten', path: '/lieferung/lieferanten' },

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 155 KiB