8 lines
4.4 KiB
JavaScript
8 lines
4.4 KiB
JavaScript
import fs from 'node:fs';import path from 'node:path';import assert from 'node:assert/strict';import {mountRequestHistory} from '../public/request-history.mjs';
|
|
const tag=process.argv[2];assert(/^[a-f0-9]{12}$/.test(tag??''));const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),root=path.join(run.root,'private/receipt-composition-'+tag),out=path.join(root,'request-history-ui.json');assert(!fs.existsSync(out));const checks=[],ok=(v,name)=>{assert(v,name);checks.push(name);};
|
|
class Element{constructor(tag,text){this.tag=tag;this.textContent=text??'';this.children=[];this.value='';}append(...nodes){this.children.push(...nodes);}replaceChildren(...nodes){this.children=[...nodes];}}
|
|
globalThis.document={createElement:tag=>new Element(tag)};globalThis.Option=class extends Element{constructor(text,value){super('option',text);this.value=value;}};const walk=node=>[node,...node.children.flatMap(walk)],button=(node,text)=>walk(node).find(e=>e.tag==='button'&&e.textContent===text),entry=id=>({id,created_at:'2026-11-03',action:'requisition.qa_history',user_id:1,before:{note:id-1},after:{note:id}}),nav=(next=null,previous=null)=>({next,previous,per_page:25}),tick=()=>new Promise(resolve=>setTimeout(resolve,0));
|
|
const container=new Element('history'),form=new Element('form'),draft=new Element('input');draft.value='alteração ainda não gravada';form.append(draft);let calls=[],message='';const api=async(...args)=>{calls.push(args);return {data:[entry(2)],navigation:nav(null,'newer-token')};};mountRequestHistory({id:3,records:[entry(1)],navigation:nav('older+/token'),container,api,active:()=>true,message:text=>message=text});ok(calls.length===0&&Boolean(button(container,'Mais antigos'))&&!button(container,'Mais recentes'),'initial own-stage page is reused without another request');await button(container,'Mais antigos').onclick();let url=new URL('http://qa'+calls.at(-1)[0]);ok(url.pathname==='/3/history'&&url.searchParams.get('cursor')==='older+/token'&&url.searchParams.get('per_page')==='25','older navigation encodes opaque cursor and current size');ok(!button(container,'Mais antigos')&&Boolean(button(container,'Mais recentes')),'final page exposes only valid newer direction');await button(container,'Mais recentes').onclick();ok(new URL('http://qa'+calls.at(-1)[0]).searchParams.get('cursor')==='newer-token','newer direction sends server-issued previous cursor');let select=walk(container).find(e=>e.name==='history_size');select.value='100';select.onchange();await tick();url=new URL('http://qa'+calls.at(-1)[0]);ok(url.searchParams.get('per_page')==='100'&&!url.searchParams.has('cursor'),'page-size change begins new bounded consultation');await button(container,'Actualizar histórico').onclick();ok(!new URL('http://qa'+calls.at(-1)[0]).searchParams.has('cursor')&&draft.value==='alteração ainda não gravada'&&form.children[0]===draft,'history refresh preserves separate unsaved request form');ok(calls.every(args=>args.length===1),'history component calls read API without a command payload');
|
|
const pending=[],race=new Element('history');let active=true;mountRequestHistory({id:4,records:[entry(10)],navigation:nav('cursor'),container:race,api:path=>new Promise((resolve,reject)=>pending.push({path,resolve,reject})),active:()=>active,message:text=>message=text});const old=button(race,'Mais antigos').onclick(),latest=button(race,'Mais antigos').onclick();pending[1].resolve({data:[entry(22)],navigation:nav()});await latest;pending[0].resolve({data:[entry(11)],navigation:nav()});await old;ok(walk(race).some(e=>e.tag==='pre'&&e.textContent.includes('22'))&&!walk(race).some(e=>e.tag==='pre'&&e.textContent.includes('11')),'late older response cannot replace newer history response');const detached=button(race,'Actualizar histórico').onclick();active=false;pending[2].resolve({data:[entry(99)],navigation:nav()});await detached;ok(!walk(race).some(e=>e.tag==='pre'&&e.textContent.includes('99')),'changed record or detached history drops late response');active=true;const failed=button(race,'Actualizar histórico').onclick();pending[3].reject(Error('Cursor expirado'));await failed;ok(message.includes('Cursor expirado')&&message.includes('Actualizar')&&Boolean(button(race,'Actualizar histórico')),'expired or refused cursor offers explicit safe refresh');
|
|
fs.writeFileSync(out,JSON.stringify({passed:true,checks,dom_simulation:true,business_commands:0,visual_review:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length}));
|