From 67a609dd5e98df4df9a3fb40104817e0c25e5582 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 2 Jul 2026 13:10:54 -0400 Subject: feat(theme-studio): screenshot harness + ecosystem coverage policy Two speedrun-enabling pieces. A #preview=&theme= hash handler plus screenshot-previews.sh shoot any app's face table and live preview headlessly under a real theme (WIP.json by default), so preview work can be verified without a human clicking through the studio. The README gains the coverage policy: the studio themes popular packages even when uninstalled, pinning their faces rather than dropping them, and unloaded packages' previews matter more, not less. --- scripts/theme-studio/theme-studio.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'scripts/theme-studio/theme-studio.html') diff --git a/scripts/theme-studio/theme-studio.html b/scripts/theme-studio/theme-studio.html index 8cb6cc02..8e219fcd 100644 --- a/scripts/theme-studio/theme-studio.html +++ b/scripts/theme-studio/theme-studio.html @@ -3499,6 +3499,29 @@ function initApp(){ } initApp(); addEventListener('resize',()=>{syncPaneHeight('uitable','mockframe');syncPaneHeight('pkgtable','pkgpreview');}); +// #preview=[&theme=]: select that app on load and hide the +// topbar + palette so its face table + live preview render from the top of the +// page (headless screenshots can't scroll reliably). An optional theme URL is +// fetched and imported first, so shots show a real theme instead of untitled +// (fresh headless profiles have no localStorage; Chrome needs +// --allow-file-access-from-files for a file:// fetch). Drives the screenshot +// harness (screenshot-previews.sh), same hash-URL pattern as the browser gates. +// The title flip lets the harness confirm the selection landed. +if(location.hash.startsWith('#preview=')){ + const q=location.hash.slice(9).split('&theme='); + const k=decodeURIComponent(q[0]); + const showApp=()=>{ + if(!APPS[k])return; + const s=document.getElementById('viewsel'); + if(!s)return; + s.value=k;onViewChange();document.title='PREVIEW '+k; + document.querySelectorAll('.topbar, body > section') + .forEach(e=>{e.style.display='none';});}; + if(q[1])fetch(decodeURIComponent(q[1])).then(r=>r.text()) + .then(t=>{applyImported(t);showApp();}) + .catch(()=>{document.title='PREVIEW THEME-LOAD-FAILED';showApp();}); + else showApp(); +} // Shared gate harness. Each call site keeps its literal location.hash==='#NAMEtest' // check (run-tests.sh greps it); gate() owns the ok/notes/A setup and the verdict // postamble. Note format standardized to ' fails=note1,note2'. -- cgit v1.2.3