Files
sam-scenarios/crud-delete-vendor.json

667 lines
18 KiB
JSON

{
"id": "crud-delete-vendor",
"name": "거래처 CRUD 삭제 기능 테스트",
"status": "BLOCKED",
"blockedReason": "거래처관리 페이지에 등록 버튼이 없음 - CREATE 단계 불가",
"discoveredOn": "2026-01-29",
"alternative": "crud-delete-freeboard.json 사용 (자유게시판 CRUD 테스트)",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "거래처관리에서 생성 → 수정 → 삭제 전체 CRUD 흐름 테스트. 테스트용 데이터를 생성하고, 수정한 후, 삭제하여 기존 데이터에 영향 없이 삭제 기능을 검증",
"baseUrl": "https://dev.codebridge-x.com",
"menuNavigation": {
"level1": "회계관리",
"level2": "거래처관리",
"expectedUrl": "/ko/accounting/vendors"
},
"auth": {
"username": "TestUser5",
"password": "password123!"
},
"testPolicy": {
"deleteAllowed": true,
"deleteCondition": "CRUD 흐름 내에서만 허용 (생성 → 수정 → 삭제)",
"protectExistingData": true,
"description": "이 시나리오에서 생성한 테스트 데이터만 삭제"
},
"modalHandling": {
"description": "모달 창 처리 규칙",
"closeMethods": [
{
"priority": 1,
"method": "완료 버튼",
"selector": "button:has-text('확인'), button:has-text('등록'), button:has-text('저장')"
},
{
"priority": 2,
"method": "취소 버튼",
"selector": "button:has-text('취소'), [class*='cancel']"
},
{
"priority": 3,
"method": "X 버튼",
"selector": "button[class*='close'], [aria-label='닫기'], [aria-label='Close']"
},
{
"priority": 4,
"method": "ESC 키",
"action": "press_key",
"value": "Escape"
},
{
"priority": 5,
"method": "외부 클릭",
"selector": "[class*='backdrop'], [class*='overlay']"
}
],
"rule": "모달이 열린 상태로 다음 단계 진행 금지"
},
"testData": {
"newVendor": {
"vendorName": "E2E테스트_삭제용_",
"businessNumber": "123-45-67890",
"representative": "테스트대표",
"vendorType": "매출",
"phone": "02-1234-5678",
"email": "test@e2etest.com",
"address": "서울시 테스트구 테스트동 123"
},
"updateData": {
"vendorName": "E2E테스트_수정완료_",
"representative": "수정대표"
},
"uniqueIdentifier": "timestamp를 붙여서 고유성 보장"
},
"steps": [
{
"id": "step-0",
"name": "사이드바 메뉴 탐색",
"description": "회계관리 > 거래처관리 메뉴로 이동",
"actions": [
{
"type": "scroll",
"target": "sidebar",
"direction": "top"
},
{
"type": "wait",
"duration": 300
},
{
"type": "click_if_exists",
"target": "회계관리",
"description": "1차 메뉴 클릭"
},
{
"type": "wait",
"duration": 500
},
{
"type": "click_if_exists",
"target": "거래처관리",
"description": "2차 메뉴 클릭"
},
{
"type": "wait",
"duration": 2000
}
],
"expect": {
"url": "/ko/accounting/vendors",
"no404": true
}
},
{
"id": "step-1",
"phase": "CREATE",
"name": "📝 [CREATE] 거래처 등록 버튼 클릭",
"description": "새 거래처를 등록하기 위해 등록 버튼 클릭",
"actions": [
{
"type": "capture",
"variable": "initialRowCount",
"selector": "table tbody tr",
"extract": "count",
"description": "등록 전 행 수 저장"
},
{
"type": "click_if_exists",
"target": "button:has-text('등록'), button:has-text('추가'), [class*='add'], [class*='register']",
"description": "등록 버튼 클릭"
},
{
"type": "wait",
"duration": 1000
}
],
"expect": {
"modal": true,
"modalTitle": "거래처 등록"
}
},
{
"id": "step-2",
"phase": "CREATE",
"name": "📝 [CREATE] 등록 모달 - 필수 정보 입력",
"description": "테스트용 거래처 정보 입력 (타임스탬프로 고유성 보장)",
"actions": [
{
"type": "generateTimestamp",
"variable": "testTimestamp",
"format": "MMDDHHmmss"
},
{
"type": "click_if_exists",
"target": "거래처명",
"description": "거래처명 입력 필드 확인"
},
{
"type": "click_if_exists",
"target": "사업자등록번호",
"description": "사업자번호 입력 필드 확인"
},
{
"type": "click_if_exists",
"target": "대표자명",
"description": "대표자명 입력 필드 확인"
},
{
"type": "click_if_exists",
"target": "거래처 유형",
"description": "거래처 유형 필드 확인"
},
{
"type": "click_if_exists",
"target": "전화번호",
"description": "전화번호 입력 필드 확인"
},
{
"type": "click_if_exists",
"target": "이메일",
"description": "이메일 입력 필드 확인"
}
],
"note": "타임스탬프를 사용하여 매 테스트마다 고유한 데이터 생성"
},
{
"id": "step-3",
"phase": "CREATE",
"name": "📝 [CREATE] 등록 모달 - 등록 버튼 클릭",
"description": "입력된 정보로 거래처 등록 실행",
"actions": [
{
"type": "click_if_exists",
"target": "button:has-text('등록'), button:has-text('저장')",
"description": "모달 내 등록 버튼 클릭"
},
{
"type": "wait",
"duration": 2000
}
],
"expect": {
"toast": "등록|완료|성공",
"modalClosed": true,
"apiCall": "POST /api/v1/clients"
},
"verification": {
"level": 4,
"checks": [
"API 호출 확인",
"성공 토스트 표시",
"모달 닫힘"
]
}
},
{
"id": "step-3-modal-close",
"phase": "CREATE",
"name": "📝 [CREATE] 모달 닫기 확인",
"description": "모달이 열려있으면 닫기 시도",
"condition": "modalStillOpen",
"actions": [
{
"type": "click_if_exists",
"target": "[role='dialog'] button[class*='close'], [aria-label='닫기'], [aria-label='Close']",
"description": "모달 닫기 시도"
},
{
"type": "wait",
"duration": 500
}
],
"expect": {
"modalClosed": true
}
},
{
"id": "step-4",
"phase": "CREATE",
"name": "📝 [CREATE] 등록 결과 확인",
"description": "테이블에 새로 등록한 거래처가 표시되는지 확인",
"actions": [
{
"type": "fill",
"target": "검색",
"value": "E2E테스트_삭제용",
"description": "생성한 거래처 검색"
},
{
"type": "pressKey",
"key": "Enter"
},
{
"type": "wait",
"duration": 1500
},
{
"type": "capture",
"variable": "createdVendorRow",
"selector": "table tbody tr",
"extract": "exists",
"description": "테스트 거래처 행 존재 여부 확인"
}
],
"expect": {
"rowExists": true,
"rowContains": "E2E테스트_삭제용"
},
"verification": {
"level": 4,
"description": "생성된 데이터가 목록에 표시되어야 함"
}
},
{
"id": "step-5",
"phase": "UPDATE",
"name": "✏️ [UPDATE] 생성된 거래처 상세 페이지 진입",
"description": "생성한 테스트 거래처의 상세 페이지로 이동",
"actions": [
{
"type": "click_if_exists",
"target": "table tbody tr",
"description": "첫 번째 거래처 행 클릭"
},
{
"type": "wait",
"duration": 2000
}
],
"expect": {
"url": "/ko/accounting/vendors/",
"pageTitle": "거래처 상세"
}
},
{
"id": "step-6",
"phase": "UPDATE",
"name": "✏️ [UPDATE] 수정 모드 진입",
"description": "수정 버튼을 클릭하여 편집 모드로 전환",
"actions": [
{
"type": "click_if_exists",
"target": "button:has-text('수정')",
"description": "수정 버튼 클릭"
},
{
"type": "wait",
"duration": 1000
}
],
"expect": {
"url": "mode=edit",
"fieldsEditable": true
}
},
{
"id": "step-7",
"phase": "UPDATE",
"name": "✏️ [UPDATE] 거래처명 수정",
"description": "거래처명을 수정하여 UPDATE 동작 확인",
"actions": [
{
"type": "clear",
"target": "거래처명",
"description": "기존 값 삭제"
},
{
"type": "fill",
"target": "거래처명",
"value": "E2E테스트_수정완료_{testTimestamp}",
"description": "수정된 거래처명 입력"
},
{
"type": "fill",
"target": "대표자명",
"value": "수정대표",
"description": "대표자명 수정"
}
]
},
{
"id": "step-8",
"phase": "UPDATE",
"name": "✏️ [UPDATE] 수정 저장",
"description": "수정된 내용 저장",
"actions": [
{
"type": "click_if_exists",
"target": "button:has-text('저장')",
"description": "저장 버튼 클릭"
},
{
"type": "wait",
"duration": 500
},
{
"type": "click_if_exists",
"target": "button:has-text('확인')",
"description": "저장 확인 다이얼로그"
},
{
"type": "wait",
"duration": 2000
}
],
"expect": {
"toast": "수정|완료|성공",
"apiCall": "PUT /api/v1/clients/"
},
"verification": {
"level": 4,
"description": "수정 API 호출 및 성공 토스트 확인"
}
},
{
"id": "step-8-modal-close",
"phase": "UPDATE",
"name": "✏️ [UPDATE] 다이얼로그 닫기 확인",
"description": "다이얼로그가 열려있으면 닫기",
"condition": "dialogStillOpen",
"actions": [
{
"type": "click_if_exists",
"target": "[role='dialog'] button[class*='close'], [aria-label='닫기'], [aria-label='Close']",
"description": "다이얼로그 닫기 시도"
}
]
},
{
"id": "step-9",
"phase": "UPDATE",
"name": "✏️ [UPDATE] 수정 결과 확인",
"description": "수정된 내용이 반영되었는지 확인",
"actions": [
{
"type": "wait",
"duration": 1000
},
{
"type": "capture",
"variable": "updatedVendorName",
"selector": "[class*='vendor-name'], h1, h2",
"extract": "text"
}
],
"expect": {
"contains": "E2E테스트_수정완료"
}
},
{
"id": "step-10",
"phase": "DELETE",
"name": "🗑️ [DELETE] 삭제 버튼 클릭",
"description": "테스트용으로 생성한 거래처 삭제 시작",
"actions": [
{
"type": "click_if_exists",
"target": "button:has-text('삭제')",
"description": "삭제 버튼 클릭"
},
{
"type": "wait",
"duration": 500
}
],
"expect": {
"confirmDialog": true,
"dialogMessage": "삭제|정말|확인"
},
"warning": "이 단계에서 삭제 확인 다이얼로그가 표시되어야 함"
},
{
"id": "step-11",
"phase": "DELETE",
"name": "🗑️ [DELETE] 삭제 확인 다이얼로그 검증",
"description": "삭제 확인 다이얼로그 UI 요소 확인",
"actions": [
{
"type": "verify",
"target": "dialog",
"checks": [
"삭제 확인 메시지",
"취소 버튼",
"확인/삭제 버튼"
]
}
],
"expect": {
"dialogElements": [
"취소",
"확인|삭제"
]
}
},
{
"id": "step-12",
"phase": "DELETE",
"name": "🗑️ [DELETE] 삭제 확인 버튼 클릭",
"description": "삭제를 최종 확인하여 실행",
"actions": [
{
"type": "click_if_exists",
"target": "button:has-text('확인'), button:has-text('삭제')",
"description": "삭제 확인 클릭"
},
{
"type": "wait",
"duration": 2000
}
],
"expect": {
"toast": "삭제|완료|성공",
"apiCall": "DELETE /api/v1/clients/",
"redirect": "/ko/accounting/vendors"
},
"verification": {
"level": 4,
"checks": [
"DELETE API 호출",
"성공 토스트",
"목록 페이지로 리다이렉트"
]
}
},
{
"id": "step-12-modal-close",
"phase": "DELETE",
"name": "🗑️ [DELETE] 다이얼로그 닫기 확인",
"description": "다이얼로그가 열려있으면 닫기",
"condition": "dialogStillOpen",
"actions": [
{
"type": "click_if_exists",
"target": "[role='dialog'] button[class*='close'], [aria-label='닫기'], [aria-label='Close']",
"description": "다이얼로그 닫기 시도"
}
]
},
{
"id": "step-13",
"phase": "VERIFY",
"name": "✅ [VERIFY] 삭제 결과 확인 - 목록 페이지",
"description": "삭제된 거래처가 목록에서 제거되었는지 확인",
"actions": [
{
"type": "wait",
"duration": 1000
},
{
"type": "verifyUrl",
"contains": "/ko/accounting/vendors",
"description": "목록 페이지 확인"
},
{
"type": "fill",
"target": "검색",
"value": "E2E테스트_수정완료",
"description": "삭제된 거래처 검색"
},
{
"type": "pressKey",
"key": "Enter"
},
{
"type": "wait",
"duration": 1500
}
],
"expect": {
"noResults": true,
"rowNotExists": "E2E테스트_수정완료"
}
},
{
"id": "step-14",
"phase": "VERIFY",
"name": "✅ [VERIFY] 최종 검증 - 데이터 삭제 확인",
"description": "검색 결과에서 테스트 데이터가 없음을 최종 확인",
"actions": [
{
"type": "capture",
"variable": "searchResultCount",
"selector": "table tbody tr",
"extract": "count"
},
{
"type": "verify",
"condition": "searchResultCount === 0 OR no row contains 'E2E테스트'"
}
],
"expect": {
"testDataDeleted": true,
"noTestDataInList": true
},
"verification": {
"level": 4,
"description": "테스트 데이터가 완전히 삭제되어 검색되지 않아야 함"
}
},
{
"id": "step-15",
"phase": "CLEANUP",
"name": "🧹 [CLEANUP] 검색 초기화",
"description": "테스트 종료 후 검색어 삭제하여 원래 상태로 복원",
"actions": [
{
"type": "clear",
"target": "검색"
},
{
"type": "pressKey",
"key": "Enter"
},
{
"type": "wait",
"duration": 1000
}
],
"expect": {
"originalListRestored": true
}
}
],
"expectedAPIs": [
{
"phase": "CREATE",
"method": "POST",
"endpoint": "/api/v1/clients",
"description": "거래처 등록"
},
{
"phase": "UPDATE",
"method": "PUT",
"endpoint": "/api/v1/clients/{id}",
"description": "거래처 수정"
},
{
"phase": "DELETE",
"method": "DELETE",
"endpoint": "/api/v1/clients/{id}",
"description": "거래처 삭제"
}
],
"requiredVerifications": [
{
"id": 1,
"name": "CREATE - 등록 기능",
"steps": [
"step-1",
"step-2",
"step-3",
"step-4"
],
"criteria": "POST API 호출 + 성공 토스트 + 목록에 데이터 표시"
},
{
"id": 2,
"name": "UPDATE - 수정 기능",
"steps": [
"step-6",
"step-7",
"step-8",
"step-9"
],
"criteria": "PUT API 호출 + 성공 토스트 + 데이터 변경 반영"
},
{
"id": 3,
"name": "DELETE - 삭제 기능",
"steps": [
"step-10",
"step-11",
"step-12",
"step-13",
"step-14"
],
"criteria": "DELETE API 호출 + 성공 토스트 + 목록에서 데이터 제거"
},
{
"id": 4,
"name": "모달/다이얼로그 닫기",
"steps": [
"step-3-modal-close",
"step-8-modal-close",
"step-12-modal-close"
],
"criteria": "모든 모달/다이얼로그가 정상적으로 닫혀야 함"
}
],
"rollbackPlan": {
"description": "테스트 실패 시 롤백 계획",
"onCreateFail": "모달 닫기 → 다음 테스트 영향 없음",
"onUpdateFail": "테스트 데이터 수동 삭제 필요 (DB 또는 UI)",
"onDeleteFail": "테스트 데이터 수동 삭제 필요",
"cleanupRequired": "E2E테스트_ 로 시작하는 거래처는 테스트 데이터이므로 수동 삭제 가능"
}
}