const fs=require("fs"); const path=require("path"); const root=path.resolve(__dirname,".."); const appJs=fs.readFileSync(path.join(root,"static/js/app.js"),"utf8"); const html=fs.readFileSync(path.join(root,"app.html"),"utf8"); // Catch the exact class of bug that caused the v3.7.5 black screen: // a standalone `async` token before a normal function declaration. const strayAsync=/(^|\n)\s*async\s*\n\s*function\s+[A-Za-z_$]/m; if(strayAsync.test(appJs)){ throw new Error("runtime guard: stray standalone async token found"); } if(!/async function boot\s*\(\s*\)/.test(appJs)){ throw new Error("runtime guard: async boot() missing"); } if(!/\bboot\s*\(\s*\)\s*;/.test(appJs)){ throw new Error("runtime guard: boot() is not invoked"); } if(!/classList\.remove\(\s*["']auth-pending["']\s*\)/.test(appJs)){ throw new Error("runtime guard: auth-pending removal missing"); } if(!html.includes('id="sidebarToolsToggle"')){ throw new Error("runtime guard: sidebar collapse control missing"); } if(!appJs.includes("bindSidebarToolsToggle")){ throw new Error("runtime guard: sidebar collapse binding missing"); } // Parse the script as real JavaScript as an additional runtime-oriented gate. // Using Function catches parse errors in the same JS engine that runs this test. new Function(appJs); console.log("[frontend-smoke] OK: boot guard, auth escape, sidebar binding, no stray async");