test(ux): add today workspace contract

This commit is contained in:
Masterluke77
2026-07-12 11:54:57 +02:00
parent c34d400a60
commit ce59e83d16
+112
View File
@@ -0,0 +1,112 @@
import fs from 'node:fs';
import path from 'node:path';
const root = process.cwd();
const read = relative => fs.readFileSync(path.join(root, relative), 'utf8');
const js = read('public/today-workspace.js');
const css = read('public/today-workspace.css');
const runtime = read('public/design-system/theme-runtime.js');
const html = read('public/index.html');
const pkg = JSON.parse(read('package.json'));
const failures = [];
const expect = (condition, message) => {
if (!condition) failures.push(message);
};
const includesAll = (source, values, label) => {
for (const value of values) expect(source.includes(value), `${label}: ${value}`);
};
includesAll(html, [
'id="today"',
'class="today-summary-grid"',
'id="today-count-ready"',
'id="today-count-scheduled"',
'id="today-count-published"',
'id="today-count-sold"',
'id="today-count-attention"',
'class="today-filterbar"',
'class="today-ready-panel"',
'class="today-scheduled-panel"',
'class="attention-panel"',
'class="today-activity-panel"',
'id="studio-inspector"',
'id="studio-inspector-content"',
], 'Bestehender Heute-Vertrag fehlt');
includesAll(runtime, [
'today-workspace.css?v=1.44.0',
'today-workspace.js?v=1.44.0',
'data-ux-today-workspace',
'loadTodayWorkspaceAssets()',
], 'Theme-Runtime bindet den Heute-Arbeitsplatz nicht vollständig ein');
expect(pkg.scripts?.['verify:today-workspace'] === 'node tools/verify-today-workspace-ux-1.44.0.mjs', 'verify:today-workspace Script fehlt');
expect(pkg.scripts?.['verify:all']?.includes('npm run verify:today-workspace'), 'verify:all enthält das Heute-UX-Gate nicht');
includesAll(js, [
'ux-today-command',
'ux-today-command-actions',
'ux-today-shortcuts',
'ux-today-filter-details',
'ux-today-panel-toggle',
'ux-today-inspector-toggle',
'ux-today-has-attention',
'ux-today-no-attention',
'data-ux-today-primary',
'data-ux-today-title',
'data-ux-today-copy',
'today-count-ready',
'today-count-scheduled',
'today-count-attention',
'today-ready-panel',
'today-scheduled-panel',
'attention-panel',
'today-activity-panel',
'studio-inspector-content',
'MutationObserver',
'requestAnimationFrame',
'scrollIntoView',
'ArrowLeft',
'ArrowRight',
'aria-expanded',
'aria-controls',
], 'Heute-UX-Vertrag fehlt');
includesAll(css, [
'#today.ux-today-workspace-ready',
'.ux-today-command',
'.ux-today-shortcuts',
'.ux-today-filter-details',
'.ux-today-panel-collapsed',
'.ux-today-inspector-toggle',
'.ux-today-has-attention',
'.ux-today-no-attention',
'@media (max-width: 900px)',
'@media (max-width: 700px)',
'@media (max-width: 470px)',
'@media (prefers-reduced-motion: reduce)',
':focus-visible',
'var(--',
], 'Heute-UX-CSS-Vertrag fehlt');
expect(!/\bfetch\s*\(/.test(js), 'Additive Heute-UX darf keine eigenen Netzwerkaufrufe ausführen');
expect(!/\bapi\s*\(/.test(js), 'Additive Heute-UX darf die Vendoo-API nicht direkt aufrufen');
expect(!/\.innerHTML\s*=/.test(js), 'Heute-UX darf keine innerHTML-Zuweisungen verwenden');
expect(!/\.outerHTML\s*=/.test(js), 'Heute-UX darf keine outerHTML-Zuweisungen verwenden');
expect(!/\.onclick\s*=/.test(js), 'Heute-UX darf keine onclick-Zuweisungen verwenden');
expect(!/confirm\s*\(/.test(js), 'Gefährliche Aktionen müssen in der bestehenden geprüften Logik bleiben');
expect(!/\b(?:DELETE|PATCH|POST|PUT)\b/.test(js), 'Heute-UX darf keine Schreiboperationen implementieren');
expect(!/loadToday\s*\(/.test(js), 'Heute-UX darf den produktiven Heute-Ladevorgang nicht direkt auslösen');
expect(!/loadPublishList\s*\(/.test(js), 'Heute-UX darf Publishing-Daten nicht direkt laden');
expect(!/loadHistory\s*\(/.test(js), 'Heute-UX darf Artikeldaten nicht direkt laden');
expect(!/setInterval\s*\(/.test(js), 'Heute-UX darf keinen eigenen Polling-Zyklus starten');
expect(!/state\.[a-zA-Z]/.test(js), 'Additive Heute-UX darf den produktiven App-State nicht direkt verändern');
if (failures.length) {
console.error('Today Workspace UX Gate fehlgeschlagen:');
for (const failure of failures) console.error(`- ${failure}`);
process.exit(1);
}
console.log('Today Workspace UX Gate bestanden.');