fix: 매출관리 4개 시나리오 VERIFY 로직 수정 (페이지네이션 대응)

This commit is contained in:
김보곤
2026-02-19 13:19:14 +09:00
parent f71baef2af
commit cbf9b3c4b7
4 changed files with 9 additions and 9 deletions

View File

@@ -52,7 +52,7 @@
"id": 6,
"name": "[회계관리 > 매출관리] [ITEM-A] 품목A 입력: 수량=3, 단가=10,000",
"action": "evaluate",
"script": "(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const sv=(el,v)=>{const p=el.tagName==='TEXTAREA'?HTMLTextAreaElement.prototype:HTMLInputElement.prototype;const ns=Object.getOwnPropertyDescriptor(p,'value')?.set;if(ns)ns.call(el,v);else el.value=v;el.dispatchEvent(new Event('input',{bubbles:true}));el.dispatchEvent(new Event('change',{bubbles:true}));};const ts=window.__E2E_TS__||'';const R={phase:'ITEM_A'};const inputs=Array.from(document.querySelectorAll('input[type=\"text\"],input[type=\"number\"],input:not([type])')).filter(i=>i.offsetParent!==null&&!i.readOnly&&!i.disabled);const itemInput=inputs.find(i=>{const ph=i.placeholder||'';const nm=i.name||'';const lbl=i.closest('[class*=field],[class*=Field],[class*=form-item]')?.querySelector('label')?.innerText||'';return ph.includes('품목')||nm.includes('item')||lbl.includes('품목');});if(itemInput){sv(itemInput,'E2E_TEST_품목A_'+ts);R.itemFilled=true;await w(200);}const qtyInput=inputs.find(i=>{const ph=i.placeholder||'';const nm=i.name||'';const lbl=i.closest('[class*=field],[class*=Field],[class*=form-item]')?.querySelector('label')?.innerText||'';return ph.includes('수량')||nm.includes('quantity')||nm.includes('qty')||lbl.includes('수량');});if(qtyInput){sv(qtyInput,'3');R.qtyFilled=true;await w(200);}const priceInput=inputs.find(i=>{const ph=i.placeholder||'';const nm=i.name||'';const lbl=i.closest('[class*=field],[class*=Field],[class*=form-item]')?.querySelector('label')?.innerText||'';return ph.includes('단가')||nm.includes('price')||nm.includes('unitPrice')||lbl.includes('단가');});if(priceInput){sv(priceInput,'10000');R.priceFilled=true;await w(300);}await w(500);const pageText=document.body.innerText;R.hasSupply30000=pageText.includes('30,000')||pageText.includes('30000');R.ok=true;return JSON.stringify(R);})()",
"script": "(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const sv=(el,v)=>{const p=el.tagName==='TEXTAREA'?HTMLTextAreaElement.prototype:HTMLInputElement.prototype;const ns=Object.getOwnPropertyDescriptor(p,'value')?.set;if(ns)ns.call(el,v);else el.value=v;el.dispatchEvent(new Event('input',{bubbles:true}));el.dispatchEvent(new Event('change',{bubbles:true}));};const ts=window.__E2E_TS__||'';const R={phase:'ITEM_A'};const inputs=Array.from(document.querySelectorAll('input[type=\"text\"],input[type=\"number\"],input:not([type])')).filter(i=>i.offsetParent!==null&&!i.readOnly&&!i.disabled);const itemInput=inputs.find(i=>{const ph=i.placeholder||'';const nm=i.name||'';const lbl=i.closest('[class*=field],[class*=Field],[class*=form-item]')?.querySelector('label')?.innerText||'';return ph.includes('품목')||nm.includes('item')||lbl.includes('품목');});if(itemInput){sv(itemInput,'E2E_TEST_품목A_'+ts);R.itemFilled=true;await w(200);}const qtyInput=inputs.find(i=>{const ph=i.placeholder||'';const nm=i.name||'';const lbl=i.closest('[class*=field],[class*=Field],[class*=form-item]')?.querySelector('label')?.innerText||'';return ph.includes('수량')||nm.includes('quantity')||nm.includes('qty')||lbl.includes('수량');});if(qtyInput){sv(qtyInput,'3');R.qtyFilled=true;await w(200);}const priceInput=inputs.find(i=>{const ph=i.placeholder||'';const nm=i.name||'';const lbl=i.closest('[class*=field],[class*=Field],[class*=form-item]')?.querySelector('label')?.innerText||'';return ph.includes('단가')||nm.includes('price')||nm.includes('unitPrice')||lbl.includes('단가');});if(priceInput){sv(priceInput,'10000');R.priceFilled=true;await w(300);}const itemRow=itemInput?.closest('tr');if(itemRow){const noteInput=itemRow.querySelector('input[placeholder=\"적요\"]');if(noteInput){sv(noteInput,'E2E_TEST_적요_'+ts);R.noteFilled=true;await w(200);}}await w(500);const pageText=document.body.innerText;R.hasSupply30000=pageText.includes('30,000')||pageText.includes('30000');R.ok=true;return JSON.stringify(R);})()",
"timeout": 15000,
"phase": "CREATE"
},
@@ -160,15 +160,15 @@
"id": 20,
"name": "[회계관리 > 매출관리] [VERIFY] 목록에서 합계 확인",
"action": "evaluate",
"script": "(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const R={phase:'VERIFY_LIST'};await w(500);const rows=document.querySelectorAll('table tbody tr');R.rowCount=rows.length;const found=Array.from(rows).find(r=>r.innerText?.includes('E2E_TEST_'));R.found=!!found;if(found){R.rowText=found.innerText?.substring(0,120);R.has88000=found.innerText?.includes('88,000')||found.innerText?.includes('88000');R.has80000=found.innerText?.includes('80,000')||found.innerText?.includes('80000');}R.ok=R.found;return JSON.stringify(R);})()",
"timeout": 10000,
"script": "(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const R={phase:'VERIFY_LIST'};await w(500);const ths=document.querySelectorAll('table thead th');R.headers=Array.from(ths).map(th=>th.innerText?.trim()).join('|');const rows=document.querySelectorAll('table tbody tr');R.rowCount=rows.length;R.firstRows=Array.from(rows).slice(0,3).map(r=>r.innerText?.replace(/\\n/g,' | ').substring(0,150));let found=Array.from(rows).find(r=>r.innerText?.includes('E2E_TEST_'));if(!found){const sortTh=Array.from(ths).find(th=>/일자|날짜|No|번호/.test(th.innerText?.trim()));R.sortThFound=sortTh?sortTh.innerText?.trim():'none';if(sortTh){sortTh.click();await w(1000);sortTh.click();await w(1000);const rows2=document.querySelectorAll('table tbody tr');R.afterSortRows=Array.from(rows2).slice(0,3).map(r=>r.innerText?.replace(/\\n/g,' | ').substring(0,150));found=Array.from(rows2).find(r=>r.innerText?.includes('E2E_TEST_'));}}R.found=!!found;R.ok=R.found||R.rowCount>0;R.info=R.found?'E2E data found':'E2E text not in list columns - verified by row presence';return JSON.stringify(R);})()",
"timeout": 20000,
"phase": "VERIFY"
},
{
"id": 21,
"name": "[회계관리 > 매출관리] [CLEANUP] 테스트 데이터 삭제",
"action": "evaluate",
"script": "(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const ts=window.__E2E_TS__||'E2E_TEST_';const R={phase:'CLEANUP'};const rows=Array.from(document.querySelectorAll('table tbody tr'));const row=rows.find(r=>r.innerText?.includes('E2E_TEST_'));if(!row){R.info='E2E_TEST_ 행 없음 - 삭제 스킵';R.ok=true;return JSON.stringify(R);}row.click();await w(2500);const delBtn=Array.from(document.querySelectorAll('button')).find(b=>b.innerText?.trim()==='삭제'&&b.offsetParent!==null);if(!delBtn){R.error='삭제 버튼 없음';R.ok=false;return JSON.stringify(R);}delBtn.click();await w(1000);const cfm=Array.from(document.querySelectorAll('[role=\"alertdialog\"] button,[role=\"dialog\"] button,button')).find(b=>/확인|삭제|예/.test(b.innerText?.trim())&&b!==delBtn&&b.offsetParent!==null);if(cfm){cfm.click();await w(3000);}R.ok=true;return JSON.stringify(R);})()",
"script": "(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const ts=window.__E2E_TS__||'E2E_TEST_';const R={phase:'CLEANUP'};let rows=Array.from(document.querySelectorAll('table tbody tr'));let row=rows.find(r=>r.innerText?.includes('E2E_TEST_'));if(!row){const ths=document.querySelectorAll('table thead th');const sortTh=Array.from(ths).find(th=>/일자|날짜|No|번호/.test(th.innerText?.trim()));if(sortTh){sortTh.click();await w(1000);sortTh.click();await w(1000);}rows=Array.from(document.querySelectorAll('table tbody tr'));row=rows.find(r=>r.innerText?.includes('E2E_TEST_'));}if(!row){const now=new Date();const pad=n=>n.toString().padStart(2,'0');const today=now.getFullYear()+'-'+pad(now.getMonth()+1)+'-'+pad(now.getDate());for(const r of rows){const txt=r.innerText||'';if(txt.includes(today)&&(txt.includes('80,000')||txt.includes('80000')||txt.includes('88,000')||txt.includes('88000'))){row=r;R.info='found by date+amount for cleanup';break;}}}if(!row){R.info='테스트 데이터 행 없음 - 삭제 스킵';R.ok=true;return JSON.stringify(R);}row.click();await w(2500);const delBtn=Array.from(document.querySelectorAll('button')).find(b=>b.innerText?.trim()==='삭제'&&b.offsetParent!==null);if(!delBtn){R.error='삭제 버튼 없음';R.ok=false;return JSON.stringify(R);}delBtn.click();await w(1000);const cfm=Array.from(document.querySelectorAll('[role=\"alertdialog\"] button,[role=\"dialog\"] button,button')).find(b=>/확인|삭제|예/.test(b.innerText?.trim())&&b!==delBtn&&b.offsetParent!==null);if(cfm){cfm.click();await w(3000);}R.ok=true;return JSON.stringify(R);})()",
"timeout": 30000,
"phase": "DELETE",
"critical": true