// Actual UI client over actual HTTP. Only previews (rolled back) are allowed to POST. import fs from 'node:fs';import assert from 'node:assert/strict';import {parsePage,installDom} from './purchasing-workspace-dom.mjs';import {session} from './sgf-single-http.mjs'; const nativeFetch=globalThis.fetch,s=await session('sgf:finance_prepare','finance');let r=await s.get('/finance/indicators',{headers:{Accept:'text/html'}});assert.equal(r.status,200);const document=parsePage(await r.text());installDom(document);document.getElementById=id=>document.querySelector('#'+id);globalThis.window={addEventListener(){}};const $=id=>document.getElementById(id);let previews=0,confirms=0;const calls=[],checks=[];const ok=(v,n)=>{assert(v,n);checks.push(n);};globalThis.fetch=async(url,options={})=>{if(url.startsWith('http:'))return nativeFetch(url,options);calls.push(url);if(options.method==='POST'){if(url.endsWith('/confirm')){confirms++;throw Error('No indicator confirmations in UI proof');}assert(url.endsWith('/preview'));previews++;const a=await s.command(url,JSON.parse(options.body),options.headers['Idempotency-Key']);return{status:a.status,json:async()=>a.value};}const a=await s.get(url);return{status:a.status,json:()=>a.json()};}; await import('../public/sgf-indicators.mjs?dom-http');const wait=async f=>{const end=Date.now()+15000;while(!f()&&Date.now()setTimeout(r,25));assert(f(),$('message').textContent);};await wait(()=>$('events').children.length===2);ok($('selection').textContent.includes('Nenhuma versão'),'no first criterion auto-selected');ok($('summary').textContent.includes('950.00')&&$('summary').textContent.includes('100.00')&&$('summary').textContent.includes('50.00')&&$('summary').textContent.includes('1000.00'),'actual source amounts visible');ok($('summary').textContent.includes('fontes efectivas conciliadas'),'actual source kind visible');await $('events').children[0].querySelector('button').onclick();ok($('selection').textContent.includes('Despesa/entradas'),'explicit expense criterion selected');$('action').value='calculate';$('action').onchange();$('asOf').value='2026-11-10';$('reason').value='Ensaio UI QA com critério escolhido e fonte real do exercício; não confirmar.';$('operation').oninput();await $('operation').onsubmit({preventDefault(){}});ok(previews===1&&confirms===0,'actual rollback preview no confirmation');ok($('impact').textContent.includes('5.00 %')&&$('impact').textContent.includes('1/20'),'exact fraction and percent shown before commit');ok($('impact').textContent.includes('Série anterior/tendência: Indeterminadas'),'no fake prior comparison');ok($('fields').disabled&&$('filters').disabled,'preview locks form and catalogue');$('cancel').onclick();ok(!$('fields').disabled&&$('asOf').value==='2026-11-10','cancel keeps unsubmitted date');$('size').value='100';$('apply').onclick();await wait(()=>$('filters').disabled===false&&calls.some(c=>c.includes('per_page=100')));ok($('asOf').value==='2026-11-10'&&$('reason').value.includes('não confirmar'),'pagination preserves unsubmitted inputs'); $('view').value='results';$('apply').onclick();await wait(()=>$('events').children.length===2&&$('events').textContent.includes('Resultado'));await $('events').children[0].querySelector('button').onclick();ok($('detail').textContent.includes('source_snapshot')&&$('detail').textContent.includes('5.00'),'historical result retains source and value');ok($('inputs').textContent.includes('Sem critério escolhido'),'historical result does not adopt its criterion');ok($('download').querySelector('a').href.endsWith('/report'),'historical report offered');const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),root=run.root+'/private/receipt-composition-cc50a276c10c',p=JSON.parse(fs.readFileSync(root+'/analysis-http-20261110.json'));$('referenceKey').value=p.operations['calculate-coverage'].key;await $('recovery').onsubmit({preventDefault(){}});ok($('receipt').textContent.includes('Nenhuma operação repetida'),'own historical receipt recovered by GET');r=await s.get('/api/financial-indicators?view=results');ok((await r.json()).records.total===2&&confirms===0,'two saved results unchanged');r=await s.get('/api/bank-reconciliation');const bank=await r.json();ok(bank.finalized&&bank.history.total===7,'bank conference7events remains finalized');const file=root+'/analysis-dom-http-20261110.json';fs.writeFileSync(file,JSON.stringify({passed:true,checks,preview_posts:previews,confirmation_posts:confirms,real_http_forwarded:true,browser_visual_review:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof:file}));