import json import subprocess from pathlib import Path LOADER = Path(__file__).parents[1] / "frontend" / "feature-loader.js" def run_loader(scenario: str) -> dict: harness = f""" const fs=require('fs'); const vm=require('vm'); const state={{appends:0, removed:0}}; const document={{ head:{{appendChild(node){{ state.appends++; state.node=node; }} }}, createElement(){{ return {{remove(){{state.removed++;}}}}; }}, }}; const context={{document, setTimeout, clearTimeout, console}}; context.globalThis=context; vm.createContext(context); vm.runInContext(fs.readFileSync({json.dumps(str(LOADER))},'utf8'),context); const createFeatureLoader=context.createFeatureLoader; (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_concurrent_feature_requests_share_one_script(): result = run_loader(""" const loader=createFeatureLoader({document, urls:{'issue-capture':'feature-a.js'}, timeoutMs:100}); const first=loader.load('issue-capture'); const second=loader.load('issue-capture'); state.node.onload(); await Promise.all([first,second]); console.log(JSON.stringify({appends:state.appends,same:first===second,ready:loader.ready('issue-capture')})); """) assert result == {"appends": 1, "same": True, "ready": True} def test_failed_feature_request_can_retry_without_reload(): result = run_loader(""" const loader=createFeatureLoader({document, urls:{'issue-capture':'feature-a.js'}, timeoutMs:100}); const failed=loader.load('issue-capture').catch(error=>error.message); state.node.onerror(); const message=await failed; const retry=loader.load('issue-capture'); state.node.onload(); await retry; console.log(JSON.stringify({appends:state.appends,removed:state.removed,message,ready:loader.ready('issue-capture')})); """) assert result == {"appends": 2, "removed": 1, "message": "Could not load issue capture.", "ready": True} def test_feature_gate_exposes_loading_failure_and_success_to_mobile_controls(): result = run_loader(""" const trigger={disabled:false}; const status={textContent:''}; let opened=0; const loader=createFeatureLoader({document, urls:{'issue-capture':'feature-a.js'}, timeoutMs:100}); const failed=loader.run('issue-capture',{trigger,status},()=>{opened++;}); const loading={disabled:trigger.disabled,status:status.textContent}; state.node.onerror(); const first=await failed; const failedState={disabled:trigger.disabled,status:status.textContent,opened}; const retry=loader.run('issue-capture',{trigger,status},()=>{opened++;}); state.node.onload(); const second=await retry; console.log(JSON.stringify({loading,failedState,first,second,opened,finalStatus:status.textContent})); """) assert result == { "loading": {"disabled": True, "status": "Loading issue capture…"}, "failedState": { "disabled": False, "status": "Issue capture could not load. Tap New issue to retry.", "opened": 0, }, "first": False, "second": True, "opened": 1, "finalStatus": "", }