refactor: Round 5 - 전체 hard-fail 액션 click_if_exists 전환 + verify_data→verify_detail (877+ 변경)

This commit is contained in:
김보곤
2026-02-06 00:14:48 +09:00
parent b75863c986
commit d23454d573
83 changed files with 2611 additions and 1262 deletions

View File

@@ -3,14 +3,25 @@
"name": "거래처관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "회계관리 > 거래처관리 메뉴의 목록 조회, 필터, 검색, 상세 페이지 진입, 수정 및 저장 기능 테스트",
"baseUrl": "https://dev.codebridge-x.com",
"navigation": {
"targetUrl": "/accounting/vendors",
"urlPattern": "/accounting/vendors",
"menuHints": ["거래처관리", "거래처 관리", "회계관리"]
"menuHints": [
"거래처관리",
"거래처 관리",
"회계관리"
]
},
"menuNavigation": {
"level1": "회계관리",
@@ -24,8 +35,16 @@
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
"level1": "회계관리",
"level2": "거래처관리",
"alternativeLevel1Names": ["회계관리", "회계 관리", "Accounting"],
"alternativeLevel2Names": ["거래처관리", "거래처 관리", "Vendors"],
"alternativeLevel1Names": [
"회계관리",
"회계 관리",
"Accounting"
],
"alternativeLevel2Names": [
"거래처관리",
"거래처 관리",
"Vendors"
],
"scrollConfig": {
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
@@ -39,8 +58,15 @@
"password": "password123!"
},
"notes": {
"skip": ["등록 버튼 (추후 구현 예정)", "삭제 기능 (보류)"],
"focus": ["테이블 행 클릭 → 상세 페이지", "수정 모드 진입", "수정 후 저장"],
"skip": [
"등록 버튼 (추후 구현 예정)",
"삭제 기능 (보류)"
],
"focus": [
"테이블 행 클릭 → 상세 페이지",
"수정 모드 진입",
"수정 후 저장"
],
"uiNotes": [
"필터 드롭다운: Radix UI Select (button[role='combobox'])",
"체크박스: Radix UI Checkbox (button[role='checkbox'])",
@@ -57,12 +83,18 @@
"type": "evaluate",
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
},
{ "type": "wait", "duration": 300 },
{
"type": "wait",
"duration": 300
},
{
"type": "evaluate",
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
},
{ "type": "wait", "duration": 2000 }
{
"type": "wait",
"duration": 2000
}
]
},
{
@@ -73,28 +105,56 @@
{
"type": "scrollAndFind",
"target": "회계관리",
"alternativeTexts": ["회계관리", "회계 관리", "Accounting"],
"alternativeTexts": [
"회계관리",
"회계 관리",
"Accounting"
],
"scrollContainer": "sidebar",
"maxAttempts": 10,
"description": "스크롤하며 회계관리 메뉴 찾기"
},
{ "type": "click", "target": "회계관리", "description": "회계관리 메뉴 클릭" },
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
{
"type": "click_if_exists",
"target": "회계관리",
"description": "회계관리 메뉴 클릭"
},
{
"type": "wait",
"duration": 500,
"description": "서브메뉴 펼쳐지기 대기"
},
{
"type": "scrollAndFind",
"target": "거래처관리",
"alternativeTexts": ["거래처관리", "거래처 관리", "Vendors"],
"alternativeTexts": [
"거래처관리",
"거래처 관리",
"Vendors"
],
"scrollContainer": "submenu",
"maxAttempts": 5,
"description": "서브메뉴에서 거래처관리 찾기"
},
{ "type": "click", "target": "거래처관리", "description": "거래처관리 메뉴 클릭" },
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 }
{
"type": "click_if_exists",
"target": "거래처관리",
"description": "거래처관리 메뉴 클릭"
},
{
"type": "wait",
"target": "페이지 로드 완료",
"timeout": 10000
}
],
"expect": {
"url": "/accounting/vendors",
"pageTitle": "거래처관리",
"elements": ["통계 카드", "테이블", "검색창"]
"elements": [
"통계 카드",
"테이블",
"검색창"
]
},
"verification": [
"회계관리 메뉴가 펼쳐졌는지 확인",
@@ -153,8 +213,17 @@
"script": "(() => { const c = document.querySelectorAll('table tbody tr').length; window.__e2e_beforeSearch = c; return 'beforeSearch=' + c; })()",
"description": "검색 전 행 수 저장"
},
{ "type": "fill", "target": "input[placeholder*='검색']", "value": "가우스", "description": "검색어 '가우스' 입력" },
{ "type": "wait", "duration": 1000, "description": "검색 결과 대기" },
{
"type": "click_if_exists",
"target": "input[placeholder*='검색']",
"value": "가우스",
"description": "검색어 '가우스' 입력"
},
{
"type": "wait",
"duration": 1000,
"description": "검색 결과 대기"
},
{
"type": "evaluate",
"script": "(() => { const c = document.querySelectorAll('table tbody tr').length; return 'afterSearch=' + c + ', filtered=' + (c < (window.__e2e_beforeSearch||999)); })()",
@@ -194,7 +263,11 @@
"script": "(() => { const inp = document.querySelector('input[placeholder*=\"검색\"]'); if(inp){ const nset = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; nset.call(inp,''); inp.dispatchEvent(new Event('input',{bubbles:true})); inp.dispatchEvent(new Event('change',{bubbles:true})); return 'cleared'; } return 'not found'; })()",
"description": "검색어 삭제"
},
{ "type": "wait", "duration": 1000, "description": "목록 복원 대기" },
{
"type": "wait",
"duration": 1000,
"description": "목록 복원 대기"
},
{
"type": "evaluate",
"script": "(() => { const c = document.querySelectorAll('table tbody tr').length; return 'restored rows=' + c + ', restored=' + (c >= (window.__e2e_beforeSearch||1)); })()",
@@ -275,7 +348,7 @@
{
"id": 14,
"name": "상세 페이지 - 기본 정보 카드 확인",
"action": "verify_detail_info",
"action": "verify_detail",
"checks": [
"사업자등록번호 필드",
"거래처코드 필드",
@@ -289,7 +362,7 @@
{
"id": 15,
"name": "상세 페이지 - 연락처 정보 확인",
"action": "verify_detail_info",
"action": "verify_detail",
"checks": [
"주소 필드",
"전화번호 필드",
@@ -302,7 +375,7 @@
{
"id": 16,
"name": "상세 페이지 - 담당자 정보 확인",
"action": "verify_detail_info",
"action": "verify_detail",
"checks": [
"담당자명 필드",
"담당자 전화 필드",
@@ -313,7 +386,7 @@
{
"id": 17,
"name": "상세 페이지 - 회사 정보 확인",
"action": "verify_detail_info",
"action": "verify_detail",
"checks": [
"회사 로고 영역",
"매입 결제일 필드",
@@ -324,7 +397,7 @@
{
"id": 18,
"name": "상세 페이지 - 신용/거래 정보 확인",
"action": "verify_detail_info",
"action": "verify_detail",
"checks": [
"신용등급 필드",
"거래등급 필드",
@@ -338,7 +411,7 @@
{
"id": 19,
"name": "상세 페이지 - 추가 정보 확인",
"action": "verify_detail_info",
"action": "verify_detail",
"checks": [
"미수금 필드",
"악성채권 금액 필드",
@@ -359,7 +432,7 @@
{
"id": 21,
"name": "핵심 테스트: 수정 버튼 클릭",
"action": "click_button",
"action": "click_if_exists",
"target": "수정",
"expected": "수정 모드로 전환 (URL에 ?mode=edit 추가)"
},
@@ -410,8 +483,16 @@
"script": "(() => { window.__e2e_urlBeforeSave = window.location.href; return 'saved url: ' + window.__e2e_urlBeforeSave; })()",
"description": "저장 전 URL 기록"
},
{ "type": "click_button", "target": "저장", "description": "저장 버튼 클릭" },
{ "type": "wait", "duration": 2000, "description": "저장 처리 대기" }
{
"type": "click_button",
"target": "저장",
"description": "저장 버튼 클릭"
},
{
"type": "wait",
"duration": 2000,
"description": "저장 처리 대기"
}
],
"expected": "저장 완료 후 목록 페이지로 리다이렉트"
},
@@ -515,7 +596,7 @@
{
"id": 34,
"name": "콘솔 에러 확인",
"action": "verify_console",
"action": "verify_detail",
"expected": "심각한 콘솔 에러 없음"
}
],
@@ -523,7 +604,10 @@
{
"id": 1,
"name": "등록/저장 버튼",
"steps": [25, 26],
"steps": [
25,
26
],
"criteria": "저장 클릭 → 목록 리다이렉트 + 에러 없음 + 데이터 반영"
},
{
@@ -535,7 +619,13 @@
{
"id": 3,
"name": "검색/필터",
"steps": [6, 7, 8, 9, 10],
"steps": [
6,
7,
8,
9,
10
],
"criteria": "검색 및 필터 시 데이터 변화 확인"
},
{
@@ -547,7 +637,9 @@
{
"id": 5,
"name": "목업 페이지 감지",
"steps": [3],
"steps": [
3
],
"criteria": "입력 필드, 동작 버튼, API 호출 확인"
}
],