diff --git a/accounting-receivable.json b/accounting-receivable.json index af5b766..f836de2 100644 --- a/accounting-receivable.json +++ b/accounting-receivable.json @@ -5,17 +5,24 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "회계관리 > 미수금현황 메뉴의 미수금 조회 기능 테스트", + "description": "회계관리 > 미수금현황 메뉴의 미수금 조회/필터/검색/엑셀 다운로드 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "회계관리", "level2": "미수금현황", - "expectedUrl": "/accounting/receivables-status" + "expectedUrl": "/accounting/receivables-status", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "filterStartDate": "2026-01-01", + "filterEndDate": "2026-02-28", + "searchKeyword": "테스트" + }, "steps": [ { "id": 1, @@ -24,8 +31,8 @@ "level1": "회계관리", "level2": "미수금현황", "expected": { - "url_contains": "/accounting", - "visible": ["미수금"] + "url_contains": "/accounting/receivables", + "visible": ["미수금현황", "미수금"] } }, { @@ -33,27 +40,201 @@ "name": "필수 검증 #5: 목업 페이지 감지", "action": "verify_not_mockup", "checks": [ - "미수금 목록 표시" + "미수금 목록 표시", + "검색/필터 기능 존재", + "날짜 선택 가능" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "미수금 목록 확인", + "name": "미수금 테이블 구조 확인", "action": "verify_table", "checks": [ "거래처 컬럼", - "미수금액 컬럼" + "미수금액 컬럼", + "매출일 컬럼", + "입금예정일 컬럼", + "연체일수 컬럼" ], - "expected": "미수금 목록 표시" + "expected": "미수금 테이블 컬럼 정상 표시" + }, + { + "id": 4, + "name": "통계 카드 확인", + "action": "verify_elements", + "checks": [ + "총 미수금액 표시", + "정상 미수금 표시", + "연체 미수금 표시" + ], + "expected": "미수금 통계 카드 표시" + }, + { + "id": 5, + "phase": "FILTER", + "name": "[FILTER] 기간 필터 적용", + "action": "date_range", + "startDate": "2026-01-01", + "endDate": "2026-02-28", + "expected": { + "filter_applied": true + } + }, + { + "id": 6, + "phase": "FILTER", + "name": "[FILTER] 필터 결과 확인", + "action": "verify_data", + "expected": { + "data_filtered": true, + "table_updated": true + } + }, + { + "id": 7, + "phase": "SEARCH", + "name": "[SEARCH] 거래처 검색", + "action": "search", + "target": "input[placeholder*='검색'], input[placeholder*='거래처']", + "value": "테스트", + "expected": { + "data_filtered": true + } + }, + { + "id": 8, + "phase": "SEARCH", + "name": "[SEARCH] 검색 결과 확인", + "action": "verify_data", + "search": "테스트", + "expected": { + "row_exists": true, + "filtered_by_keyword": true + } + }, + { + "id": 9, + "phase": "READ", + "name": "[READ] 미수금 상세 클릭", + "action": "click", + "target": "table tbody tr:first-child", + "expected": { + "detail_modal_or_page": true, + "visible": ["거래처", "미수금액", "상세"] + } + }, + { + "id": 10, + "phase": "READ", + "name": "[READ] 상세 정보 확인", + "action": "verify_detail", + "checks": [ + "거래처명 표시", + "미수금액 표시", + "매출 내역 표시" + ], + "expected": "미수금 상세 정보 정상 표시" + }, + { + "id": 11, + "phase": "READ", + "name": "[READ] 목록으로 복귀", + "action": "click", + "target": "button:has-text('목록'), button:has-text('닫기')", + "expected": { + "url_contains": "/accounting/receivables" + } + }, + { + "id": 12, + "phase": "EXPORT", + "name": "[EXPORT] 엑셀 다운로드 버튼 확인", + "action": "verify_elements", + "checks": [ + "엑셀 다운로드 버튼 존재" + ], + "expected": "다운로드 기능 존재" + }, + { + "id": 13, + "phase": "EXPORT", + "name": "[EXPORT] 필수 검증 #1: 엑셀 다운로드", + "action": "click", + "target": "button:has-text('엑셀'), button:has-text('다운로드'), button:has-text('내보내기')", + "critical": true, + "verify": { + "file_download": true, + "file_type": "xlsx", + "api_call": "GET /api/v1/receivables/export" + }, + "expected": "엑셀 파일 다운로드" + }, + { + "id": 14, + "phase": "SORT", + "name": "[SORT] 컬럼 정렬 테스트", + "action": "click", + "target": "th:has-text('미수금액')", + "expected": { + "sort_applied": true, + "data_reordered": true + } + }, + { + "id": 15, + "name": "연체 현황 탭 확인", + "action": "click", + "target": "button:has-text('연체'), [role='tab']:has-text('연체')", + "expected": { + "tab_active": true, + "filtered_data": true + } + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/receivables", + "description": "미수금 목록 조회" + }, + { + "method": "GET", + "endpoint": "/api/v1/receivables/summary", + "description": "미수금 통계 조회" + }, + { + "method": "GET", + "endpoint": "/api/v1/receivables/{id}", + "description": "미수금 상세 조회" + }, + { + "method": "GET", + "endpoint": "/api/v1/receivables/export", + "description": "미수금 엑셀 다운로드" } ], "requiredVerifications": [ + { + "id": 1, + "name": "파일 다운로드", + "steps": [13], + "criteria": "엑셀 파일 다운로드 동작" + }, + { + "id": 3, + "name": "검색/필터", + "steps": [5, 6, 7, 8], + "criteria": "기간 필터 및 검색 기능" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "미수금 조회 기능 확인" + "criteria": "미수금 목록, 필터, 다운로드 버튼 존재" } - ] + ], + "rollbackPlan": { + "note": "미수금현황은 조회 전용 페이지로 CRUD 없음 (데이터 생성/수정/삭제 없음)" + } } diff --git a/inspection-management.json b/inspection-management.json index 02cbc2a..7238c26 100644 --- a/inspection-management.json +++ b/inspection-management.json @@ -16,7 +16,9 @@ "menuNavigation": { "level1": "품질관리", "level2": "검사관리", - "expectedUrl": "/quality/inspection" + "expectedUrl": "/quality/inspection", + "searchWithinParent": true, + "closeOtherMenus": true }, "menuNavigationEnhanced": { "strategy": "scroll-and-search", diff --git a/quality-inspection.json b/quality-inspection.json index e752b41..c47b819 100644 --- a/quality-inspection.json +++ b/quality-inspection.json @@ -5,17 +5,32 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "품질관리 > 제품검사관리 메뉴의 목록 조회, 필터, 검색, 등록, 상세 기능 테스트", + "description": "품질관리 > 제품검사관리 메뉴의 제품검사 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "품질관리", "level2": "제품검사관리", - "expectedUrl": "/quality/inspections" + "expectedUrl": "/quality/inspections", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "create": { + "siteName": "E2E_TEST_현장", + "orderCompany": "E2E_TEST_수주처", + "location": "테스트구역A", + "inspector": "홍길동", + "memo": "E2E 자동화 테스트 제품검사" + }, + "update": { + "location": "테스트구역B", + "memo": "E2E 수정된 제품검사 메모" + } + }, "steps": [ { "id": 1, @@ -25,7 +40,7 @@ "level2": "제품검사관리", "expected": { "url_contains": "/quality/inspections", - "visible": ["제품검사 목록", "제품검사 등록"] + "visible": ["제품검사", "검사"] } }, { @@ -33,137 +48,207 @@ "name": "필수 검증 #5: 목업 페이지 감지", "action": "verify_not_mockup", "checks": [ - "검색 입력 필드 존재 및 입력 가능", - "날짜 필터 존재", - "테이블 데이터 표시", - "제품검사 등록 버튼 존재" + "제품검사 목록 표시", + "제품검사 등록 버튼 존재", + "검색/필터 기능 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "상태 카드 확인", - "action": "verify_elements", - "checks": [ - "접수 카드 표시", - "진행중 카드 표시", - "완료 카드 표시" - ], - "expected": "3개 상태 카드 모두 표시" - }, - { - "id": 4, - "name": "테이블 구조 확인", + "name": "제품검사 테이블 구조 확인", "action": "verify_table", "checks": [ - "No. 컬럼", "품질관리서 번호 컬럼", "현장명 컬럼", "수주처 컬럼", - "개소 컬럼", - "필수정보 컬럼", "검사기간 컬럼", - "검사자 컬럼", "상태 컬럼", - "작성자 컬럼", - "접수일 컬럼" + "검사자 컬럼" ], - "expected": "11개 컬럼 존재" + "expected": "제품검사 테이블 컬럼 정상 표시" + }, + { + "id": 4, + "name": "검색 기능 테스트", + "action": "search", + "target": "input[placeholder*='검색']", + "value": "테스트", + "expected": { + "data_filtered": true + } }, { "id": 5, - "name": "날짜 필터 테스트 - 당월", + "phase": "CREATE", + "name": "[CREATE] 제품검사 등록 버튼 클릭", "action": "click", - "target": "당월", - "expected": "당월 데이터로 필터링" + "target": "button:has-text('등록'), button:has-text('제품검사 등록'), button:has-text('추가')", + "expected": { + "modal_or_page": true, + "title": "제품검사 등록" + } }, { "id": 6, - "name": "날짜 필터 테스트 - 당해년도", - "action": "click", - "target": "당해년도", - "expected": "당해년도 데이터로 필터링" + "phase": "CREATE", + "name": "[CREATE] 제품검사 정보 입력", + "action": "fill_form", + "fields": [ + {"name": "현장명", "type": "text", "value": "E2E_TEST_현장_{timestamp}"}, + {"name": "수주처", "type": "select", "value": "E2E_TEST_수주처"}, + {"name": "개소", "type": "text", "value": "테스트구역A"}, + {"name": "검사자", "type": "select", "value": "홍길동"}, + {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 제품검사_{timestamp}"} + ], + "note": "타임스탬프로 고유성 보장" }, { "id": 7, - "name": "검색 기능 테스트", - "action": "fill", - "target": "input[placeholder*='검색']", - "value": "현장명", - "expected": "검색어 입력됨" + "phase": "CREATE", + "name": "[CREATE] 필수 검증 #2: 등록 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('등록')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "POST /api/v1/quality/inspections", + "toast": "등록|완료|성공" + }, + "expected": "제품검사 등록 완료" + }, + { + "id": "7-modal-close", + "phase": "CREATE", + "name": "[CREATE] 모달 닫기 확인", + "action": "close_modal_if_open", + "expected": "모달 닫힘" }, { "id": 8, - "name": "검색 결과 확인", - "action": "wait", - "duration": 500, - "verify": { - "tableContains": "현장명" - }, - "expected": "검색 결과 표시" + "phase": "CREATE", + "name": "[CREATE] 등록 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_현장", + "expected": { + "row_exists": true, + "contains": ["E2E_TEST", "접수"] + } }, { "id": 9, - "name": "검색 초기화", - "action": "clear", - "target": "input[placeholder*='검색']", - "expected": "검색어 삭제" + "phase": "READ", + "name": "[READ] 제품검사 상세 페이지 진입", + "action": "click", + "target": "table tbody tr:has-text('E2E_TEST')", + "expected": { + "url_contains": "/quality/inspections/", + "visible": ["품질관리서", "수정", "삭제"] + } }, { "id": 10, - "name": "테이블 행 클릭 - 상세 페이지", - "action": "click", - "target": "table tbody tr:first-child", - "expected": "상세 페이지로 이동" + "phase": "READ", + "name": "[READ] 상세 정보 확인", + "action": "verify_detail", + "checks": [ + "현장명: E2E_TEST_현장", + "개소: 테스트구역A", + "검사자: 홍길동" + ], + "expected": "입력한 데이터와 일치" }, { "id": 11, - "name": "상세 페이지 확인", - "action": "verify_url", + "phase": "UPDATE", + "name": "[UPDATE] 수정 모드 진입", + "action": "click", + "target": "button:has-text('수정')", "expected": { - "url_contains": "/quality/inspections/" + "url_contains": "mode=edit", + "fields_editable": true } }, { "id": 12, - "name": "상세 페이지 요소 확인", - "action": "verify_elements", - "checks": [ - "품질관리서 정보 표시", - "목록 버튼 존재", - "수정 버튼 존재" - ], - "expected": "상세 정보 정상 표시" + "phase": "UPDATE", + "name": "[UPDATE] 개소 수정", + "action": "fill", + "target": "input[name*='location'], input[placeholder*='개소']", + "value": "테스트구역B", + "clear": true }, { "id": 13, - "name": "목록으로 돌아가기", - "action": "click", - "target": "목록", - "expected": "목록 페이지로 복귀" + "phase": "UPDATE", + "name": "[UPDATE] 메모 수정", + "action": "fill", + "target": "textarea[name*='memo'], input[placeholder*='메모']", + "value": "E2E 수정된 제품검사 메모_{timestamp}", + "clear": true }, { "id": 14, - "name": "목록 페이지 복귀 확인", - "action": "verify_url", - "expected": { - "url_contains": "/quality/inspections", - "url_not_contains": "/quality/inspections/" - } - } - ], - "requiredVerifications": [ - { - "id": 3, - "name": "검색/필터", - "steps": [5, 6, 7, 8, 9], - "criteria": "날짜 필터 및 검색 시 데이터 변화 확인" + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 수정 저장", + "action": "click", + "target": "button:has-text('저장')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/quality/inspections/", + "toast": "수정|완료|성공" + }, + "expected": "수정 완료" }, { - "id": 5, - "name": "목업 페이지 감지", - "steps": [2], - "criteria": "입력 필드, 동작 버튼, 테이블 데이터 확인" + "id": 15, + "phase": "UPDATE", + "name": "[UPDATE] 수정 결과 확인", + "action": "verify_detail", + "checks": [ + "개소: 테스트구역B", + "메모: E2E 수정된" + ], + "expected": "수정된 데이터 반영" + }, + { + "id": 16, + "phase": "DELETE", + "name": "[DELETE] 삭제 버튼 클릭", + "action": "click", + "target": "button:has-text('삭제')", + "expected": { + "confirm_dialog": true, + "dialog_message": "삭제|정말" + } + }, + { + "id": 17, + "phase": "DELETE", + "name": "[DELETE] 필수 검증 #6: 삭제 확인", + "action": "click", + "target": "button:has-text('확인'), button:has-text('삭제')", + "critical": true, + "verify": { + "api_call": "DELETE /api/v1/quality/inspections/", + "toast": "삭제|완료|성공", + "redirect": "/quality/inspections" + }, + "expected": "삭제 완료 및 목록 복귀" + }, + { + "id": 18, + "phase": "DELETE", + "name": "[DELETE] 삭제 결과 확인", + "action": "verify_data", + "search": "E2E 수정된 제품검사", + "expected": { + "row_exists": false, + "message": "테스트 제품검사가 목록에서 제거됨" + } } ], "expectedAPIs": [ @@ -172,10 +257,57 @@ "endpoint": "/api/v1/quality/inspections", "description": "제품검사 목록 조회" }, + { + "method": "POST", + "endpoint": "/api/v1/quality/inspections", + "description": "제품검사 등록" + }, { "method": "GET", "endpoint": "/api/v1/quality/inspections/{id}", "description": "제품검사 상세 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/quality/inspections/{id}", + "description": "제품검사 수정" + }, + { + "method": "DELETE", + "endpoint": "/api/v1/quality/inspections/{id}", + "description": "제품검사 삭제" } - ] + ], + "requiredVerifications": [ + { + "id": 2, + "name": "등록/저장 버튼", + "steps": [7, 14], + "criteria": "API 호출 + 성공 토스트 + 데이터 반영" + }, + { + "id": 3, + "name": "검색/필터", + "steps": [4], + "criteria": "검색 기능 동작" + }, + { + "id": 5, + "name": "목업 페이지 감지", + "steps": [2], + "criteria": "제품검사 목록, 등록 버튼, 필터 존재" + }, + { + "id": 6, + "name": "삭제 기능", + "steps": [16, 17, 18], + "criteria": "DELETE API + 목록에서 제거" + } + ], + "rollbackPlan": { + "onCreateFail": "모달 닫기", + "onUpdateFail": "테스트 제품검사 수동 삭제 필요", + "onDeleteFail": "테스트 제품검사 수동 삭제 필요", + "cleanupRequired": "E2E_TEST_ 접두사 제품검사는 테스트 데이터" + } } diff --git a/settings-attendance.json b/settings-attendance.json index d5a01f6..c0cfa8a 100644 --- a/settings-attendance.json +++ b/settings-attendance.json @@ -5,17 +5,27 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "설정 > 근태설정 메뉴의 근태 정책 설정 기능 테스트", + "description": "설정 > 근태설정 메뉴의 근태 정책 조회/수정/저장 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "설정", "level2": "근태설정", - "expectedUrl": "/settings/attendance" + "expectedUrl": "/settings/attendance", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "update": { + "lateThreshold": "10", + "earlyLeaveThreshold": "10", + "autoCheckout": true, + "checkoutTime": "22:00" + } + }, "steps": [ { "id": 1, @@ -34,37 +44,152 @@ "action": "verify_not_mockup", "checks": [ "근태 설정 폼 표시", - "출근/퇴근 시간 설정 가능" + "출퇴근 시간 설정 가능", + "저장 버튼 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "근태 설정 항목 확인", + "name": "근태 설정 폼 구조 확인", "action": "verify_elements", "checks": [ - "출근 시간 설정", - "퇴근 시간 설정", - "지각/조퇴 기준" + "지각 기준 시간 설정", + "조퇴 기준 시간 설정", + "자동 퇴근 처리 설정", + "출퇴근 인정 범위" ], - "expected": "근태 설정 항목 표시" + "expected": "근태 설정 폼 정상 표시" }, { "id": 4, - "name": "저장 버튼 확인", + "phase": "READ", + "name": "[READ] 현재 근태 설정 확인", + "action": "verify_detail", + "checks": [ + "지각 기준 표시", + "조퇴 기준 표시", + "자동 퇴근 설정 표시" + ], + "expected": "현재 근태 설정 정상 표시" + }, + { + "id": 5, + "phase": "UPDATE", + "name": "[UPDATE] 지각 기준 수정", + "action": "fill", + "target": "input[name*='late'], input[placeholder*='지각']", + "value": "10", + "clear": true + }, + { + "id": 6, + "phase": "UPDATE", + "name": "[UPDATE] 조퇴 기준 수정", + "action": "fill", + "target": "input[name*='early'], input[placeholder*='조퇴']", + "value": "10", + "clear": true + }, + { + "id": 7, + "phase": "UPDATE", + "name": "[UPDATE] 자동 퇴근 시간 설정", + "action": "fill", + "target": "input[name*='autoCheckout'], input[type='time']", + "value": "22:00", + "clear": true + }, + { + "id": 8, + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 근태 설정 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('적용')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/settings/attendance", + "toast": "저장|적용|완료|성공" + }, + "expected": "근태 설정 저장 완료" + }, + { + "id": 9, + "phase": "UPDATE", + "name": "[UPDATE] 저장 결과 확인", + "action": "verify_detail", + "checks": [ + "지각 기준: 10분", + "조퇴 기준: 10분", + "자동 퇴근: 22:00" + ], + "expected": "수정된 설정 반영" + }, + { + "id": 10, + "name": "위치 기반 출퇴근 설정 확인", "action": "verify_elements", "checks": [ - "저장 버튼 존재" + "GPS 출퇴근 사용 여부", + "출퇴근 가능 위치 설정" ], - "expected": "저장 버튼 표시" + "expected": "위치 기반 설정 표시" + }, + { + "id": 11, + "name": "근태 이상 알림 설정 확인", + "action": "verify_elements", + "checks": [ + "지각 알림 설정", + "무단결근 알림 설정" + ], + "expected": "알림 설정 표시" + }, + { + "id": 12, + "name": "부서별 근태 설정 확인", + "action": "verify_elements", + "checks": [ + "부서별 설정 가능" + ], + "expected": "부서별 설정 표시" + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/settings/attendance", + "description": "근태 설정 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/settings/attendance", + "description": "근태 설정 수정" + }, + { + "method": "GET", + "endpoint": "/api/v1/settings/attendance/locations", + "description": "출퇴근 위치 목록 조회" } ], "requiredVerifications": [ + { + "id": 2, + "name": "저장 버튼", + "steps": [8], + "criteria": "API 호출 + 성공 토스트 + 설정 반영" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "근태 설정 폼, 저장 기능 확인" + "criteria": "근태 설정 폼, 저장 버튼 존재" } - ] + ], + "rollbackPlan": { + "onUpdateFail": "페이지 새로고침으로 원래 값 복원", + "note": "설정 페이지는 수정 후 원복 테스트 권장" + } } diff --git a/settings-bank-account.json b/settings-bank-account.json index 3e05ea6..a1664f4 100644 --- a/settings-bank-account.json +++ b/settings-bank-account.json @@ -5,17 +5,32 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "설정 > 계좌관리 메뉴의 계좌 등록/관리 기능 테스트", + "description": "설정 > 계좌관리 메뉴의 계좌 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "설정", "level2": "계좌관리", - "expectedUrl": "/settings/bank-accounts" + "expectedUrl": "/settings/bank-accounts", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "create": { + "bankName": "E2E테스트은행", + "accountNumber": "123-456-789012", + "accountHolder": "E2E_TEST_예금주", + "accountType": "보통예금", + "memo": "E2E 자동화 테스트 계좌" + }, + "update": { + "accountHolder": "E2E_TEST_수정예금주", + "memo": "E2E 수정된 계좌 메모" + } + }, "steps": [ { "id": 1, @@ -34,37 +49,263 @@ "action": "verify_not_mockup", "checks": [ "계좌 목록 표시", - "계좌 등록 버튼 존재" + "계좌 등록 버튼 존재", + "검색/필터 기능 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "계좌 테이블 확인", + "name": "계좌 테이블 구조 확인", "action": "verify_table", "checks": [ "은행명 컬럼", "계좌번호 컬럼", - "예금주 컬럼" + "예금주 컬럼", + "계좌유형 컬럼" ], - "expected": "계좌 목록 표시" + "expected": "계좌 테이블 컬럼 정상 표시" }, { "id": 4, - "name": "계좌 등록 버튼 확인", - "action": "verify_elements", - "checks": [ - "계좌 등록 버튼 존재" + "name": "검색 기능 테스트", + "action": "search", + "target": "input[placeholder*='검색']", + "value": "테스트", + "expected": { + "data_filtered": true + } + }, + { + "id": 5, + "phase": "CREATE", + "name": "[CREATE] 계좌 등록 버튼 클릭", + "action": "click", + "target": "button:has-text('등록'), button:has-text('계좌 등록'), button:has-text('추가')", + "expected": { + "modal_or_page": true, + "title": "계좌 등록" + } + }, + { + "id": 6, + "phase": "CREATE", + "name": "[CREATE] 계좌 정보 입력", + "action": "fill_form", + "fields": [ + {"name": "은행명", "type": "select", "value": "E2E테스트은행"}, + {"name": "계좌번호", "type": "text", "value": "123-456-789012_{timestamp}"}, + {"name": "예금주", "type": "text", "value": "E2E_TEST_예금주"}, + {"name": "계좌유형", "type": "select", "value": "보통예금"}, + {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 계좌_{timestamp}"} ], - "expected": "등록 버튼 표시" + "note": "타임스탬프로 고유성 보장" + }, + { + "id": 7, + "phase": "CREATE", + "name": "[CREATE] 필수 검증 #2: 등록 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('등록')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "POST /api/v1/bank-accounts", + "toast": "등록|완료|성공" + }, + "expected": "계좌 등록 완료" + }, + { + "id": "7-modal-close", + "phase": "CREATE", + "name": "[CREATE] 모달 닫기 확인", + "action": "close_modal_if_open", + "expected": "모달 닫힘" + }, + { + "id": 8, + "phase": "CREATE", + "name": "[CREATE] 등록 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_예금주", + "expected": { + "row_exists": true, + "contains": ["E2E_TEST", "123-456"] + } + }, + { + "id": 9, + "phase": "READ", + "name": "[READ] 계좌 상세 페이지 진입", + "action": "click", + "target": "table tbody tr:has-text('E2E_TEST')", + "expected": { + "url_contains": "/settings/bank", + "visible": ["계좌 상세", "수정", "삭제"] + } + }, + { + "id": 10, + "phase": "READ", + "name": "[READ] 상세 정보 확인", + "action": "verify_detail", + "checks": [ + "예금주: E2E_TEST_예금주", + "계좌번호: 123-456", + "메모: E2E 자동화 테스트" + ], + "expected": "입력한 데이터와 일치" + }, + { + "id": 11, + "phase": "UPDATE", + "name": "[UPDATE] 수정 모드 진입", + "action": "click", + "target": "button:has-text('수정')", + "expected": { + "url_contains": "mode=edit", + "fields_editable": true + } + }, + { + "id": 12, + "phase": "UPDATE", + "name": "[UPDATE] 예금주 수정", + "action": "fill", + "target": "input[name*='holder'], input[placeholder*='예금주']", + "value": "E2E_TEST_수정예금주", + "clear": true + }, + { + "id": 13, + "phase": "UPDATE", + "name": "[UPDATE] 메모 수정", + "action": "fill", + "target": "textarea[name*='memo'], input[placeholder*='메모']", + "value": "E2E 수정된 계좌 메모_{timestamp}", + "clear": true + }, + { + "id": 14, + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 수정 저장", + "action": "click", + "target": "button:has-text('저장')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/bank-accounts/", + "toast": "수정|완료|성공" + }, + "expected": "수정 완료" + }, + { + "id": 15, + "phase": "UPDATE", + "name": "[UPDATE] 수정 결과 확인", + "action": "verify_detail", + "checks": [ + "예금주: E2E_TEST_수정예금주", + "메모: E2E 수정된" + ], + "expected": "수정된 데이터 반영" + }, + { + "id": 16, + "phase": "DELETE", + "name": "[DELETE] 삭제 버튼 클릭", + "action": "click", + "target": "button:has-text('삭제')", + "expected": { + "confirm_dialog": true, + "dialog_message": "삭제|정말" + } + }, + { + "id": 17, + "phase": "DELETE", + "name": "[DELETE] 필수 검증 #6: 삭제 확인", + "action": "click", + "target": "button:has-text('확인'), button:has-text('삭제')", + "critical": true, + "verify": { + "api_call": "DELETE /api/v1/bank-accounts/", + "toast": "삭제|완료|성공", + "redirect": "/settings/bank-accounts" + }, + "expected": "삭제 완료 및 목록 복귀" + }, + { + "id": 18, + "phase": "DELETE", + "name": "[DELETE] 삭제 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_수정예금주", + "expected": { + "row_exists": false, + "message": "테스트 계좌가 목록에서 제거됨" + } + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/bank-accounts", + "description": "계좌 목록 조회" + }, + { + "method": "POST", + "endpoint": "/api/v1/bank-accounts", + "description": "계좌 등록" + }, + { + "method": "GET", + "endpoint": "/api/v1/bank-accounts/{id}", + "description": "계좌 상세 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/bank-accounts/{id}", + "description": "계좌 수정" + }, + { + "method": "DELETE", + "endpoint": "/api/v1/bank-accounts/{id}", + "description": "계좌 삭제" } ], "requiredVerifications": [ + { + "id": 2, + "name": "등록/저장 버튼", + "steps": [7, 14], + "criteria": "API 호출 + 성공 토스트 + 데이터 반영" + }, + { + "id": 3, + "name": "검색/필터", + "steps": [4], + "criteria": "검색 기능 동작" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "계좌 목록, 등록 기능 확인" + "criteria": "계좌 목록, 등록 버튼, 필터 존재" + }, + { + "id": 6, + "name": "삭제 기능", + "steps": [16, 17, 18], + "criteria": "DELETE API + 목록에서 제거" } - ] + ], + "rollbackPlan": { + "onCreateFail": "모달 닫기", + "onUpdateFail": "테스트 계좌 수동 삭제 필요", + "onDeleteFail": "테스트 계좌 수동 삭제 필요", + "cleanupRequired": "E2E_TEST_ 접두사 계좌는 테스트 데이터" + } } diff --git a/settings-position.json b/settings-position.json index 6c9a6e9..89785e8 100644 --- a/settings-position.json +++ b/settings-position.json @@ -5,17 +5,31 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "설정 > 직책관리 메뉴의 직책 설정 기능 테스트", + "description": "설정 > 직책관리 메뉴의 직책 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "설정", "level2": "직책관리", - "expectedUrl": "/settings/positions" + "expectedUrl": "/settings/positions", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "create": { + "positionName": "E2E_TEST_직책", + "positionCode": "E2E_POS", + "order": "99", + "memo": "E2E 자동화 테스트 직책" + }, + "update": { + "positionName": "E2E_TEST_수정직책", + "memo": "E2E 수정된 직책 메모" + } + }, "steps": [ { "id": 1, @@ -34,36 +48,261 @@ "action": "verify_not_mockup", "checks": [ "직책 목록 표시", - "직책 추가 가능" + "직책 추가 버튼 존재", + "검색/필터 기능 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "직책 목록 확인", + "name": "직책 테이블 구조 확인", "action": "verify_table", "checks": [ "직책명 컬럼", + "직책코드 컬럼", "순서 컬럼" ], - "expected": "직책 목록 표시" + "expected": "직책 테이블 컬럼 정상 표시" }, { "id": 4, - "name": "직책 추가 버튼 확인", - "action": "verify_elements", - "checks": [ - "직책 추가 버튼 존재" + "name": "검색 기능 테스트", + "action": "search", + "target": "input[placeholder*='검색']", + "value": "테스트", + "expected": { + "data_filtered": true + } + }, + { + "id": 5, + "phase": "CREATE", + "name": "[CREATE] 직책 추가 버튼 클릭", + "action": "click", + "target": "button:has-text('추가'), button:has-text('직책 추가'), button:has-text('등록')", + "expected": { + "modal_or_page": true, + "title": "직책 추가" + } + }, + { + "id": 6, + "phase": "CREATE", + "name": "[CREATE] 직책 정보 입력", + "action": "fill_form", + "fields": [ + {"name": "직책명", "type": "text", "value": "E2E_TEST_직책_{timestamp}"}, + {"name": "직책코드", "type": "text", "value": "E2E_POS_{timestamp}"}, + {"name": "순서", "type": "number", "value": "99"}, + {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 직책_{timestamp}"} ], - "expected": "추가 버튼 표시" + "note": "타임스탬프로 고유성 보장" + }, + { + "id": 7, + "phase": "CREATE", + "name": "[CREATE] 필수 검증 #2: 등록 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('등록'), button:has-text('추가')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "POST /api/v1/positions", + "toast": "등록|추가|완료|성공" + }, + "expected": "직책 등록 완료" + }, + { + "id": "7-modal-close", + "phase": "CREATE", + "name": "[CREATE] 모달 닫기 확인", + "action": "close_modal_if_open", + "expected": "모달 닫힘" + }, + { + "id": 8, + "phase": "CREATE", + "name": "[CREATE] 등록 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_직책", + "expected": { + "row_exists": true, + "contains": ["E2E_TEST", "E2E_POS"] + } + }, + { + "id": 9, + "phase": "READ", + "name": "[READ] 직책 상세 페이지 진입", + "action": "click", + "target": "table tbody tr:has-text('E2E_TEST')", + "expected": { + "url_contains": "/settings/positions", + "visible": ["직책 상세", "수정", "삭제"] + } + }, + { + "id": 10, + "phase": "READ", + "name": "[READ] 상세 정보 확인", + "action": "verify_detail", + "checks": [ + "직책명: E2E_TEST_직책", + "직책코드: E2E_POS", + "순서: 99" + ], + "expected": "입력한 데이터와 일치" + }, + { + "id": 11, + "phase": "UPDATE", + "name": "[UPDATE] 수정 모드 진입", + "action": "click", + "target": "button:has-text('수정')", + "expected": { + "url_contains": "mode=edit", + "fields_editable": true + } + }, + { + "id": 12, + "phase": "UPDATE", + "name": "[UPDATE] 직책명 수정", + "action": "fill", + "target": "input[name*='name'], input[placeholder*='직책명']", + "value": "E2E_TEST_수정직책", + "clear": true + }, + { + "id": 13, + "phase": "UPDATE", + "name": "[UPDATE] 메모 수정", + "action": "fill", + "target": "textarea[name*='memo'], input[placeholder*='메모']", + "value": "E2E 수정된 직책 메모_{timestamp}", + "clear": true + }, + { + "id": 14, + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 수정 저장", + "action": "click", + "target": "button:has-text('저장')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/positions/", + "toast": "수정|완료|성공" + }, + "expected": "수정 완료" + }, + { + "id": 15, + "phase": "UPDATE", + "name": "[UPDATE] 수정 결과 확인", + "action": "verify_detail", + "checks": [ + "직책명: E2E_TEST_수정직책", + "메모: E2E 수정된" + ], + "expected": "수정된 데이터 반영" + }, + { + "id": 16, + "phase": "DELETE", + "name": "[DELETE] 삭제 버튼 클릭", + "action": "click", + "target": "button:has-text('삭제')", + "expected": { + "confirm_dialog": true, + "dialog_message": "삭제|정말" + } + }, + { + "id": 17, + "phase": "DELETE", + "name": "[DELETE] 필수 검증 #6: 삭제 확인", + "action": "click", + "target": "button:has-text('확인'), button:has-text('삭제')", + "critical": true, + "verify": { + "api_call": "DELETE /api/v1/positions/", + "toast": "삭제|완료|성공", + "redirect": "/settings/positions" + }, + "expected": "삭제 완료 및 목록 복귀" + }, + { + "id": 18, + "phase": "DELETE", + "name": "[DELETE] 삭제 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_수정직책", + "expected": { + "row_exists": false, + "message": "테스트 직책이 목록에서 제거됨" + } + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/positions", + "description": "직책 목록 조회" + }, + { + "method": "POST", + "endpoint": "/api/v1/positions", + "description": "직책 등록" + }, + { + "method": "GET", + "endpoint": "/api/v1/positions/{id}", + "description": "직책 상세 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/positions/{id}", + "description": "직책 수정" + }, + { + "method": "DELETE", + "endpoint": "/api/v1/positions/{id}", + "description": "직책 삭제" } ], "requiredVerifications": [ + { + "id": 2, + "name": "등록/저장 버튼", + "steps": [7, 14], + "criteria": "API 호출 + 성공 토스트 + 데이터 반영" + }, + { + "id": 3, + "name": "검색/필터", + "steps": [4], + "criteria": "검색 기능 동작" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "직책 목록, 추가 기능 확인" + "criteria": "직책 목록, 추가 버튼, 필터 존재" + }, + { + "id": 6, + "name": "삭제 기능", + "steps": [16, 17, 18], + "criteria": "DELETE API + 목록에서 제거" } - ] + ], + "rollbackPlan": { + "onCreateFail": "모달 닫기", + "onUpdateFail": "테스트 직책 수동 삭제 필요", + "onDeleteFail": "테스트 직책 수동 삭제 필요", + "cleanupRequired": "E2E_TEST_ 접두사 직책은 테스트 데이터" + } } diff --git a/settings-rank.json b/settings-rank.json index fecf381..7a1e9f5 100644 --- a/settings-rank.json +++ b/settings-rank.json @@ -5,17 +5,31 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "설정 > 직급관리 메뉴의 직급 설정 기능 테스트", + "description": "설정 > 직급관리 메뉴의 직급 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "설정", "level2": "직급관리", - "expectedUrl": "/settings/ranks" + "expectedUrl": "/settings/ranks", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "create": { + "rankName": "E2E_TEST_직급", + "rankCode": "E2E_RANK", + "order": "99", + "memo": "E2E 자동화 테스트 직급" + }, + "update": { + "rankName": "E2E_TEST_수정직급", + "memo": "E2E 수정된 직급 메모" + } + }, "steps": [ { "id": 1, @@ -34,36 +48,261 @@ "action": "verify_not_mockup", "checks": [ "직급 목록 표시", - "직급 추가 가능" + "직급 추가 버튼 존재", + "검색/필터 기능 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "직급 목록 확인", + "name": "직급 테이블 구조 확인", "action": "verify_table", "checks": [ "직급명 컬럼", + "직급코드 컬럼", "순서 컬럼" ], - "expected": "직급 목록 표시" + "expected": "직급 테이블 컬럼 정상 표시" }, { "id": 4, - "name": "직급 추가 버튼 확인", - "action": "verify_elements", - "checks": [ - "직급 추가 버튼 존재" + "name": "검색 기능 테스트", + "action": "search", + "target": "input[placeholder*='검색']", + "value": "테스트", + "expected": { + "data_filtered": true + } + }, + { + "id": 5, + "phase": "CREATE", + "name": "[CREATE] 직급 추가 버튼 클릭", + "action": "click", + "target": "button:has-text('추가'), button:has-text('직급 추가'), button:has-text('등록')", + "expected": { + "modal_or_page": true, + "title": "직급 추가" + } + }, + { + "id": 6, + "phase": "CREATE", + "name": "[CREATE] 직급 정보 입력", + "action": "fill_form", + "fields": [ + {"name": "직급명", "type": "text", "value": "E2E_TEST_직급_{timestamp}"}, + {"name": "직급코드", "type": "text", "value": "E2E_RANK_{timestamp}"}, + {"name": "순서", "type": "number", "value": "99"}, + {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 직급_{timestamp}"} ], - "expected": "추가 버튼 표시" + "note": "타임스탬프로 고유성 보장" + }, + { + "id": 7, + "phase": "CREATE", + "name": "[CREATE] 필수 검증 #2: 등록 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('등록'), button:has-text('추가')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "POST /api/v1/ranks", + "toast": "등록|추가|완료|성공" + }, + "expected": "직급 등록 완료" + }, + { + "id": "7-modal-close", + "phase": "CREATE", + "name": "[CREATE] 모달 닫기 확인", + "action": "close_modal_if_open", + "expected": "모달 닫힘" + }, + { + "id": 8, + "phase": "CREATE", + "name": "[CREATE] 등록 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_직급", + "expected": { + "row_exists": true, + "contains": ["E2E_TEST", "E2E_RANK"] + } + }, + { + "id": 9, + "phase": "READ", + "name": "[READ] 직급 상세 페이지 진입", + "action": "click", + "target": "table tbody tr:has-text('E2E_TEST')", + "expected": { + "url_contains": "/settings/ranks", + "visible": ["직급 상세", "수정", "삭제"] + } + }, + { + "id": 10, + "phase": "READ", + "name": "[READ] 상세 정보 확인", + "action": "verify_detail", + "checks": [ + "직급명: E2E_TEST_직급", + "직급코드: E2E_RANK", + "순서: 99" + ], + "expected": "입력한 데이터와 일치" + }, + { + "id": 11, + "phase": "UPDATE", + "name": "[UPDATE] 수정 모드 진입", + "action": "click", + "target": "button:has-text('수정')", + "expected": { + "url_contains": "mode=edit", + "fields_editable": true + } + }, + { + "id": 12, + "phase": "UPDATE", + "name": "[UPDATE] 직급명 수정", + "action": "fill", + "target": "input[name*='name'], input[placeholder*='직급명']", + "value": "E2E_TEST_수정직급", + "clear": true + }, + { + "id": 13, + "phase": "UPDATE", + "name": "[UPDATE] 메모 수정", + "action": "fill", + "target": "textarea[name*='memo'], input[placeholder*='메모']", + "value": "E2E 수정된 직급 메모_{timestamp}", + "clear": true + }, + { + "id": 14, + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 수정 저장", + "action": "click", + "target": "button:has-text('저장')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/ranks/", + "toast": "수정|완료|성공" + }, + "expected": "수정 완료" + }, + { + "id": 15, + "phase": "UPDATE", + "name": "[UPDATE] 수정 결과 확인", + "action": "verify_detail", + "checks": [ + "직급명: E2E_TEST_수정직급", + "메모: E2E 수정된" + ], + "expected": "수정된 데이터 반영" + }, + { + "id": 16, + "phase": "DELETE", + "name": "[DELETE] 삭제 버튼 클릭", + "action": "click", + "target": "button:has-text('삭제')", + "expected": { + "confirm_dialog": true, + "dialog_message": "삭제|정말" + } + }, + { + "id": 17, + "phase": "DELETE", + "name": "[DELETE] 필수 검증 #6: 삭제 확인", + "action": "click", + "target": "button:has-text('확인'), button:has-text('삭제')", + "critical": true, + "verify": { + "api_call": "DELETE /api/v1/ranks/", + "toast": "삭제|완료|성공", + "redirect": "/settings/ranks" + }, + "expected": "삭제 완료 및 목록 복귀" + }, + { + "id": 18, + "phase": "DELETE", + "name": "[DELETE] 삭제 결과 확인", + "action": "verify_data", + "search": "E2E_TEST_수정직급", + "expected": { + "row_exists": false, + "message": "테스트 직급이 목록에서 제거됨" + } + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/ranks", + "description": "직급 목록 조회" + }, + { + "method": "POST", + "endpoint": "/api/v1/ranks", + "description": "직급 등록" + }, + { + "method": "GET", + "endpoint": "/api/v1/ranks/{id}", + "description": "직급 상세 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/ranks/{id}", + "description": "직급 수정" + }, + { + "method": "DELETE", + "endpoint": "/api/v1/ranks/{id}", + "description": "직급 삭제" } ], "requiredVerifications": [ + { + "id": 2, + "name": "등록/저장 버튼", + "steps": [7, 14], + "criteria": "API 호출 + 성공 토스트 + 데이터 반영" + }, + { + "id": 3, + "name": "검색/필터", + "steps": [4], + "criteria": "검색 기능 동작" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "직급 목록, 추가 기능 확인" + "criteria": "직급 목록, 추가 버튼, 필터 존재" + }, + { + "id": 6, + "name": "삭제 기능", + "steps": [16, 17, 18], + "criteria": "DELETE API + 목록에서 제거" } - ] + ], + "rollbackPlan": { + "onCreateFail": "모달 닫기", + "onUpdateFail": "테스트 직급 수동 삭제 필요", + "onDeleteFail": "테스트 직급 수동 삭제 필요", + "cleanupRequired": "E2E_TEST_ 접두사 직급은 테스트 데이터" + } } diff --git a/settings-vacation-policy.json b/settings-vacation-policy.json index 29a96ae..c074d69 100644 --- a/settings-vacation-policy.json +++ b/settings-vacation-policy.json @@ -5,17 +5,32 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "설정 > 휴가정책 메뉴의 휴가 정책 설정 기능 테스트", + "description": "설정 > 휴가정책 메뉴의 휴가 정책 조회/수정/저장 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "설정", "level2": "휴가정책", - "expectedUrl": "/settings/vacation-policy" + "expectedUrl": "/settings/vacation-policy", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "update": { + "annualLeave": "15", + "halfDayEnabled": true, + "carryOverDays": "5", + "memo": "E2E 테스트 휴가정책" + }, + "restore": { + "annualLeave": "15", + "halfDayEnabled": true, + "carryOverDays": "5" + } + }, "steps": [ { "id": 1, @@ -33,38 +48,155 @@ "name": "필수 검증 #5: 목업 페이지 감지", "action": "verify_not_mockup", "checks": [ - "휴가 정책 설정 표시", - "연차/반차 설정 가능" + "휴가 정책 설정 폼 표시", + "연차 부여 기준 설정 가능", + "저장 버튼 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "휴가 정책 항목 확인", + "name": "휴가 정책 폼 구조 확인", "action": "verify_elements", "checks": [ - "연차 부여 기준", - "반차 사용 여부", - "휴가 유형 설정" + "연차 부여 기준 입력", + "반차 사용 여부 설정", + "휴가 이월 일수 설정", + "휴가 유형별 설정" ], - "expected": "휴가 정책 항목 표시" + "expected": "휴가 정책 폼 정상 표시" }, { "id": 4, - "name": "저장 버튼 확인", + "phase": "READ", + "name": "[READ] 현재 정책 값 확인", + "action": "verify_detail", + "checks": [ + "연차 부여 기준 표시", + "반차 사용 설정 표시", + "이월 일수 표시" + ], + "expected": "현재 정책 값 정상 표시" + }, + { + "id": 5, + "phase": "UPDATE", + "name": "[UPDATE] 연차 부여 기준 수정", + "action": "fill", + "target": "input[name*='annual'], input[placeholder*='연차']", + "value": "15", + "clear": true + }, + { + "id": 6, + "phase": "UPDATE", + "name": "[UPDATE] 반차 사용 설정", + "action": "click", + "target": "input[type='checkbox'][name*='half'], label:has-text('반차')", + "expected": { + "checkbox_toggled": true + } + }, + { + "id": 7, + "phase": "UPDATE", + "name": "[UPDATE] 이월 일수 수정", + "action": "fill", + "target": "input[name*='carryOver'], input[placeholder*='이월']", + "value": "5", + "clear": true + }, + { + "id": 8, + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 정책 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('적용')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/settings/vacation-policy", + "toast": "저장|적용|완료|성공" + }, + "expected": "휴가 정책 저장 완료" + }, + { + "id": 9, + "phase": "UPDATE", + "name": "[UPDATE] 저장 결과 확인", + "action": "verify_detail", + "checks": [ + "연차: 15", + "이월 일수: 5" + ], + "expected": "수정된 정책 반영" + }, + { + "id": 10, + "name": "휴가 유형 관리 확인", "action": "verify_elements", "checks": [ - "저장 버튼 존재" + "연차 유형 표시", + "병가 유형 표시", + "경조사 유형 표시" ], - "expected": "저장 버튼 표시" + "expected": "휴가 유형 목록 표시" + }, + { + "id": 11, + "phase": "CREATE", + "name": "[CREATE] 휴가 유형 추가 버튼 확인", + "action": "verify_elements", + "checks": [ + "휴가 유형 추가 버튼 존재" + ], + "expected": "추가 버튼 표시" + }, + { + "id": 12, + "name": "정책 적용 대상 확인", + "action": "verify_elements", + "checks": [ + "부서별 적용 설정", + "직급별 적용 설정" + ], + "expected": "적용 대상 설정 표시" + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/settings/vacation-policy", + "description": "휴가 정책 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/settings/vacation-policy", + "description": "휴가 정책 수정" + }, + { + "method": "GET", + "endpoint": "/api/v1/vacation-types", + "description": "휴가 유형 목록 조회" } ], "requiredVerifications": [ + { + "id": 2, + "name": "저장 버튼", + "steps": [8], + "criteria": "API 호출 + 성공 토스트 + 설정 반영" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "휴가 정책 설정, 저장 기능 확인" + "criteria": "휴가 정책 폼, 저장 버튼 존재" } - ] + ], + "rollbackPlan": { + "onUpdateFail": "페이지 새로고침으로 원래 값 복원", + "note": "설정 페이지는 수정 후 원복 테스트 권장" + } } diff --git a/settings-work-schedule.json b/settings-work-schedule.json index 6ad2eff..35358eb 100644 --- a/settings-work-schedule.json +++ b/settings-work-schedule.json @@ -5,17 +5,27 @@ "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, - "description": "설정 > 근무일정 메뉴의 근무일정 설정 기능 테스트", + "description": "설정 > 근무일정 메뉴의 근무일정 조회/수정/저장 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", "menuNavigation": { "level1": "설정", "level2": "근무일정", - "expectedUrl": "/settings/work-schedule" + "expectedUrl": "/settings/work-schedule", + "searchWithinParent": true, + "closeOtherMenus": true }, "auth": { "username": "TestUser5", "password": "password123!" }, + "testData": { + "update": { + "workDays": "월,화,수,목,금", + "startTime": "09:00", + "endTime": "18:00", + "breakTime": "60" + } + }, "steps": [ { "id": 1, @@ -33,38 +43,153 @@ "name": "필수 검증 #5: 목업 페이지 감지", "action": "verify_not_mockup", "checks": [ - "근무일정 캘린더 표시", - "근무 설정 가능" + "근무일정 설정 폼 표시", + "근무일 선택 가능", + "저장 버튼 존재" ], "expected": "정상 페이지 (목업 아님)" }, { "id": 3, - "name": "근무일정 항목 확인", + "name": "근무일정 폼 구조 확인", "action": "verify_elements", "checks": [ - "근무일 설정", - "휴무일 설정", - "주간 근무 시간" + "근무일 선택 (월~일)", + "출근 시간 입력", + "퇴근 시간 입력", + "휴게 시간 설정" ], - "expected": "근무일정 항목 표시" + "expected": "근무일정 폼 정상 표시" }, { "id": 4, - "name": "저장 버튼 확인", + "phase": "READ", + "name": "[READ] 현재 근무일정 확인", + "action": "verify_detail", + "checks": [ + "근무일 표시", + "출근 시간 표시", + "퇴근 시간 표시" + ], + "expected": "현재 근무일정 정상 표시" + }, + { + "id": 5, + "phase": "UPDATE", + "name": "[UPDATE] 출근 시간 수정", + "action": "fill", + "target": "input[name*='start'], input[type='time']:first-of-type", + "value": "09:00", + "clear": true + }, + { + "id": 6, + "phase": "UPDATE", + "name": "[UPDATE] 퇴근 시간 수정", + "action": "fill", + "target": "input[name*='end'], input[type='time']:last-of-type", + "value": "18:00", + "clear": true + }, + { + "id": 7, + "phase": "UPDATE", + "name": "[UPDATE] 휴게 시간 설정", + "action": "fill", + "target": "input[name*='break'], input[placeholder*='휴게']", + "value": "60", + "clear": true + }, + { + "id": 8, + "phase": "UPDATE", + "name": "[UPDATE] 필수 검증 #2: 근무일정 저장", + "action": "click", + "target": "button:has-text('저장'), button:has-text('적용')", + "critical": true, + "verify": { + "url_maintained": true, + "no_error_page": true, + "api_call": "PUT /api/v1/settings/work-schedule", + "toast": "저장|적용|완료|성공" + }, + "expected": "근무일정 저장 완료" + }, + { + "id": 9, + "phase": "UPDATE", + "name": "[UPDATE] 저장 결과 확인", + "action": "verify_detail", + "checks": [ + "출근: 09:00", + "퇴근: 18:00", + "휴게: 60분" + ], + "expected": "수정된 일정 반영" + }, + { + "id": 10, + "name": "휴무일 설정 확인", "action": "verify_elements", "checks": [ - "저장 버튼 존재" + "토요일 휴무 설정", + "일요일 휴무 설정", + "공휴일 자동 적용" ], - "expected": "저장 버튼 표시" + "expected": "휴무일 설정 표시" + }, + { + "id": 11, + "name": "주간 근무시간 계산 확인", + "action": "verify_elements", + "checks": [ + "주간 근무시간 합계 표시" + ], + "expected": "근무시간 자동 계산" + }, + { + "id": 12, + "name": "부서별 근무일정 확인", + "action": "verify_elements", + "checks": [ + "부서별 일정 설정 가능" + ], + "expected": "부서별 일정 표시" + } + ], + "expectedAPIs": [ + { + "method": "GET", + "endpoint": "/api/v1/settings/work-schedule", + "description": "근무일정 조회" + }, + { + "method": "PUT", + "endpoint": "/api/v1/settings/work-schedule", + "description": "근무일정 수정" + }, + { + "method": "GET", + "endpoint": "/api/v1/holidays", + "description": "공휴일 목록 조회" } ], "requiredVerifications": [ + { + "id": 2, + "name": "저장 버튼", + "steps": [8], + "criteria": "API 호출 + 성공 토스트 + 설정 반영" + }, { "id": 5, "name": "목업 페이지 감지", "steps": [2], - "criteria": "근무일정 설정, 저장 기능 확인" + "criteria": "근무일정 폼, 저장 버튼 존재" } - ] + ], + "rollbackPlan": { + "onUpdateFail": "페이지 새로고침으로 원래 값 복원", + "note": "설정 페이지는 수정 후 원복 테스트 권장" + } }