import json import subprocess from pathlib import Path BOOTSTRAP = Path(__file__).parents[1] / "frontend" / "workspace-bootstrap.js" def run_bootstrap(scenario: str) -> dict: harness = f""" const loadWorkspace = require({json.dumps(str(BOOTSTRAP))}); (async()=>{{ {scenario} }})().catch(error=>{{console.error(error);process.exit(1);}}); """ completed = subprocess.run( ["node", "-e", harness], check=True, capture_output=True, text=True ) return json.loads(completed.stdout) def test_workspace_bootstrap_loads_content_addressed_feature_before_startup(): result = run_bootstrap(""" const status={textContent:''}; const document={ querySelector(selector) { if (selector === 'meta[name="stackchain-feature-today-timer"]') return {content:'feature-workspace-abc.js'}; if (selector === '#my-work-action-status') return status; return null; } }; let requested=''; const createLoader=options=>({load:async name=>{requested=name + ':' + options.urls[name];}}); await loadWorkspace({document,createLoader}); console.log(JSON.stringify({requested,status:status.textContent})); """) assert result == {"requested": "today-timer:feature-workspace-abc.js", "status": ""} def test_workspace_bootstrap_keeps_shell_and_announces_retry_when_feature_fails(): result = run_bootstrap(""" const status={textContent:''}; const document={ querySelector(selector) { if (selector === 'meta[name="stackchain-feature-today-timer"]') return {content:'feature-workspace-abc.js'}; if (selector === '#my-work-action-status') return status; return null; } }; const createLoader=()=>({load:async()=>{throw new Error('network failed');}}); let message=''; try { await loadWorkspace({document,createLoader}); } catch (error) { message=error.message; } console.log(JSON.stringify({message,status:status.textContent})); """) assert result == { "message": "network failed", "status": "Workspace could not load. Check your connection, then reload to retry.", } def test_workspace_bootstrap_reloads_after_a_failed_offline_load_reconnects(): result = run_bootstrap(""" const status={textContent:''}; const listeners={}; let reloads=0; const document={querySelector(selector) { if (selector.startsWith('meta[')) return {content:'feature-workspace-abc.js'}; if (selector === '#my-work-action-status') return status; return null; }}; const window={ location:{reload(){reloads++;}}, addEventListener(name,callback) { listeners[name]=callback; }, removeEventListener(name,callback) { if (listeners[name] === callback) delete listeners[name]; }, }; const createLoader=()=>({load:async()=>{throw new Error('offline');}}); try { await loadWorkspace({document,window,createLoader}); } catch (error) {} const waiting=Boolean(listeners.online); if (listeners.online) listeners.online(); console.log(JSON.stringify({waiting,reloads,status:status.textContent})); """) assert result == { "waiting": True, "reloads": 1, "status": "Workspace could not load. Reconnect to retry automatically, or reload now.", } def test_workspace_bootstrap_reloads_when_reconnect_arrives_before_load_failure(): result = run_bootstrap(""" const status={textContent:''}; const listeners={}; let reloads=0; const document={querySelector(selector) { if (selector.startsWith('meta[')) return {content:'feature-workspace-abc.js'}; if (selector === '#my-work-action-status') return status; return null; }}; const window={ location:{reload(){reloads++;}}, addEventListener(name,callback) { listeners[name]=callback; }, removeEventListener(name,callback) { if (listeners[name] === callback) delete listeners[name]; }, }; const createLoader=()=>({load:async()=>{listeners.online(); throw new Error('offline request');}}); try { await loadWorkspace({document,window,createLoader}); } catch (error) {} console.log(JSON.stringify({reloads,waiting:Boolean(listeners.online)})); """) assert result == {"reloads": 1, "waiting": False} def test_workspace_bootstrap_replays_online_event_after_dashboard_registers_handlers(): result = run_bootstrap(""" const status={textContent:''}; const listeners={}; const document={querySelector(selector) { if (selector.startsWith('meta[')) return {content:'feature-workspace-abc.js'}; if (selector === '#my-work-action-status') return status; return null; }}; const window={ addEventListener(name,callback) { listeners[name]=callback; }, removeEventListener(name,callback) { if (listeners[name] === callback) delete listeners[name]; }, }; const createLoader=()=>({load:async()=>{listeners.online();}}); const lifecycle=await loadWorkspace({document,window,createLoader}); let reconnects=0; lifecycle.replayOnline(()=>{reconnects++;}); lifecycle.replayOnline(()=>{reconnects++;}); console.log(JSON.stringify({reconnects,listening:Boolean(listeners.online)})); """) assert result == {"reconnects": 1, "listening": False}