'use strict'; if (!process.versions.electron) { const fs = require('node:fs'), path = require('node:path'), os = require('node:os'); const { spawn } = require('node:child_process'); const owned = fs.mkdtempSync(path.join(os.tmpdir(), 'safetynet-ui-showcase-')); const env = { ...process.env, SAFETYNET_SHOWCASE_PROFILE: owned }; delete env.ELECTRON_RUN_AS_NODE; const child = spawn(require('electron'), [__filename], { stdio: 'inherit', windowsHide: true, env }); const deadline = setTimeout(() => child.kill(), 90_000); const finish = code => { clearTimeout(deadline); const resolved = path.resolve(owned); if (!resolved.startsWith(path.resolve(os.tmpdir()) + path.sep) || !path.basename(resolved).startsWith('safetynet-ui-showcase-')) throw Error('Unsafe showcase cleanup'); fs.rmSync(resolved, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }); process.exit(code ?? 1); }; child.once('error', () => finish(1)); child.once('exit', finish); } else { // Finite test harness for the real trusted shell. No production browser startup, // site view, real credentials, network browsing or external application state. const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron'); const fs = require('node:fs'); const path = require('node:path'); const os = require('node:os'); const assert = require('node:assert/strict'); const { capturePNG } = require('../apps/browser/visual-capture.cjs'); app.disableHardwareAcceleration(); // Windows fixture uses the CPU compositor; production keeps its sandboxed defaults. app.commandLine.appendSwitch('force-device-scale-factor', '1'); const root = path.resolve(__dirname, '..'); const profile = process.env.SAFETYNET_SHOWCASE_PROFILE || fs.mkdtempSync(path.join(os.tmpdir(), 'safetynet-ui-showcase-')); if (!profile.startsWith(path.resolve(os.tmpdir()) + path.sep)) throw Error('Unsafe showcase profile'); app.setPath('userData', profile); const output = path.join(root, 'artifacts'); fs.mkdirSync(output, { recursive: true }); const methods = ['organizeLibrary','applyLibraryOrganization','createTab','activateTab','closeTab','groupTab','mutateBookmarks','updateSettings','authorizeSetting','state', 'windowControls', 'setChromeLayout', 'shareURL', 'enroll', 'sso', 'navigate', 'back', 'forward', 'reload', 'ai', 'inspectFile', 'agentConnection', 'toggleAI', 'toggleVault', 'vaultStatus', 'vaultCreate', 'vaultUnlock', 'vaultLock', 'vaultList', 'vaultSave', 'vaultDelete', 'vaultFill', 'vaultGenerate']; const preload = path.join(profile, 'showcase-preload.cjs'); fs.writeFileSync(preload, `const {contextBridge,ipcRenderer}=require('electron'); const methods=${JSON.stringify(methods)}; const api={};for(const method of methods)api[method]=(...args)=>ipcRenderer.invoke('showcase:call',method,args);api.onState=callback=>{const listener=(_event,state)=>callback(state);ipcRenderer.on('showcase:state',listener);return()=>ipcRenderer.removeListener('showcase:state',listener);};contextBridge.exposeInMainWorld('safetynet',api);`); const fixtures = [ { title: 'Apple Documentation', url: 'https://developer.apple.com/' }, { title: 'GitHub', url: 'https://github.com/' }, { title: 'MDN', url: 'https://developer.mozilla.org/' }, { title: 'Wikipedia', url: 'https://wikipedia.org/' }, { title: 'Company Intranet', url: 'https://intranet.example.test/' }, { title: 'Design Library', url: 'https://design.example.test/' } ]; let state = { ready: true, enrolled: true, brand: { name: 'SafetyNet' }, url: 'https://example.test', pageTitle: 'Reference Workspace', pageColor: '#8aacb4', canNavigate: true, policyVersion: 12, message: 'Public fixture · centrally managed workspace', aiEnabled: true, agentsEnabled: true, documentScanEnabled: true, passwordManagerEnabled: true, vaultLocked: false }; let nextTab=1;state.tabsRevision=0;state.tabs=[{id:'showcase-native-1',url:state.url,title:state.pageTitle,color:state.pageColor,group:'',startPage:false,canGoBack:false,canGoForward:false}];state.activeTabId=state.tabs[0].id; function snapshot(){const tab=state.tabs.find(tab=>tab.id===state.activeTabId);state={...state,url:tab.url,pageTitle:tab.title,pageColor:tab.color,tabsRevision:state.tabsRevision+1};return JSON.parse(JSON.stringify(state));} function publish(sender){const result=snapshot();sender.send('showcase:state',result);return result;} state.settings={available:true,visible:true,hiddenSections:[],lockedSections:[],appearance:{mode:'system',accent:'blue',tabMode:'separate'}}; state.bookmarks={managed:[{...fixtures[4],id:'showcase-company',folder:'Company'}],personal:{revision:0,items:fixtures.filter((_,i)=>i!==4).map((item,i)=>({...item,id:`showcase-${i}`,folder:'Work'}))},allowUserAdd:true,allowUserEdit:true,allowUserDelete:true,adminReadUserBookmarks:true}; let vaultLocked = false; const records = [], screenshots = [], consoleErrors = []; let window, finished = false; function cleanup() { if (path.resolve(profile).startsWith(path.resolve(os.tmpdir()) + path.sep) && path.basename(profile).startsWith('safetynet-ui-showcase-')) { try { fs.rmSync(profile, { recursive: true, force: true }); } catch {} } } if (!process.env.SAFETYNET_SHOWCASE_PROFILE) app.on('quit', cleanup); const watchdog = setTimeout(() => { console.error('UI showcase exceeded 80 seconds'); app.exit(1); }, 80_000); watchdog.unref(); ipcMain.handle('showcase:call', (event, method, args) => { if (event.sender !== window?.webContents || !methods.includes(method)) return { ok: false, error: 'Showcase operation refused' }; let data = null; const navigation=typeof args[0]==='object'?args[0]:{url:args[0],tabId:state.activeTabId}; if(method==='navigate'&&navigation.url==='https://example.test/slow'){const id=navigation.tabId;return new Promise(resolve=>setTimeout(()=>{const tab=state.tabs.find(tab=>tab.id===id);if(tab){tab.url=navigation.url;tab.title='Delayed public fixture';tab.startPage=false;}resolve({ok:true,data:publish(event.sender)});},250));} if (method === 'state' || ['enroll', 'sso', 'back', 'forward', 'reload'].includes(method)) data = snapshot(); else if(method==='createTab'){const tab={id:`showcase-native-${++nextTab}`,url:'',title:'New Tab',group:args[0]?.group||'',startPage:true,color:'#b8c7dd',canGoBack:false,canGoForward:false};state.tabs.push(tab);state.activeTabId=tab.id;data=publish(event.sender);} else if(method==='activateTab'){assert.ok(state.tabs.some(tab=>tab.id===args[0]));state.activeTabId=args[0];data=publish(event.sender);} else if(method==='closeTab'){const index=state.tabs.findIndex(tab=>tab.id===args[0]);assert.ok(index>=0);state.tabs.splice(index,1);if(!state.tabs.length){state.tabs.push({id:`showcase-native-${++nextTab}`,url:'',title:'New Tab',group:'',startPage:true,color:'#b8c7dd',canGoBack:false,canGoForward:false});}if(state.activeTabId===args[0])state.activeTabId=state.tabs[Math.min(index,state.tabs.length-1)].id;data=publish(event.sender);} else if(method==='organizeLibrary'){assert.ok(state.libraryAI?.suggestionsEnabled);data={proposalId:'fixture-review-id',plan:{bookmarks:[{id:'showcase-1',folder:'Engineering'}],tabs:[]}};} else if(method==='applyLibraryOrganization'){assert.equal(args[0].proposalId,'fixture-review-id');assert.equal(args[0].confirm,true);state.bookmarks.personal.items.find(item=>item.id==='showcase-1').folder='Engineering';state.bookmarks.personal.revision++;data={completed:true};} else if(method==='groupTab'){assert.ok(state.settings.visible&&!state.settings.hiddenSections.includes('library')&&!state.settings.lockedSections.includes('library'));const tab=state.tabs.find(tab=>tab.id===args[0].id);assert.ok(tab);tab.group=args[0].group;data=publish(event.sender);} else if(method==='mutateBookmarks'){const input=args[0];if(!state.settings.visible||state.settings.hiddenSections.includes('library')||state.settings.lockedSections.includes('library')||input.expectedRevision!==state.bookmarks.personal.revision)return {ok:false,error:'Managed bookmark refused'};assert.equal(input.action,'add');state.bookmarks.personal={revision:state.bookmarks.personal.revision+1,items:[...state.bookmarks.personal.items,input.bookmark]};data=state;event.sender.send('showcase:state',state);} else if(method==='updateSettings'){if(!state.settings.available||!state.settings.visible||state.settings.hiddenSections.includes('appearance')||state.settings.lockedSections.includes('appearance'))return{ok:false,error:'Managed setting refused'};state.settings={...state.settings,appearance:{...args[0]}};data=state.settings;} else if(method==='authorizeSetting'){if(!state.settings.available||!state.settings.visible||state.settings.hiddenSections.includes(args[0])||state.settings.lockedSections.includes(args[0]))return{ok:false,error:'Managed setting refused'};data={allowed:true};} else if (method === 'navigate') { const url = new URL(navigation.url); assert.equal(url.protocol, 'https:');const tab=state.tabs.find(tab=>tab.id===navigation.tabId);assert.ok(tab);tab.url=url.href;tab.title=fixtures.find(item=>item.url===url.href)?.title||'Reference Workspace';tab.startPage=false;data=publish(event.sender); } else if (method === 'setChromeLayout') { const layout = args[0]; assert.ok([64, 104].includes(layout.height)); for (const key of ['sidebarOpen', 'startPageOpen', 'overviewOpen', 'toolsOpen']) assert.equal(typeof layout[key], 'boolean'); records.push({ method, ...layout, nativeHidden: layout.startPageOpen || layout.overviewOpen || layout.toolsOpen }); data = { applied: true }; } else if (method === 'windowControls') { assert.ok(['minimize', 'maximize', 'close'].includes(args[0])); records.push({ method, action: args[0], nativeFlag: false }); data = { recorded: true }; } else if (method === 'shareURL') data = { shared: true }; else if (method === 'toggleAI' || method === 'toggleVault') { records.push({ method, open: args[0] }); data = { applied: true }; } else if (method === 'vaultStatus') data = { enabled: true, exists: true, locked: vaultLocked, allowSaving: true, allowAutofill: true, idleLockSeconds: 300 }; else if (method === 'vaultList') data = [{ id: 'public-fixture', origin: 'https://example.test', username: 'example-user', label: 'Public demonstration account' }]; else if (method === 'vaultLock') { vaultLocked = true; data = { locked: true }; } else if (method === 'vaultCreate' || method === 'vaultUnlock') { vaultLocked = false; data = { locked: false }; } else if (method === 'vaultGenerate') data = 'PUBLIC-DEMONSTRATION-ONLY'; else if (method === 'vaultSave' || method === 'vaultDelete' || method === 'vaultFill') data = { completed: true }; else if (method === 'ai') data = { answer: 'Public local fixture response.' }; else if (method === 'agentConnection') data = { address: 'http://127.0.0.1:0', credentialPath: 'Public showcase · no pairing credential' }; return { ok: true, data }; }); const delay = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds)); async function execute(source) { return window.webContents.executeJavaScript(source, true); } async function reloadShell() { const loaded = new Promise((resolve, reject) => { const timer = setTimeout(() => reject(Error('Showcase shell reload timed out')), 5000); window.webContents.once('did-finish-load', () => { clearTimeout(timer); resolve(); }); }); window.webContents.reload(); await loaded; await delay(100); } async function waitFor(source, expected) { for (let attempt = 0; attempt < 40; attempt++) { if (await execute(source) === expected) return; await delay(70); } assert.equal(await execute(source), expected); } async function click(id) { await execute(`document.getElementById(${JSON.stringify(id)}).click()`); await delay(100); } async function appearance(theme, mode) { await execute(`for(const [id,value] of ${JSON.stringify([['theme-mode', theme], ['tab-mode', mode]])}){const element=document.getElementById(id);element.value=value;element.dispatchEvent(new Event('change',{bubbles:true}));}`); await delay(100); } async function accent(value) { await execute(`(()=>{const selector=document.getElementById('accent-mode');selector.value=${JSON.stringify(value)};selector.dispatchEvent(new Event('change',{bubbles:true}));})()`); await delay(90); } async function shot(name) { console.log('Showcase capture: ' + name); await execute('document.fonts.ready'); await delay(90); const measurements = await execute(`(()=>{const rect=id=>{const element=document.getElementById(id),r=element.getBoundingClientRect();return{hidden:element.hidden,x:r.x,y:r.y,width:r.width,height:r.height}};const brokenImages=[...document.images].filter(image=>image.hasAttribute('src')&&(!image.complete||!image.naturalWidth)).map(image=>image.getAttribute('src'));return{viewport:{width:innerWidth,height:innerHeight,zoom:devicePixelRatio},theme:document.documentElement.dataset.theme,effectiveTheme:document.documentElement.dataset.effectiveTheme,accent:document.documentElement.dataset.accent,tabMode:document.documentElement.dataset.tabMode,chrome:rect('chrome'),toolbar:document.querySelector('.toolbar').getBoundingClientRect().height,library:rect('library'),ai:rect('ai'),vault:rect('vault'),startPage:rect('start-page'),overview:rect('overview'),tools:rect('tools-menu'),scrollWidth:document.documentElement.scrollWidth,brokenImages,error:document.getElementById('error').textContent,passwordFieldsEmpty:[...document.querySelectorAll('input[type=password]')].every(input=>!input.value)}})()`); assert.equal(measurements.toolbar, 64); assert.ok([64, 104].includes(measurements.chrome.height)); assert.equal(measurements.scrollWidth, measurements.viewport.width); assert.deepEqual(measurements.brokenImages, []); assert.equal(measurements.passwordFieldsEmpty, true); assert.equal(measurements.error, ''); if (!measurements.library.hidden) assert.equal(measurements.library.width, 240); for (const panel of ['ai', 'vault']) if (!measurements[panel].hidden) assert.equal(measurements[panel].width, 360); // This Windows host's native capturePage can return an earlier compositor frame. // Exercise the existing trusted screenshot-only CDP fallback for finite fixtures. const capturePage = window.webContents.capturePage; let png; try { window.webContents.capturePage = async () => { throw Error('Use finite showcase compositor fallback'); }; png = await capturePNG(window.webContents); } finally { window.webContents.capturePage = capturePage; } fs.writeFileSync(path.join(output, name + '.png'), png); screenshots.push({ name, ...measurements }); } app.whenReady().then(async () => { window = new BrowserWindow({ width: 1320, height: 900, useContentSize: true, frame: false, show: true, backgroundColor: '#f7f8fa', webPreferences: { preload, contextIsolation: true, sandbox: true, nodeIntegration: false, zoomFactor: 1 } }); window.webContents.setZoomFactor(1); window.webContents.on('console-message', event => { if (event.level === 'error' || event.level >= 3) consoleErrors.push(event.message); }); window.webContents.on('will-navigate', event => event.preventDefault()); window.webContents.setWindowOpenHandler(() => ({ action: 'deny' })); await window.loadFile(path.join(root, 'apps/browser/index.html')); await execute(`localStorage.clear();localStorage.setItem('sbrowser.bookmarks',${JSON.stringify(JSON.stringify(fixtures))});localStorage.setItem('sbrowser.theme','"light"');localStorage.setItem('sbrowser.tab-mode','"separate"');localStorage.setItem('sbrowser.accent','{"toString":0}');`); await reloadShell(); assert.equal(await execute(`document.documentElement.dataset.accent`), 'blue'); await appearance('auto', 'separate'); nativeTheme.themeSource = 'dark'; await waitFor(`document.documentElement.dataset.effectiveTheme`, 'dark'); nativeTheme.themeSource = 'light'; await waitFor(`document.documentElement.dataset.effectiveTheme`, 'light'); await appearance('dark', 'separate'); nativeTheme.themeSource = 'light'; await delay(90); assert.equal(await execute(`document.body.dataset.theme`), 'dark'); await accent('teal'); await reloadShell(); assert.equal(await execute(`document.documentElement.dataset.accent`), 'teal'); assert.equal(await execute(`document.documentElement.dataset.theme`), 'dark'); assert.equal(await execute(`document.documentElement.style.getPropertyValue('--accent')`), '#007d76'); await accent('blue'); await appearance('light', 'separate'); // Real DOM interactions verify tabs, bookmarks, themes and overlay signaling. await click('tools-toggle'); await click('bookmark'); await execute(`document.getElementById('bookmark-form').requestSubmit()`); await waitFor(`document.getElementById('bookmark-editor').open`,false); assert.equal(state.bookmarks.managed.length+state.bookmarks.personal.items.length,7); assert.equal(await execute(`JSON.parse(localStorage.getItem('sbrowser.bookmarks')).length`), 6,'User bookmarks must not be mutated through renderer storage'); await click('new-tab'); assert.equal(await execute(`document.getElementById('library').hidden`),true,'Sidebar starts collapsed'); assert.equal(await execute(`document.querySelectorAll('#favorites-grid .favorite-card').length`), 7); await click('sidebar-toggle');await execute(`document.getElementById('group-name').value='Work'`);await click('group-add');assert.equal(state.tabs.find(t=>t.id===state.activeTabId).group,'Work');await execute(`document.getElementById('group-name').value='Research';document.querySelector('[aria-label="Rename group Work"]').click()`);await waitFor(`document.querySelector('[aria-label="Ungroup tabs in Research"]')!==null`,true);assert.equal(state.tabs.find(t=>t.id===state.activeTabId).group,'Research');await execute(`document.querySelector('[aria-label="Ungroup tabs in Research"]').click()`);await waitFor(`document.querySelector('[aria-label="Ungroup tabs in Research"]')===null`,true);assert.equal(state.tabs.find(t=>t.id===state.activeTabId).group,'');await click('sidebar-toggle'); const aligned=await execute(`(()=>{const cards=[...document.querySelectorAll('#favorites-grid .favorite-card')];const first=cards[0].getBoundingClientRect().top;return cards.filter(c=>c.getBoundingClientRect().top===first).map(c=>c.querySelector('.favorite-icon').getBoundingClientRect().top)})()`);assert.ok(aligned.length>1);assert.ok(aligned.every(top=>Math.abs(top-aligned[0])<1),'Managed and personal favorites share icon baseline'); await click('favorites-manage');assert.equal(await execute(`document.getElementById('bookmark-manager').open`),true);assert.equal(await execute(`document.querySelectorAll('#manager-list .manager-row').length`),7);assert.equal(await execute(`document.querySelector('#manager-list [data-bookmark-id="showcase-company"] .manager-row-actions')===null`),true);assert.equal(await execute(`document.getElementById('manager-ai').disabled`),true);await execute(`document.getElementById('bookmark-search').value='github';document.getElementById('bookmark-search').dispatchEvent(new Event('input'))`);assert.equal(await execute(`document.querySelectorAll('#manager-list .manager-row').length`),1);await shot('sbrowser-bookmark-manager');state.libraryAI={suggestionsEnabled:true,autoApplyEnabled:false,busy:false};window.webContents.send('showcase:state',snapshot());await delay(100);await click('manager-ai');assert.equal(await execute(`document.getElementById('manager-proposal').hidden`),false);assert.match(await execute(`document.getElementById('manager-diff').textContent`),/GitHub.*Engineering/);assert.equal(state.bookmarks.personal.items.find(item=>item.id==='showcase-1').folder,'Work','Preview has no side effects');await click('manager-apply');assert.equal(state.bookmarks.personal.items.find(item=>item.id==='showcase-1').folder,'Engineering');await click('bookmark-manager-close'); await shot('sbrowser-light'); state.brand={name:'Northstar Company',color:'#166b68',logoDataUrl:'data:image/png;base64,'+fs.readFileSync(path.join(root,'docs/brand/safetynet-icon.png')).toString('base64')}; state.startPage={title:'Welcome to Northstar.',subtitle:'Your company workspace, news and favorite tools.',newsEnabled:true,news:[{id:'news-1',title:'Company update: our new intranet is here',url:'https://intranet.example.test/news',publishedAt:'2026-10-13T12:00:00Z'},{id:'news-2',title:'Security week: join the local AI workshop',url:'https://intranet.example.test/events'}]}; window.webContents.send('showcase:state',snapshot());await delay(150); assert.equal(await execute(`document.getElementById('start-brand-name').textContent`),'Northstar Company'); assert.equal(await execute(`document.querySelectorAll('#company-news-items .company-news-card').length`),2); assert.equal(await execute(`document.getElementById('start-company-logo').hidden`),false); await shot('sbrowser-company-branding'); state.startPage={newsEnabled:false};state.brand={name:'SafetyNet'};window.webContents.send('showcase:state',snapshot());await delay(100); assert.equal(await execute(`document.getElementById('company-news').hidden`),true);assert.equal(await execute(`document.getElementById('start-company-logo').hasAttribute('src')`),false); await appearance('dark', 'compact'); await shot('sbrowser-dark'); await click('tab-overview'); assert.equal(await execute(`document.querySelectorAll('#overview-grid .overview-card').length`), 2); await shot('sbrowser-overview'); await click('overview-close'); await appearance('light', 'separate'); await click('tools-toggle'); await shot('sbrowser-settings'); await appearance('dark', 'separate'); await accent('violet'); await shot('sbrowser-theme-violet'); await appearance('light', 'separate'); await accent('blue'); await click('passwords'); await shot('sbrowser-vault'); await click('vault-close'); await appearance('light', 'compact'); window.setContentSize(800, 650); await delay(150); await shot('sbrowser-compact'); await click('tools-toggle'); await click('ai-toggle'); await shot('sbrowser-compact-panels'); await click('ai-close');window.setContentSize(480,740);await delay(120);await shot('sbrowser-narrow');window.setContentSize(800,650); await execute(`document.getElementById('address').value='https://example.test/slow';document.getElementById('address-form').requestSubmit();`); await click('new-tab'); await delay(300); assert.equal(await execute(`document.querySelector('.browser-tab.active .tab-label').textContent`), 'New Tab'); assert.equal(await execute(`document.getElementById('address').value`), ''); assert.equal(await execute(`document.getElementById('start-page').hidden`), false); const latestLayout=records.findLast(record=>record.method==='setChromeLayout');assert.ok(latestLayout.startPageOpen&&latestLayout.nativeHidden); for (const overlay of ['startPageOpen', 'overviewOpen', 'toolsOpen']) assert.ok(records.some(record => record.method === 'setChromeLayout' && record[overlay] && record.nativeHidden)); // Policy updates override stale or hostile renderer preferences immediately. state={...state,settings:{...state.settings,lockedSections:['appearance','ai','passwords','documentScan','agents'],appearance:{mode:'dark',accent:'violet',tabMode:'compact'}}}; window.webContents.send('showcase:state',state);await delay(120); await execute(`localStorage.setItem('sbrowser.theme','"light"');localStorage.setItem('sbrowser.accent','"blue"');window.dispatchEvent(new StorageEvent('storage',{key:'sbrowser.theme'}));`); assert.equal(await execute(`document.body.dataset.theme`),'dark'); assert.equal(await execute(`document.documentElement.dataset.accent`),'violet'); assert.equal(await execute(`['theme-mode','accent-mode','tab-mode','ai-toggle','passwords','inspect','agents'].every(id=>document.getElementById(id).disabled)`),true); assert.equal((await execute(`window.safetynet.updateSettings({mode:'light',accent:'blue',tabMode:'separate'})`)).ok,false); state={...state,settings:{...state.settings,lockedSections:[],hiddenSections:['appearance','ai','passwords','documentScan','agents'],visible:true}}; window.webContents.send('showcase:state',state);await delay(100); assert.equal(await execute(`['appearance-section','ai-toggle','sidebar','passwords','inspect','agents'].every(id=>document.getElementById(id).hidden)`),true); state={...state,settings:{...state.settings,visible:false}};window.webContents.send('showcase:state',state);await delay(100); assert.equal(await execute(`document.getElementById('tools-toggle').hidden&&document.getElementById('tools-menu').hidden`),true); state={...state,settings:{...state.settings,hiddenSections:['appearance']}};window.webContents.send('showcase:state',state);await delay(100); assert.equal(await execute(`!document.getElementById('quick-ai').hidden&&!document.getElementById('quick-ai').disabled&&document.getElementById('appearance-section').hidden`),true); await click('quick-ai');assert.equal(await execute(`document.getElementById('ai').hidden`),false);await click('ai-close'); await reloadShell();assert.equal(await execute(`document.getElementById('tools-toggle').hidden&&document.body.dataset.theme==='dark'`),true); await execute(`document.getElementById('error').textContent=''`); for (const control of ['window-minimize', 'window-maximize', 'window-close']) await click(control); assert.equal(records.filter(record => record.method === 'windowControls').length, 3); fs.writeFileSync(path.join(output, 'sbrowser-ui-layout.json'), JSON.stringify({ fixtureOnly: true, managedSettingsProof:{liveLocks:true,hiddenSections:true,globalHidden:true,localStorageCannotOverride:true,reloadPreservesPolicy:true,directUpdateRejected:true,globalHiddenPreservesApprovedFeatures:true},screenshots, records, consoleErrors }, null, 2)); assert.deepEqual(consoleErrors, []); finished = true; clearTimeout(watchdog); console.log('UI showcase passed: ten screenshots, live system themes, persisted accents, real DOM interactions and delayed-navigation regression.'); if(window.webContents.debugger.isAttached())window.webContents.debugger.detach(); window.destroy(); app.exit(0); }).catch(error => { clearTimeout(watchdog); console.error(error.message); if (!finished) app.exit(1); }); }