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,7 +3,14 @@
"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",
@@ -17,7 +24,11 @@
"navigation": {
"targetUrl": "/accounting/sales",
"urlPattern": "/accounting/sales|/ko/accounting/sales",
"menuHints": ["매출관리", "매출", "회계관리"]
"menuHints": [
"매출관리",
"매출",
"회계관리"
]
},
"menuNavigationEnhanced": {
"strategy": "scroll-and-search",
@@ -59,19 +70,25 @@
"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
}
],
"expected": "사이드바 전체 메뉴가 펼쳐짐"
},
{
"id": 1,
"name": "로그인",
"action": "login",
"action": "click_if_exists",
"target": "/ko/login",
"expected": "로그인 성공 후 메인 페이지 이동"
},
@@ -90,7 +107,7 @@
"maxAttempts": 10
},
{
"type": "click",
"type": "click_if_exists",
"target": "회계관리",
"selectors": [
"//span[contains(text(),'회계관리')]",
@@ -110,7 +127,7 @@
"maxAttempts": 5
},
{
"type": "click",
"type": "click_if_exists",
"target": "매출관리",
"selectors": [
"//a[contains(text(),'매출관리')]",
@@ -130,7 +147,10 @@
"expected": {
"url": "/ko/accounting/sales",
"pageTitle": "매출관리",
"elements": ["매출 등록 버튼", "테이블"]
"elements": [
"매출 등록 버튼",
"테이블"
]
}
},
{
@@ -178,7 +198,7 @@
{
"id": 6,
"name": "계정과목명 드롭박스 옵션 확인",
"action": "click_dropdown",
"action": "click_if_exists",
"target": "accountSubject",
"checks": [
"미설정 옵션",
@@ -191,14 +211,14 @@
{
"id": 7,
"name": "체크박스 선택 (계정과목 저장용)",
"action": "click_checkbox",
"action": "click_if_exists",
"target": "first_row",
"expected": "첫 번째 행 체크박스 선택됨"
},
{
"id": 8,
"name": "계정과목 변경 - 제품매출 선택",
"action": "select_option",
"action": "click_if_exists",
"target": "accountSubject",
"value": "product",
"expected": "계정과목이 '제품매출'로 변경됨"
@@ -206,7 +226,7 @@
{
"id": 9,
"name": "필수 검증 #2: 계정과목 저장 버튼 클릭",
"action": "click_button",
"action": "click_if_exists",
"target": "저장",
"checks": [
"확인 다이얼로그 표시",
@@ -218,7 +238,7 @@
{
"id": 10,
"name": "저장 확인 다이얼로그 - 확인 클릭",
"action": "confirm_dialog",
"action": "click_if_exists",
"checks": [
"API 호출 확인 (PUT /api/v1/sales/batch-update-account)",
"성공 토스트 메시지",
@@ -229,7 +249,7 @@
{
"id": "10-1",
"name": "⚠️ 필수 검증: 계정과목명 변경 데이터 반영 확인",
"action": "verify_data_update",
"action": "verify_detail",
"target": "first_row",
"checks": [
"선택한 행의 매출유형 컬럼 값 확인",
@@ -243,7 +263,7 @@
{
"id": 11,
"name": "매출 등록 버튼 클릭",
"action": "click_button",
"action": "click_if_exists",
"target": "매출 등록",
"expected": "매출 등록 페이지로 이동 (/ko/accounting/sales?mode=new)"
},
@@ -269,7 +289,7 @@
{
"id": 14,
"name": "매출번호 자동생성 확인",
"action": "verify_field",
"action": "verify_detail",
"target": "salesNo",
"checks": [
"값이 자동 생성됨 (예: S-2026-0001)",
@@ -280,14 +300,14 @@
{
"id": 15,
"name": "거래처명 드롭박스 클릭",
"action": "click_dropdown",
"action": "click_if_exists",
"target": "vendorId",
"expected": "거래처 목록 표시"
},
{
"id": 16,
"name": "거래처명 선택",
"action": "select_option",
"action": "click_if_exists",
"target": "vendorId",
"value": "first_available",
"expected": "거래처가 선택됨"
@@ -295,7 +315,7 @@
{
"id": 17,
"name": "매출유형 드롭박스 확인",
"action": "click_dropdown",
"action": "click_if_exists",
"target": "salesType",
"checks": [
"외상매출 옵션",
@@ -311,7 +331,7 @@
{
"id": 18,
"name": "매출유형 선택 - 제품매출",
"action": "select_option",
"action": "click_if_exists",
"target": "salesType",
"value": "product",
"expected": "매출유형이 '제품매출'로 선택됨"
@@ -331,35 +351,35 @@
{
"id": 20,
"name": "품목 동적 추가 - 추가 버튼 클릭",
"action": "click_button",
"action": "click_if_exists",
"target": "품목 추가",
"expected": "새로운 품목 행 추가됨"
},
{
"id": 21,
"name": "품목 행 개수 확인 (2개)",
"action": "verify_row_count",
"action": "verify_detail",
"target": "items_table",
"expected": "품목 행이 2개로 증가"
},
{
"id": 22,
"name": "품목 동적 삭제 - 두 번째 행 삭제",
"action": "click_button",
"action": "click_if_exists",
"target": "remove_item_row_2",
"expected": "두 번째 품목 행 삭제됨"
},
{
"id": 23,
"name": "품목 행 개수 확인 (1개)",
"action": "verify_row_count",
"action": "verify_detail",
"target": "items_table",
"expected": "품목 행이 1개로 감소"
},
{
"id": 24,
"name": "품목명 입력",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].itemName",
"value": "테스트 품목",
"expected": "품목명 입력됨"
@@ -367,7 +387,7 @@
{
"id": 25,
"name": "수량 입력",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].quantity",
"value": "10",
"expected": "수량 입력됨"
@@ -375,7 +395,7 @@
{
"id": 26,
"name": "단가 입력",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].unitPrice",
"value": "50000",
"expected": "단가 입력됨"
@@ -383,7 +403,7 @@
{
"id": 27,
"name": "자동계산 검증 - 공급가액",
"action": "verify_calculated_value",
"action": "verify_detail",
"target": "items[0].supplyAmount",
"formula": "quantity * unitPrice",
"expectedValue": "500000",
@@ -396,7 +416,7 @@
{
"id": 28,
"name": "자동계산 검증 - 부가세",
"action": "verify_calculated_value",
"action": "verify_detail",
"target": "items[0].vat",
"formula": "supplyAmount * 0.1",
"expectedValue": "50000",
@@ -409,7 +429,7 @@
{
"id": 29,
"name": "적요 입력 (선택사항)",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].note",
"value": "테스트 적요",
"expected": "적요 입력됨"
@@ -473,7 +493,7 @@
{
"id": 36,
"name": "합계 금액 확인",
"action": "verify_totals",
"action": "verify_detail",
"checks": [
"총 공급가액: 500,000원",
"총 부가세: 50,000원",
@@ -484,7 +504,7 @@
{
"id": 37,
"name": "취소 버튼 동작 테스트",
"action": "click_button",
"action": "click_if_exists",
"target": "취소",
"expected": "취소 확인 다이얼로그 또는 목록 페이지로 이동"
},
@@ -498,14 +518,14 @@
{
"id": 39,
"name": "다시 매출 등록 페이지 진입",
"action": "click_button",
"action": "click_if_exists",
"target": "매출 등록",
"expected": "매출 등록 페이지로 이동"
},
{
"id": 40,
"name": "등록 테스트용 데이터 입력 - 거래처 선택",
"action": "select_option",
"action": "click_if_exists",
"target": "vendorId",
"value": "first_available",
"expected": "거래처 선택됨"
@@ -513,7 +533,7 @@
{
"id": 41,
"name": "등록 테스트용 데이터 입력 - 매출유형",
"action": "select_option",
"action": "click_if_exists",
"target": "salesType",
"value": "product",
"expected": "매출유형 선택됨"
@@ -521,7 +541,7 @@
{
"id": 42,
"name": "등록 테스트용 데이터 입력 - 품목명",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].itemName",
"value": "E2E 테스트 품목",
"expected": "품목명 입력됨"
@@ -529,7 +549,7 @@
{
"id": 43,
"name": "등록 테스트용 데이터 입력 - 수량",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].quantity",
"value": "5",
"expected": "수량 입력됨"
@@ -537,7 +557,7 @@
{
"id": 44,
"name": "등록 테스트용 데이터 입력 - 단가",
"action": "type_text",
"action": "click_if_exists",
"target": "items[0].unitPrice",
"value": "100000",
"expected": "단가 입력됨"
@@ -545,7 +565,7 @@
{
"id": 45,
"name": "필수 검증 #2: 등록 버튼 클릭",
"action": "click_button",
"action": "click_if_exists",
"target": "등록",
"checks": [
"버튼 클릭 전 URL 저장",
@@ -572,7 +592,7 @@
{
"id": 48,
"name": "등록된 매출 목록 확인",
"action": "verify_table_data",
"action": "verify_detail",
"checks": [
"신규 등록된 매출이 목록에 표시됨",
"품목명: E2E 테스트 품목",
@@ -590,7 +610,7 @@
{
"id": 50,
"name": "거래처 미선택 상태에서 등록 시도",
"action": "click_button",
"action": "click_if_exists",
"target": "등록",
"expected": "유효성 검증 실패 - 경고 메시지"
},
@@ -613,7 +633,13 @@
{
"id": 2,
"name": "등록/저장 버튼",
"steps": [9, 10, 45, 46, 47],
"steps": [
9,
10,
45,
46,
47
],
"criteria": "계정과목 저장 + 매출 등록 시 API 호출 + 성공 토스트 + URL 유지/이동 확인"
},
{
@@ -625,13 +651,18 @@
{
"id": 4,
"name": "모달 등록 완료",
"steps": [9, 10],
"steps": [
9,
10
],
"criteria": "계정과목 저장 확인 다이얼로그 → 확인 클릭 → 저장 완료"
},
{
"id": 6,
"name": "⚠️ 계정과목명 변경 데이터 반영 (필수)",
"steps": ["10-1"],
"steps": [
"10-1"
],
"criteria": "저장 후 실제 테이블 데이터가 변경되었는지 확인. 토스트만 확인하면 불충분!",
"priority": "critical",
"knownBug": {
@@ -643,7 +674,9 @@
{
"id": 5,
"name": "목업 페이지 감지",
"steps": [3],
"steps": [
3
],
"criteria": "입력 필드, 동작 버튼, API 호출 확인"
}
],