// ── Tests Plugin: conditional loader ── // // The test runner is heavy (40+ test files), so we only load it when: // - URL contains ?test query param → auto-run // - Ctrl+Shift+Alt+T pressed → manual open // // Tests are completely optional — without this plugin the app has no // test runner code loaded at all. const hyprcrd = window.hyprcrd; // Cache-bust the test modules so edits to test files are picked up without // a hard refresh. The browser treats each unique URL as a distinct module, // so a fresh query string on each page load forces re-import. const V = '?v=' + Date.now(); // Auto-load if ?test in query string if (new URLSearchParams(location.search).has('test')) { ensureProgressBar(); import('./tests.js' + V); } // Keyboard shortcut: Ctrl+Shift+Alt+T → open runner. // // runner.js is imported with the SAME `?v=2` query string the test // files use (see RUNNER_V below). Same URL → same module instance, so // suite registration in test files and runAll in the loader run against // the same `suites` array. Bump RUNNER_V whenever runner.js changes // in a way that needs cache invalidation across users. document.addEventListener('keydown', e => { if (e.ctrlKey && e.shiftKey && e.altKey && (e.key === 'T' || e.key === 't')) { e.preventDefault(); ensureProgressBar(); import('./tests.js' + V).then(() => import('./runner.js' + RUNNER_V).then(m => m.open?.()) ); } }); // Must match the `?v=…` suffix used in test files' `from './runner.js?v=…'` // imports — bump both in lock-step to invalidate the runner.js cache. const RUNNER_V = '?v=2'; function ensureProgressBar() { if (document.getElementById('test-progress')) return; // Push the whole document down by 30px AND shrink the body by the // same amount so the footer doesn't get clipped (body is h-screen + // overflow-hidden, so without the height shrink the bottom 30px get // pushed off-viewport). hideProgress() reverts both. document.body.style.marginTop = '30px'; document.body.style.height = 'calc(100vh - 30px)'; const bar = document.createElement('div'); bar.id = 'test-progress'; const s = bar.style; s.setProperty('position', 'fixed', 'important'); s.setProperty('top', '0', 'important'); s.setProperty('left', '0', 'important'); s.setProperty('right', '0', 'important'); s.setProperty('height', '30px', 'important'); s.setProperty('z-index', '2147483647', 'important'); s.setProperty('background', '#000', 'important'); s.setProperty('color', '#cbd5e1', 'important'); s.setProperty('font-family', 'monospace', 'important'); s.setProperty('font-size', '11px', 'important'); s.setProperty('display', 'flex', 'important'); s.setProperty('align-items', 'center', 'important'); s.setProperty('gap', '10px', 'important'); s.setProperty('padding', '0 12px', 'important'); s.setProperty('border-bottom', '1px solid #334155', 'important'); s.setProperty('pointer-events', 'none', 'important'); bar.innerHTML = ` tests starting…
`; document.documentElement.appendChild(bar); } hyprcrd?.registerPlugin?.({ name: 'tests', version: '1.0.0', description: 'UI + state test runner', });