u
@@ -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);
|
||||
|
||||
|
||||
51
test/cdp.mjs
@@ -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');
|
||||
|
||||
@@ -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' },
|
||||
|
||||
BIN
test/screenshots/reference/artikel-detail-icons.1280x960.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
test/screenshots/reference/artikel-detail-icons.1920x1200.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 218 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 155 KiB |