test: add article overview UX contract

This commit is contained in:
Masterluke77
2026-07-11 08:40:06 +02:00
parent 2eb759cd49
commit 61d914ecbb
@@ -0,0 +1,56 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
const root = resolve(process.cwd());
const read = path => readFileSync(resolve(root, path), 'utf8');
const loader = read('public/ux-foundation.js');
const css = read('public/article-overview-ux.css');
const js = read('public/article-overview-ux.js');
const pkg = JSON.parse(read('package.json'));
const failures = [];
const assert = (condition, message) => { if (!condition) failures.push(message); };
assert(loader.includes('/article-overview-ux.css?v=1.44.0'), 'Article-Overview-Stylesheet wird nicht über die UX-Foundation geladen.');
assert(loader.includes('/article-overview-ux.js?v=1.44.0'), 'Article-Overview-Script wird nicht über die UX-Foundation geladen.');
assert(pkg.scripts?.['verify:article-overview'] === 'node tools/verify-article-overview-ux-1.44.0.mjs', 'npm-Script verify:article-overview fehlt oder ist falsch.');
assert(String(pkg.scripts?.['verify:all'] || '').includes('verify:article-overview'), 'verify:all enthält das Article-Overview-Gate nicht.');
for (const value of ['', 'active', 'reserved', 'sold']) {
assert(js.includes(`value: '${value}'`), `Status-Schnellfilter fehlt: ${value || 'Alle'}`);
}
for (const id of ['history-list', 'filter-status', 'search-input', 'history-batch-actions', 'history-total-info']) {
assert(js.includes(id), `Bestehender Artikelvertrag wird nicht referenziert: ${id}`);
}
for (const token of ['data-article-view-choice', 'data-article-status', 'data-ux-label', 'MutationObserver', 'localStorage', 'requestAnimationFrame']) {
assert(js.includes(token), `Article-Overview-Vertrag fehlt: ${token}`);
}
assert(js.includes("row.tabIndex = 0"), 'Artikelkarten sind nicht tastaturfokussierbar.');
assert(js.includes("event.key === 'Enter'"), 'Artikelkarten unterstützen Enter nicht.');
assert(!js.includes('onclick='), 'Inline-Eventhandler sind im Article-Overview-Script unzulässig.');
assert(!js.includes('innerHTML +=') && !js.includes('outerHTML'), 'Unsichere DOM-Erweiterung im Article-Overview-Script erkannt.');
for (const selector of [
'.ux-article-toolbar',
'.ux-status-filters',
'.ux-active-filters',
'.ux-batch-more',
'#history[data-article-view="cards"] .history-list',
'#history[data-article-view="list"] .history-table-head',
'@media (max-width: 760px)',
'@media (prefers-reduced-motion: reduce)',
]) {
assert(css.includes(selector), `Article-Overview-CSS-Vertrag fehlt: ${selector}`);
}
assert(css.includes('focus-visible'), 'Sichtbare Tastaturfokusse fehlen im Article-Overview-CSS.');
assert(css.includes('var(--vd-'), 'Article-Overview-CSS verwendet das zentrale Design-Token-System nicht.');
assert(css.includes('repeat(auto-fill, minmax('), 'Adaptive Kartenraster fehlen.');
assert(css.includes('.history-batch-bar:not(.has-selection)'), 'Inaktive Mehrfachaktionen werden nicht reduziert.');
if (failures.length) {
console.error('[ARTICLE-OVERVIEW-UX] Prüfung fehlgeschlagen:');
failures.forEach(failure => console.error(`- ${failure}`));
process.exit(1);
}
console.log('[ARTICLE-OVERVIEW-UX] Karten-/Listenansicht, Status-Schnellfilter, aktive Filter, reduzierte Mehrfachaktionen, Responsive-Vertrag und Tastaturführung sind vollständig.');