// Deterministic UI fixture: public invented metadata only; no production main process. const {app,BrowserWindow,ipcMain}=require('electron'); const fs=require('node:fs'),path=require('node:path'),os=require('node:os'); const fixtureDirectory=fs.mkdtempSync(path.join(os.tmpdir(),'safetynet-ui-fixture-')); function cleanup(){ const target=path.resolve(fixtureDirectory),parent=path.resolve(os.tmpdir()); if(path.dirname(target)===parent&&path.basename(target).startsWith('safetynet-ui-fixture-')){ try{fs.rmSync(target,{recursive:true,force:true});}catch{} } } app.setPath('userData',path.join(fixtureDirectory,'profile')); app.disableHardwareAcceleration(); app.commandLine.appendSwitch('force-device-scale-factor','1'); const watchdog=setTimeout(()=>app.exit(1),20000); let locked=false; const state=()=>({ready:true,enrolled:true,brand:{name:'SafetyNet'},policyVersion:1,url:'https://example.test/',message:'UI fixture · public example metadata',aiEnabled:true,agentsEnabled:true,documentScanEnabled:true,passwordManagerEnabled:true,vaultExists:true,vaultLocked:locked}); const vaultStatus=()=>({exists:true,locked,enabled:true,idleLockSeconds:120,allowSaving:true,allowAutofill:true}); ipcMain.handle('ui-fixture',(_event,method)=>{ if(method==='state')return {ok:true,data:state()}; if(method==='vaultStatus')return {ok:true,data:vaultStatus()}; if(method==='vaultList')return {ok:true,data:locked?[]:[{id:'fixture-1',origin:'https://example.test',label:'Public example account',username:'alex@example.test'}]}; if(method==='vaultLock'){locked=true;return {ok:true,data:vaultStatus()};} if(method==='vaultUnlock'){locked=false;return {ok:true,data:vaultStatus()};} if(['toggleVault','toggleAI'].includes(method))return {ok:true,data:null}; return {ok:false,error:'This preview does not perform real browser or credential operations.'}; }); const preload=path.join(fixtureDirectory,'fixture-preload.cjs'); fs.writeFileSync(preload,`const {contextBridge,ipcRenderer}=require('electron');const api={onState:()=>()=>{}};for(const method of ['state','toggleVault','toggleAI','vaultStatus','vaultList','vaultLock','vaultUnlock','vaultCreate','vaultSave','vaultDelete','vaultFill','vaultGenerate'])api[method]=(...args)=>ipcRenderer.invoke('ui-fixture',method,...args);contextBridge.exposeInMainWorld('safetynet',api);`); app.whenReady().then(async()=>{ let win; try{ win=new BrowserWindow({show:false,useContentSize:true,width:1320,height:900,webPreferences:{preload,contextIsolation:true,sandbox:true,nodeIntegration:false}}); await win.loadFile(path.resolve('apps/browser/index.html')); await win.webContents.executeJavaScript(`document.getElementById('passwords').click()`); for(let n=0;n<40;n++){ if(await win.webContents.executeJavaScript(`document.getElementById('vault-list').textContent.includes('Public example account')`))break; await new Promise(resolve=>setTimeout(resolve,50)); } await win.webContents.executeJavaScript(`(()=>{const label=document.createElement('div');label.id='fixture-label';label.textContent='UI fixture preview · invented public metadata';label.style.cssText='position:fixed;left:30px;top:135px;color:#8994a3;font:12px Segoe UI';document.body.append(label);})()`); await win.webContents.executeJavaScript(`new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve)))`); fs.mkdirSync(path.resolve('artifacts'),{recursive:true}); fs.writeFileSync(path.resolve('artifacts/ui-vault-preview.png'),(await win.webContents.capturePage()).toPNG()); await win.webContents.executeJavaScript(`document.getElementById('vault-lock').click()`); for(let n=0;n<40;n++){ if(await win.webContents.executeJavaScript(`!document.getElementById('vault-access').hidden`))break; await new Promise(resolve=>setTimeout(resolve,50)); } fs.writeFileSync(path.resolve('artifacts/ui-vault-locked-preview.png'),(await win.webContents.capturePage()).toPNG()); const bounds=await win.webContents.executeJavaScript(`JSON.stringify({header:document.querySelector('header').getBoundingClientRect().height,vaultWidth:document.getElementById('vault').getBoundingClientRect().width,vaultTop:document.getElementById('vault').getBoundingClientRect().top,missingIcons:[...document.images].filter(i=>!i.complete||!i.naturalWidth).length,locked:document.getElementById('vault-open').hidden,masked:document.getElementById('vault-master').type==='password'})`); fs.writeFileSync(path.resolve('artifacts/ui-vault-preview-layout.json'),bounds); win.setContentSize(800,650); await win.webContents.executeJavaScript(`new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve)))`); fs.writeFileSync(path.resolve('artifacts/ui-vault-compact-preview.png'),(await win.webContents.capturePage()).toPNG()); console.log('UI fixture captured: unlocked and locked password panels.'); win.destroy();win=null;clearTimeout(watchdog); cleanup();app.exit(0); }catch{win?.destroy();clearTimeout(watchdog);cleanup();app.exit(1);} }).catch(()=>app.exit(1)); app.on('will-quit',cleanup);