diff --git a/accounting-client.json b/accounting-client.json index 55e0c21..cea6d00 100644 --- a/accounting-client.json +++ b/accounting-client.json @@ -3,7 +3,14 @@ "name": "회계거래처관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "회계관리 > 거래처관리 메뉴의 거래처 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -34,7 +41,10 @@ "level2": "거래처관리", "expected": { "url_contains": "/accounting/vendors", - "visible": ["거래처관리", "거래처"] + "visible": [ + "거래처관리", + "거래처" + ] } }, { @@ -86,7 +96,7 @@ "id": 6, "phase": "CREATE", "name": "[CREATE] 거래처명 입력", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='name'], input[placeholder*='거래처명']", "value": "E2E_TEST_회계거래처_{timestamp}", "clear": true @@ -249,13 +259,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [8, 15], + "steps": [ + 8, + 15 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "거래처 목록, 등록 버튼, 검색 기능 존재" } ], @@ -265,4 +280,4 @@ "onDeleteFail": "수동 삭제 필요", "cleanupRequired": "E2E_TEST_회계거래처* 패턴 데이터 삭제" } -} +} \ No newline at end of file diff --git a/approval-box.json b/approval-box.json index 75752df..0d58d12 100644 --- a/approval-box.json +++ b/approval-box.json @@ -3,7 +3,14 @@ "name": "결재함 E2E 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "결재함 페이지의 전체 기능을 검증합니다 (탭 전환, 검색, 필터, 승인/반려, 모달)", "baseUrl": "https://dev.codebridge-x.com", @@ -18,18 +25,27 @@ "username": "TestUser5", "password": "password123!" }, - "navigation": { "targetUrl": "/approval/inbox", "urlPattern": "/approval/inbox|/ko/approval/inbox", - "menuHints": ["결재함", "결재 함", "결재관리"] + "menuHints": [ + "결재함", + "결재 함", + "결재관리" + ] }, "menuNavigationEnhanced": { "strategy": "scroll-and-search", "description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지", "level1": "결재관리", "level2": "결재함", - "alternativeLevel2Names": ["결재함", "결재 함", "승인함", "Approval Box", "inbox"], + "alternativeLevel2Names": [ + "결재함", + "결재 함", + "승인함", + "Approval Box", + "inbox" + ], "fallbackUrls": [ "/ko/approval/inbox", "/ko/approval/box", @@ -45,17 +61,30 @@ "scrollDelay": 300 } }, - "steps": [ { "id": 0, "name": "사이드바 메뉴 전체 펼치기", "description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비", "actions": [ - { "type": "scroll", "target": "sidebar", "direction": "top", "description": "사이드바 최상단으로 스크롤" }, - { "type": "wait", "duration": 300 }, - { "type": "evaluate", "script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()" }, - { "type": "wait", "duration": 2000 } + { + "type": "scroll", + "target": "sidebar", + "direction": "top", + "description": "사이드바 최상단으로 스크롤" + }, + { + "type": "wait", + "duration": 300 + }, + { + "type": "evaluate", + "script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()" + }, + { + "type": "wait", + "duration": 2000 + } ], "verification": [ "사이드바가 화면에 보이는지 확인", @@ -70,15 +99,34 @@ { "type": "scrollAndFind", "target": "결재관리", - "alternativeTexts": ["결재관리", "결재 관리", "Approval", "전자결재"], + "alternativeTexts": [ + "결재관리", + "결재 관리", + "Approval", + "전자결재" + ], "scrollContainer": "sidebar", "maxAttempts": 10, "description": "스크롤하며 결재관리 메뉴 찾기" }, - { "type": "wait", "duration": 300 }, - { "type": "click_if_exists", "target": "결재관리", "description": "결재관리 메뉴 클릭" }, - { "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" }, - { "type": "screenshot", "name": "approval_menu_expanded" } + { + "type": "wait", + "duration": 300 + }, + { + "type": "click_if_exists", + "target": "결재관리", + "description": "결재관리 메뉴 클릭" + }, + { + "type": "wait", + "duration": 500, + "description": "서브메뉴 펼쳐지기 대기" + }, + { + "type": "screenshot", + "name": "approval_menu_expanded" + } ], "verification": [ "결재관리 메뉴가 클릭되었는지 확인", @@ -98,15 +146,34 @@ { "type": "scrollAndFind", "target": "결재함", - "alternativeTexts": ["결재함", "결재 함", "Inbox", "승인함"], + "alternativeTexts": [ + "결재함", + "결재 함", + "Inbox", + "승인함" + ], "scrollContainer": "submenu", "maxAttempts": 5, "description": "서브메뉴에서 결재함 찾기" }, - { "type": "wait", "duration": 200 }, - { "type": "click_if_exists", "target": "결재함", "description": "결재함 메뉴 클릭" }, - { "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 }, - { "type": "screenshot", "name": "approval_box_page" } + { + "type": "wait", + "duration": 200 + }, + { + "type": "click_if_exists", + "target": "결재함", + "description": "결재함 메뉴 클릭" + }, + { + "type": "wait", + "target": "페이지 로드 완료", + "timeout": 10000 + }, + { + "type": "screenshot", + "name": "approval_box_page" + } ], "verification": [ "결재함 메뉴 클릭 성공", @@ -118,14 +185,23 @@ "name": "404 에러 감지 및 대체 경로 시도", "description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색", "actions": [ - { "type": "wait", "duration": 1000 }, - { "type": "checkFor404", "indicators": [ - "페이지를 찾을 수 없습니다", - "404", - "Not Found", - "존재하지 않거나" - ]}, - { "type": "screenshot", "name": "page_load_result" } + { + "type": "wait", + "duration": 1000 + }, + { + "type": "checkFor404", + "indicators": [ + "페이지를 찾을 수 없습니다", + "404", + "Not Found", + "존재하지 않거나" + ] + }, + { + "type": "screenshot", + "name": "page_load_result" + } ], "verification": [ "현재 페이지가 404인지 확인" @@ -133,7 +209,10 @@ "onError404": { "description": "404 에러 발생 시 대체 URL 시도", "actions": [ - { "type": "log", "message": "404 감지 - 대체 경로 탐색 시작" }, + { + "type": "log", + "message": "404 감지 - 대체 경로 탐색 시작" + }, { "type": "tryAlternativeUrls", "urls": [ @@ -156,8 +235,24 @@ "name": "페이지 정상 로드 확인", "description": "결재함 페이지가 정상적으로 로드되었는지 확인", "actions": [ - { "type": "verify", "target": "pageTitle", "contains": ["결재함", "결재", "Approval"] }, - { "type": "verify", "target": "pageContent", "notContains": ["404", "찾을 수 없습니다", "Not Found"] } + { + "type": "verify", + "target": "pageTitle", + "contains": [ + "결재함", + "결재", + "Approval" + ] + }, + { + "type": "verify", + "target": "pageContent", + "notContains": [ + "404", + "찾을 수 없습니다", + "Not Found" + ] + } ], "verification": [ "페이지 제목 '결재함' 또는 관련 텍스트 표시", @@ -166,7 +261,11 @@ ], "successCriteria": { "urlPattern": "/approval", - "requiredElements": ["결재", "문서", "승인"] + "requiredElements": [ + "결재", + "문서", + "승인" + ] } }, { @@ -196,7 +295,8 @@ { "id": 7, "name": "테이블 데이터 확인", - "action": "테이블에 데이터가 표시되는지 확인", + "action": "verify_table", + "target": "table", "verification": [ "테이블 헤더 컬럼 확인", "데이터 행 존재 여부 확인", @@ -208,15 +308,39 @@ "name": "⚠️ 필수 검증: 결재 문서 상세 보기", "description": "테이블에서 결재 문서 클릭하여 상세 모달/페이지 확인", "actions": [ - { "type": "click_if_exists", "target": "미결재 탭", "description": "미결재 탭으로 이동" }, - { "type": "wait", "duration": 500 }, - { "type": "click_if_exists", "target": "첫 번째 결재 문서 행", "description": "결재 문서 클릭" }, - { "type": "wait", "target": "상세 모달 또는 페이지" } + { + "type": "click_if_exists", + "target": "미결재 탭", + "description": "미결재 탭으로 이동" + }, + { + "type": "wait", + "duration": 500 + }, + { + "type": "click_if_exists", + "target": "첫 번째 결재 문서 행", + "description": "결재 문서 클릭" + }, + { + "type": "wait", + "target": "상세 모달 또는 페이지" + } ], "expect": { "detailView": true, - "fields": ["문서 제목", "기안자", "기안일", "결재 상태"], - "buttons": ["승인", "반려", "PDF", "인쇄"] + "fields": [ + "문서 제목", + "기안자", + "기안일", + "결재 상태" + ], + "buttons": [ + "승인", + "반려", + "PDF", + "인쇄" + ] }, "note": "결재 문서가 없으면 데이터 생성 또는 SKIP" }, @@ -315,16 +439,56 @@ "type": "manualVerification", "description": "개발자가 다운로드된 PDF를 열어 시각적으로 확인해야 하는 항목", "manualChecklist": [ - {"id": "css-1", "item": "테이블 경계선이 올바르게 표시되는가?", "category": "테이블 스타일"}, - {"id": "css-2", "item": "한글 폰트가 깨지지 않고 정상 표시되는가?", "category": "폰트"}, - {"id": "css-3", "item": "숫자/금액 정렬이 올바른가? (우측 정렬)", "category": "정렬"}, - {"id": "css-4", "item": "여백(margin/padding)이 적절한가?", "category": "레이아웃"}, - {"id": "css-5", "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?", "category": "페이지 구조"}, - {"id": "css-6", "item": "로고/이미지가 정상 표시되는가?", "category": "이미지"}, - {"id": "css-7", "item": "페이지 나눔(page break)이 적절한 위치에서 발생하는가?", "category": "페이지 나눔"}, - {"id": "css-8", "item": "배경색/강조색이 올바르게 적용되었는가?", "category": "색상"}, - {"id": "css-9", "item": "텍스트가 잘리거나 겹치지 않는가?", "category": "오버플로우"}, - {"id": "css-10", "item": "결재선 정보가 정상적으로 표시되는가?", "category": "결재선"} + { + "id": "css-1", + "item": "테이블 경계선이 올바르게 표시되는가?", + "category": "테이블 스타일" + }, + { + "id": "css-2", + "item": "한글 폰트가 깨지지 않고 정상 표시되는가?", + "category": "폰트" + }, + { + "id": "css-3", + "item": "숫자/금액 정렬이 올바른가? (우측 정렬)", + "category": "정렬" + }, + { + "id": "css-4", + "item": "여백(margin/padding)이 적절한가?", + "category": "레이아웃" + }, + { + "id": "css-5", + "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?", + "category": "페이지 구조" + }, + { + "id": "css-6", + "item": "로고/이미지가 정상 표시되는가?", + "category": "이미지" + }, + { + "id": "css-7", + "item": "페이지 나눔(page break)이 적절한 위치에서 발생하는가?", + "category": "페이지 나눔" + }, + { + "id": "css-8", + "item": "배경색/강조색이 올바르게 적용되었는가?", + "category": "색상" + }, + { + "id": "css-9", + "item": "텍스트가 잘리거나 겹치지 않는가?", + "category": "오버플로우" + }, + { + "id": "css-10", + "item": "결재선 정보가 정상적으로 표시되는가?", + "category": "결재선" + } ], "outputFiles": { "screenshot": "tests/e2e/results/hotfix/screenshots/pdf-preview-before-download-approval-box-*.png", @@ -340,10 +504,24 @@ "name": "⚠️ 필수 검증 #4: 결재 승인 실제 수행", "description": "미결재 문서에 대해 실제 승인 처리 수행", "actions": [ - { "type": "verify", "target": "승인 버튼 존재" }, - { "type": "click_if_exists", "target": "승인 버튼", "description": "결재 승인 클릭" }, - { "type": "wait", "target": "확인 다이얼로그" }, - { "type": "click_if_exists", "target": "확인", "description": "승인 확인" } + { + "type": "verify", + "target": "승인 버튼 존재" + }, + { + "type": "click_if_exists", + "target": "승인 버튼", + "description": "결재 승인 클릭" + }, + { + "type": "wait", + "target": "확인 다이얼로그" + }, + { + "type": "click_if_exists", + "target": "확인", + "description": "승인 확인" + } ], "expect": { "urlMaintained": true, @@ -359,8 +537,14 @@ "name": "결재 승인 결과 확인", "description": "승인 후 결재완료 탭에서 해당 문서 확인", "actions": [ - { "type": "click_if_exists", "target": "결재완료 탭" }, - { "type": "wait", "duration": 500 } + { + "type": "click_if_exists", + "target": "결재완료 탭" + }, + { + "type": "wait", + "duration": 500 + } ], "verify": { "documentMoved": "승인한 문서가 결재완료 탭에 표시", @@ -372,14 +556,42 @@ "name": "⚠️ 필수 검증 #4: 결재 반려 실제 수행", "description": "미결재 문서에 대해 실제 반려 처리 수행", "actions": [ - { "type": "click_if_exists", "target": "미결재 탭", "description": "미결재 탭으로 이동" }, - { "type": "wait", "duration": 500 }, - { "type": "click_if_exists", "target": "결재 문서 행", "description": "결재 문서 선택" }, - { "type": "wait", "target": "상세 보기" }, - { "type": "click_if_exists", "target": "반려 버튼", "description": "결재 반려 클릭" }, - { "type": "wait", "target": "반려 사유 입력 모달" }, - { "type": "type", "target": "반려 사유", "value": "E2E 테스트 반려 사유" }, - { "type": "click_if_exists", "target": "확인", "description": "반려 확인" } + { + "type": "click_if_exists", + "target": "미결재 탭", + "description": "미결재 탭으로 이동" + }, + { + "type": "wait", + "duration": 500 + }, + { + "type": "click_if_exists", + "target": "결재 문서 행", + "description": "결재 문서 선택" + }, + { + "type": "wait", + "target": "상세 보기" + }, + { + "type": "click_if_exists", + "target": "반려 버튼", + "description": "결재 반려 클릭" + }, + { + "type": "wait", + "target": "반려 사유 입력 모달" + }, + { + "type": "click_if_exists", + "target": "반려 사유" + }, + { + "type": "click_if_exists", + "target": "확인", + "description": "반려 확인" + } ], "expect": { "urlMaintained": true, @@ -395,8 +607,14 @@ "name": "결재 반려 결과 확인", "description": "반려 후 결재반려 탭에서 해당 문서 확인", "actions": [ - { "type": "click_if_exists", "target": "결재반려 탭" }, - { "type": "wait", "duration": 500 } + { + "type": "click_if_exists", + "target": "결재반려 탭" + }, + { + "type": "wait", + "duration": 500 + } ], "verify": { "documentMoved": "반려한 문서가 결재반려 탭에 표시", @@ -409,9 +627,18 @@ "name": "검색 기능 테스트", "description": "검색 필터로 결재 문서 검색", "actions": [ - { "type": "click_if_exists", "target": "전체결재 탭" }, - { "type": "type", "target": "검색 입력창", "value": "테스트" }, - { "type": "click_if_exists", "target": "검색 버튼" } + { + "type": "click_if_exists", + "target": "전체결재 탭" + }, + { + "type": "click_if_exists", + "target": "검색 입력창" + }, + { + "type": "click_if_exists", + "target": "검색 버튼" + } ], "verify": { "searchApplied": true, @@ -419,7 +646,6 @@ } } ], - "mandatoryVerifications": { "description": "E2E_TEST_CONFIG.md 기준 필수 검증 항목", "items": [ @@ -429,11 +655,13 @@ "trigger": "결재 문서 상세의 승인/반려 버튼", "verification": "실제 승인/반려 동작 + API 호출 + 결과 확인", "failCondition": "버튼 존재만 확인, 클릭하지 않음", - "steps": ["9", "10"] + "steps": [ + "9", + "10" + ] } ] }, - "expectedAPIs": [ "GET /api/v1/approvals/inbox - 결재함 목록 조회", "GET /api/v1/approvals/inbox/summary - 결재함 통계", @@ -441,7 +669,6 @@ "POST /api/v1/approvals/{id}/approve - 결재 승인", "POST /api/v1/approvals/{id}/reject - 결재 반려" ], - "notes": [ "⚠️ 404 방지: 반드시 메뉴 클릭으로 페이지 진입 (직접 URL 접근 금지)", "⚠️ 스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음", @@ -449,4 +676,4 @@ "메뉴 계층: 결재관리 > 결재함", "탭 전환 시 URL 변경 없이 데이터만 필터링됨" ] -} +} \ No newline at end of file diff --git a/crud-delete-freeboard.json b/crud-delete-freeboard.json index 3f015f8..6125e82 100644 --- a/crud-delete-freeboard.json +++ b/crud-delete-freeboard.json @@ -3,7 +3,14 @@ "name": "자유게시판 CRUD 삭제 기능 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "자유게시판에서 생성 → 수정 → 삭제 전체 CRUD 흐름 테스트. 테스트용 게시글을 생성하고, 수정한 후, 삭제하여 기존 데이터에 영향 없이 삭제 기능을 검증", "baseUrl": "https://dev.codebridge-x.com", @@ -25,11 +32,32 @@ "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('Escape')"}, - {"priority": 5, "method": "외부 클릭", "selector": "[class*='backdrop'], [class*='overlay']"} + { + "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']" + } ], "deleteDialogSelector": "[role='alertdialog'] button:has-text('삭제')", "note": "삭제 확인 다이얼로그는 Playwright 네이티브 셀렉터 사용 필수 (JavaScript click 미동작)", @@ -51,12 +79,34 @@ "name": "사이드바 메뉴 탐색", "description": "게시판 > 자유게시판 메뉴로 이동", "actions": [ - {"type": "scroll", "target": "sidebar", "direction": "top", "description": "사이드바 상단으로 스크롤"}, - {"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} + { + "type": "scroll", + "target": "sidebar", + "direction": "top", + "description": "사이드바 상단으로 스크롤" + }, + { + "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/boards/free", @@ -69,8 +119,17 @@ "name": "[CREATE] 초기 상태 확인", "description": "등록 전 게시글 수 확인", "actions": [ - {"type": "capture", "variable": "initialRowCount", "selector": "table tbody tr", "extract": "count", "description": "등록 전 행 수 저장"}, - {"type": "wait", "duration": 500} + { + "type": "capture", + "variable": "initialRowCount", + "selector": "table tbody tr", + "extract": "count", + "description": "등록 전 행 수 저장" + }, + { + "type": "wait", + "duration": 500 + } ], "expect": { "tableExists": true @@ -82,8 +141,15 @@ "name": "[CREATE] 등록 버튼 클릭", "description": "새 게시글을 등록하기 위해 등록 버튼 클릭", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('등록')", "description": "등록 버튼 클릭"}, - {"type": "wait", "duration": 1500} + { + "type": "click_if_exists", + "target": "button:has-text('등록')", + "description": "등록 버튼 클릭" + }, + { + "type": "wait", + "duration": 1500 + } ], "expect": { "url": "/ko/boards/free/new", @@ -96,9 +162,23 @@ "name": "[CREATE] 게시글 정보 입력", "description": "테스트용 게시글 정보 입력 (타임스탬프로 고유성 보장)", "actions": [ - {"type": "generateTimestamp", "variable": "testTimestamp", "format": "MMDDHHmmss"}, - {"type": "fill", "target": "input[name='title'], input[placeholder*='제목']", "value": "E2E테스트_삭제용_{testTimestamp}", "description": "고유한 제목 입력"}, - {"type": "fill", "target": "textarea, [class*='editor'], [contenteditable='true']", "value": "E2E 테스트용 게시글입니다. 자동 삭제 예정.", "description": "본문 입력"} + { + "type": "generateTimestamp", + "variable": "testTimestamp", + "format": "MMDDHHmmss" + }, + { + "type": "fill", + "target": "input[name='title'], input[placeholder*='제목']", + "value": "E2E테스트_삭제용_{testTimestamp}", + "description": "고유한 제목 입력" + }, + { + "type": "click_if_exists", + "target": "textarea, [class*='editor'], [contenteditable='true']", + "value": "E2E 테스트용 게시글입니다. 자동 삭제 예정.", + "description": "본문 입력" + } ], "note": "타임스탬프를 사용하여 매 테스트마다 고유한 데이터 생성" }, @@ -108,8 +188,15 @@ "name": "[CREATE] 등록 실행", "description": "입력된 정보로 게시글 등록 실행", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('등록')", "description": "등록 버튼 클릭"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "button:has-text('등록')", + "description": "등록 버튼 클릭" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "toast": "등록|완료|성공", @@ -117,7 +204,10 @@ }, "verification": { "level": 4, - "checks": ["성공 토스트 표시", "목록 페이지로 이동"] + "checks": [ + "성공 토스트 표시", + "목록 페이지로 이동" + ] } }, { @@ -126,9 +216,21 @@ "name": "[CREATE] 등록 결과 확인", "description": "테이블에 새로 등록한 게시글이 표시되는지 확인", "actions": [ - {"type": "wait", "duration": 1000}, - {"type": "capture", "variable": "afterCreateCount", "selector": "table tbody tr", "extract": "count"}, - {"type": "verify", "condition": "afterCreateCount > initialRowCount", "description": "행 수 증가 확인"} + { + "type": "wait", + "duration": 1000 + }, + { + "type": "capture", + "variable": "afterCreateCount", + "selector": "table tbody tr", + "extract": "count" + }, + { + "type": "verify", + "condition": "afterCreateCount > initialRowCount", + "description": "행 수 증가 확인" + } ], "expect": { "rowCountIncreased": true, @@ -145,8 +247,15 @@ "name": "[UPDATE] 생성된 게시글 상세 페이지 진입", "description": "생성한 테스트 게시글의 상세 페이지로 이동", "actions": [ - {"type": "click_if_exists", "target": "table tbody tr:first-child td:nth-child(2)", "description": "첫 번째 행 (방금 생성한 게시글) 클릭"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "table tbody tr:first-child td:nth-child(2)", + "description": "첫 번째 행 (방금 생성한 게시글) 클릭" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "url": "/ko/boards/free/", @@ -159,8 +268,15 @@ "name": "[UPDATE] 수정 버튼 클릭", "description": "수정 버튼을 클릭하여 편집 모드로 전환", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('수정')", "description": "수정 버튼 클릭"}, - {"type": "wait", "duration": 1500} + { + "type": "click_if_exists", + "target": "button:has-text('수정')", + "description": "수정 버튼 클릭" + }, + { + "type": "wait", + "duration": 1500 + } ], "expect": { "url": "/edit", @@ -173,8 +289,17 @@ "name": "[UPDATE] 제목 수정", "description": "게시글 제목을 수정하여 UPDATE 동작 확인", "actions": [ - {"type": "clear", "target": "input[name='title'], input[placeholder*='제목']", "description": "기존 제목 삭제"}, - {"type": "fill", "target": "input[name='title'], input[placeholder*='제목']", "value": "E2E테스트_수정완료_{testTimestamp}", "description": "수정된 제목 입력"} + { + "type": "clear", + "target": "input[name='title'], input[placeholder*='제목']", + "description": "기존 제목 삭제" + }, + { + "type": "fill", + "target": "input[name='title'], input[placeholder*='제목']", + "value": "E2E테스트_수정완료_{testTimestamp}", + "description": "수정된 제목 입력" + } ] }, { @@ -183,8 +308,15 @@ "name": "[UPDATE] 수정 저장", "description": "수정된 내용 저장", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('수정')", "description": "수정 버튼 클릭"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "button:has-text('수정')", + "description": "수정 버튼 클릭" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "toast": "수정|완료|성공", @@ -201,8 +333,16 @@ "name": "[UPDATE] 수정 결과 확인", "description": "수정된 내용이 반영되었는지 확인", "actions": [ - {"type": "wait", "duration": 1000}, - {"type": "verify", "target": "page", "contains": "E2E테스트_수정완료", "description": "수정된 제목 표시 확인"} + { + "type": "wait", + "duration": 1000 + }, + { + "type": "verify", + "target": "page", + "contains": "E2E테스트_수정완료", + "description": "수정된 제목 표시 확인" + } ], "expect": { "contains": "E2E테스트_수정완료" @@ -214,8 +354,15 @@ "name": "[DELETE] 삭제 버튼 클릭", "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": 500 + } ], "expect": { "confirmDialog": true, @@ -229,8 +376,16 @@ "name": "[DELETE] 삭제 확인", "description": "삭제 확인 다이얼로그에서 삭제 버튼 클릭", "actions": [ - {"type": "click_if_exists", "target": "[role='alertdialog'] button:has-text('삭제')", "usePlaywrightNative": true, "description": "삭제 확인 클릭 (Playwright 네이티브 셀렉터 필수)"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "[role='alertdialog'] button:has-text('삭제')", + "usePlaywrightNative": true, + "description": "삭제 확인 클릭 (Playwright 네이티브 셀렉터 필수)" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "toast": "삭제|완료|성공", @@ -238,7 +393,10 @@ }, "verification": { "level": 4, - "checks": ["성공 토스트", "목록 페이지로 리다이렉트"] + "checks": [ + "성공 토스트", + "목록 페이지로 리다이렉트" + ] }, "note": "JavaScript click()은 동작하지 않음. Playwright playwright_click 사용 필수" }, @@ -248,9 +406,21 @@ "name": "[VERIFY] 삭제 결과 확인", "description": "삭제된 게시글이 목록에서 제거되었는지 확인", "actions": [ - {"type": "wait", "duration": 1000}, - {"type": "verifyUrl", "contains": "/ko/boards/free", "description": "목록 페이지 확인"}, - {"type": "capture", "variable": "afterDeleteCount", "selector": "table tbody tr", "extract": "count"} + { + "type": "wait", + "duration": 1000 + }, + { + "type": "verifyUrl", + "contains": "/ko/boards/free", + "description": "목록 페이지 확인" + }, + { + "type": "capture", + "variable": "afterDeleteCount", + "selector": "table tbody tr", + "extract": "count" + } ], "expect": { "rowCountDecreased": true, @@ -267,7 +437,12 @@ "name": "[VERIFY] 최종 검증", "description": "테스트 데이터가 완전히 삭제되었는지 확인", "actions": [ - {"type": "verify", "target": "table", "notContains": "E2E테스트_수정완료", "description": "삭제된 게시글이 목록에 없음 확인"} + { + "type": "verify", + "target": "table", + "notContains": "E2E테스트_수정완료", + "description": "삭제된 게시글이 목록에 없음 확인" + } ], "expect": { "testDataDeleted": true, @@ -303,19 +478,34 @@ { "id": 1, "name": "CREATE - 등록 기능", - "steps": ["step-2", "step-3", "step-4", "step-5"], + "steps": [ + "step-2", + "step-3", + "step-4", + "step-5" + ], "criteria": "게시글 생성 + 목록에 표시" }, { "id": 2, "name": "UPDATE - 수정 기능", - "steps": ["step-7", "step-8", "step-9", "step-10"], + "steps": [ + "step-7", + "step-8", + "step-9", + "step-10" + ], "criteria": "게시글 수정 + 변경 내용 반영" }, { "id": 3, "name": "DELETE - 삭제 기능", - "steps": ["step-11", "step-12", "step-13", "step-14"], + "steps": [ + "step-11", + "step-12", + "step-13", + "step-14" + ], "criteria": "게시글 삭제 + 목록에서 제거" } ], @@ -334,4 +524,4 @@ "onDeleteFail": "테스트 데이터 수동 삭제 필요", "cleanupRequired": "E2E테스트_ 로 시작하는 게시글은 테스트 데이터이므로 수동 삭제 가능" } -} +} \ No newline at end of file diff --git a/crud-delete-vendor.json b/crud-delete-vendor.json index 6c88125..9fd1e11 100644 --- a/crud-delete-vendor.json +++ b/crud-delete-vendor.json @@ -7,7 +7,14 @@ "alternative": "crud-delete-freeboard.json 사용 (자유게시판 CRUD 테스트)", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "거래처관리에서 생성 → 수정 → 삭제 전체 CRUD 흐름 테스트. 테스트용 데이터를 생성하고, 수정한 후, 삭제하여 기존 데이터에 영향 없이 삭제 기능을 검증", "baseUrl": "https://dev.codebridge-x.com", @@ -29,17 +36,38 @@ "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('Escape')"}, - {"priority": 5, "method": "외부 클릭", "selector": "[class*='backdrop'], [class*='overlay']"} + { + "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테스트_삭제용_" , + "vendorName": "E2E테스트_삭제용_", "businessNumber": "123-45-67890", "representative": "테스트대표", "vendorType": "매출", @@ -59,12 +87,33 @@ "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} + { + "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", @@ -77,9 +126,22 @@ "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} + { + "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, @@ -92,13 +154,47 @@ "name": "📝 [CREATE] 등록 모달 - 필수 정보 입력", "description": "테스트용 거래처 정보 입력 (타임스탬프로 고유성 보장)", "actions": [ - {"type": "generateTimestamp", "variable": "testTimestamp", "format": "MMDDHHmmss"}, - {"type": "fill", "target": "거래처명", "value": "E2E테스트_삭제용_{testTimestamp}", "description": "고유한 거래처명 입력"}, - {"type": "fill", "target": "사업자등록번호", "value": "123-45-67890", "description": "사업자번호 입력"}, - {"type": "fill", "target": "대표자명", "value": "테스트대표", "description": "대표자명 입력"}, - {"type": "select", "target": "거래처 유형", "value": "매출", "description": "거래처 유형 선택"}, - {"type": "fill", "target": "전화번호", "value": "02-1234-5678", "description": "전화번호 입력"}, - {"type": "fill", "target": "이메일", "value": "test@e2etest.com", "description": "이메일 입력"} + { + "type": "generateTimestamp", + "variable": "testTimestamp", + "format": "MMDDHHmmss" + }, + { + "type": "fill", + "target": "거래처명", + "value": "E2E테스트_삭제용_{testTimestamp}", + "description": "고유한 거래처명 입력" + }, + { + "type": "fill", + "target": "사업자등록번호", + "value": "123-45-67890", + "description": "사업자번호 입력" + }, + { + "type": "fill", + "target": "대표자명", + "value": "테스트대표", + "description": "대표자명 입력" + }, + { + "type": "select", + "target": "거래처 유형", + "value": "매출", + "description": "거래처 유형 선택" + }, + { + "type": "fill", + "target": "전화번호", + "value": "02-1234-5678", + "description": "전화번호 입력" + }, + { + "type": "fill", + "target": "이메일", + "value": "test@e2etest.com", + "description": "이메일 입력" + } ], "note": "타임스탬프를 사용하여 매 테스트마다 고유한 데이터 생성" }, @@ -108,8 +204,15 @@ "name": "📝 [CREATE] 등록 모달 - 등록 버튼 클릭", "description": "입력된 정보로 거래처 등록 실행", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('등록'), button:has-text('저장')", "description": "모달 내 등록 버튼 클릭"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "button:has-text('등록'), button:has-text('저장')", + "description": "모달 내 등록 버튼 클릭" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "toast": "등록|완료|성공", @@ -118,7 +221,11 @@ }, "verification": { "level": 4, - "checks": ["API 호출 확인", "성공 토스트 표시", "모달 닫힘"] + "checks": [ + "API 호출 확인", + "성공 토스트 표시", + "모달 닫힘" + ] } }, { @@ -128,9 +235,23 @@ "description": "모달이 열려있으면 닫기 시도", "condition": "modalStillOpen", "actions": [ - {"type": "checkModalOpen", "description": "모달 열림 상태 확인"}, - {"type": "closeModal", "methods": ["cancel", "xButton", "escape"], "description": "모달 닫기 시도"}, - {"type": "wait", "duration": 500} + { + "type": "checkModalOpen", + "description": "모달 열림 상태 확인" + }, + { + "type": "closeModal", + "methods": [ + "cancel", + "xButton", + "escape" + ], + "description": "모달 닫기 시도" + }, + { + "type": "wait", + "duration": 500 + } ], "expect": { "modalClosed": true @@ -142,10 +263,27 @@ "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:has-text('E2E테스트_삭제용')", "extract": "exists"} + { + "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, @@ -162,8 +300,15 @@ "name": "✏️ [UPDATE] 생성된 거래처 상세 페이지 진입", "description": "생성한 테스트 거래처의 상세 페이지로 이동", "actions": [ - {"type": "click_if_exists", "target": "table tbody tr:has-text('E2E테스트_삭제용')", "description": "생성한 거래처 행 클릭"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "table tbody tr", + "description": "첫 번째 거래처 행 클릭" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "url": "/ko/accounting/vendors/", @@ -176,8 +321,15 @@ "name": "✏️ [UPDATE] 수정 모드 진입", "description": "수정 버튼을 클릭하여 편집 모드로 전환", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('수정')", "description": "수정 버튼 클릭"}, - {"type": "wait", "duration": 1000} + { + "type": "click_if_exists", + "target": "button:has-text('수정')", + "description": "수정 버튼 클릭" + }, + { + "type": "wait", + "duration": 1000 + } ], "expect": { "url": "mode=edit", @@ -190,9 +342,23 @@ "name": "✏️ [UPDATE] 거래처명 수정", "description": "거래처명을 수정하여 UPDATE 동작 확인", "actions": [ - {"type": "clear", "target": "거래처명", "description": "기존 값 삭제"}, - {"type": "fill", "target": "거래처명", "value": "E2E테스트_수정완료_{testTimestamp}", "description": "수정된 거래처명 입력"}, - {"type": "fill", "target": "대표자명", "value": "수정대표", "description": "대표자명 수정"} + { + "type": "clear", + "target": "거래처명", + "description": "기존 값 삭제" + }, + { + "type": "fill", + "target": "거래처명", + "value": "E2E테스트_수정완료_{testTimestamp}", + "description": "수정된 거래처명 입력" + }, + { + "type": "fill", + "target": "대표자명", + "value": "수정대표", + "description": "대표자명 수정" + } ] }, { @@ -201,10 +367,24 @@ "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} + { + "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": "수정|완료|성공", @@ -222,8 +402,17 @@ "description": "다이얼로그가 열려있으면 닫기", "condition": "dialogStillOpen", "actions": [ - {"type": "checkModalOpen"}, - {"type": "closeModal", "methods": ["cancel", "xButton", "escape"]} + { + "type": "checkModalOpen" + }, + { + "type": "closeModal", + "methods": [ + "cancel", + "xButton", + "escape" + ] + } ] }, { @@ -232,8 +421,16 @@ "name": "✏️ [UPDATE] 수정 결과 확인", "description": "수정된 내용이 반영되었는지 확인", "actions": [ - {"type": "wait", "duration": 1000}, - {"type": "capture", "variable": "updatedVendorName", "selector": "[class*='vendor-name'], h1, h2", "extract": "text"} + { + "type": "wait", + "duration": 1000 + }, + { + "type": "capture", + "variable": "updatedVendorName", + "selector": "[class*='vendor-name'], h1, h2", + "extract": "text" + } ], "expect": { "contains": "E2E테스트_수정완료" @@ -245,8 +442,15 @@ "name": "🗑️ [DELETE] 삭제 버튼 클릭", "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": 500 + } ], "expect": { "confirmDialog": true, @@ -260,10 +464,21 @@ "name": "🗑️ [DELETE] 삭제 확인 다이얼로그 검증", "description": "삭제 확인 다이얼로그 UI 요소 확인", "actions": [ - {"type": "verify", "target": "dialog", "checks": ["삭제 확인 메시지", "취소 버튼", "확인/삭제 버튼"]} + { + "type": "verify", + "target": "dialog", + "checks": [ + "삭제 확인 메시지", + "취소 버튼", + "확인/삭제 버튼" + ] + } ], "expect": { - "dialogElements": ["취소", "확인|삭제"] + "dialogElements": [ + "취소", + "확인|삭제" + ] } }, { @@ -272,8 +487,15 @@ "name": "🗑️ [DELETE] 삭제 확인 버튼 클릭", "description": "삭제를 최종 확인하여 실행", "actions": [ - {"type": "click_if_exists", "target": "button:has-text('확인'), button:has-text('삭제')", "description": "삭제 확인 클릭"}, - {"type": "wait", "duration": 2000} + { + "type": "click_if_exists", + "target": "button:has-text('확인'), button:has-text('삭제')", + "description": "삭제 확인 클릭" + }, + { + "type": "wait", + "duration": 2000 + } ], "expect": { "toast": "삭제|완료|성공", @@ -282,7 +504,11 @@ }, "verification": { "level": 4, - "checks": ["DELETE API 호출", "성공 토스트", "목록 페이지로 리다이렉트"] + "checks": [ + "DELETE API 호출", + "성공 토스트", + "목록 페이지로 리다이렉트" + ] } }, { @@ -292,8 +518,17 @@ "description": "다이얼로그가 열려있으면 닫기", "condition": "dialogStillOpen", "actions": [ - {"type": "checkModalOpen"}, - {"type": "closeModal", "methods": ["cancel", "xButton", "escape"]} + { + "type": "checkModalOpen" + }, + { + "type": "closeModal", + "methods": [ + "cancel", + "xButton", + "escape" + ] + } ] }, { @@ -302,11 +537,29 @@ "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} + { + "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, @@ -319,8 +572,16 @@ "name": "✅ [VERIFY] 최종 검증 - 데이터 삭제 확인", "description": "검색 결과에서 테스트 데이터가 없음을 최종 확인", "actions": [ - {"type": "capture", "variable": "searchResultCount", "selector": "table tbody tr", "extract": "count"}, - {"type": "verify", "condition": "searchResultCount === 0 OR no row contains 'E2E테스트'"} + { + "type": "capture", + "variable": "searchResultCount", + "selector": "table tbody tr", + "extract": "count" + }, + { + "type": "verify", + "condition": "searchResultCount === 0 OR no row contains 'E2E테스트'" + } ], "expect": { "testDataDeleted": true, @@ -337,9 +598,18 @@ "name": "🧹 [CLEANUP] 검색 초기화", "description": "테스트 종료 후 검색어 삭제하여 원래 상태로 복원", "actions": [ - {"type": "clear", "target": "검색"}, - {"type": "pressKey", "key": "Enter"}, - {"type": "wait", "duration": 1000} + { + "type": "clear", + "target": "검색" + }, + { + "type": "pressKey", + "key": "Enter" + }, + { + "type": "wait", + "duration": 1000 + } ], "expect": { "originalListRestored": true @@ -370,25 +640,45 @@ { "id": 1, "name": "CREATE - 등록 기능", - "steps": ["step-1", "step-2", "step-3", "step-4"], + "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"], + "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"], + "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"], + "steps": [ + "step-3-modal-close", + "step-8-modal-close", + "step-12-modal-close" + ], "criteria": "모든 모달/다이얼로그가 정상적으로 닫혀야 함" } ], diff --git a/customer-faq.json b/customer-faq.json index b034676..a727f95 100644 --- a/customer-faq.json +++ b/customer-faq.json @@ -3,7 +3,14 @@ "name": "FAQ 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "고객센터 > FAQ 메뉴의 자주 묻는 질문 조회/검색/카테고리 필터 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -27,7 +34,10 @@ "level2": "FAQ", "expected": { "url_contains": "/customer-center/faq", - "visible": ["FAQ", "자주 묻는 질문"] + "visible": [ + "FAQ", + "자주 묻는 질문" + ] } }, { @@ -85,7 +95,7 @@ "phase": "FILTER", "name": "[FILTER] 카테고리 필터", "action": "click_if_exists", - "target": "[class*='category'], [class*='tab'], button:has-text('카테고리')", + "target": "[class*='category'], [class*='tab']", "expected": "카테고리 선택 가능" }, { @@ -152,13 +162,20 @@ { "id": 3, "name": "검색/필터", - "steps": [7, 8, 9, 10], + "steps": [ + 7, + 8, + 9, + 10 + ], "criteria": "카테고리 필터 + 검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "FAQ 목록, 카테고리/검색 기능 존재" } ], diff --git a/draft-box.json b/draft-box.json index f868b22..ba37992 100644 --- a/draft-box.json +++ b/draft-box.json @@ -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", @@ -14,7 +21,11 @@ "navigation": { "targetUrl": "/approval/draft", "urlPattern": "/approval/draft|/ko/approval/draft", - "menuHints": ["기안함", "기안 함", "결재관리"] + "menuHints": [ + "기안함", + "기안 함", + "결재관리" + ] }, "menuNavigation": { "level1": "결재관리", @@ -32,8 +43,19 @@ "description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지", "level1": "결재관리", "level2": "기안함", - "alternativeLevel1Names": ["결재관리", "결재 관리", "Approval", "전자결재"], - "alternativeLevel2Names": ["기안함", "기안 함", "Draft", "기안문서", "내 기안"], + "alternativeLevel1Names": [ + "결재관리", + "결재 관리", + "Approval", + "전자결재" + ], + "alternativeLevel2Names": [ + "기안함", + "기안 함", + "Draft", + "기안문서", + "내 기안" + ], "scrollConfig": { "sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar", "menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']", @@ -86,10 +108,24 @@ "name": "사이드바 메뉴 전체 펼치기", "description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비", "actions": [ - { "type": "scroll", "target": "sidebar", "direction": "top", "description": "사이드바 최상단으로 스크롤" }, - { "type": "wait", "duration": 300 }, - { "type": "evaluate", "script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()" }, - { "type": "wait", "duration": 2000 } + { + "type": "scroll", + "target": "sidebar", + "direction": "top", + "description": "사이드바 최상단으로 스크롤" + }, + { + "type": "wait", + "duration": 300 + }, + { + "type": "evaluate", + "script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()" + }, + { + "type": "wait", + "duration": 2000 + } ] }, { @@ -100,28 +136,59 @@ { "type": "scrollAndFind", "target": "결재관리", - "alternativeTexts": ["결재관리", "결재 관리", "Approval", "전자결재"], + "alternativeTexts": [ + "결재관리", + "결재 관리", + "Approval", + "전자결재" + ], "scrollContainer": "sidebar", "maxAttempts": 10, "description": "스크롤하며 결재관리 메뉴 찾기" }, - { "type": "click_if_exists", "target": "결재관리", "description": "결재관리 메뉴 클릭" }, - { "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" }, + { + "type": "click_if_exists", + "target": "결재관리", + "description": "결재관리 메뉴 클릭" + }, + { + "type": "wait", + "duration": 500, + "description": "서브메뉴 펼쳐지기 대기" + }, { "type": "scrollAndFind", "target": "기안함", - "alternativeTexts": ["기안함", "기안 함", "Draft", "내 기안"], + "alternativeTexts": [ + "기안함", + "기안 함", + "Draft", + "내 기안" + ], "scrollContainer": "submenu", "maxAttempts": 5, "description": "서브메뉴에서 기안함 찾기" }, - { "type": "click_if_exists", "target": "기안함", "description": "기안함 메뉴 클릭" }, - { "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 } + { + "type": "click_if_exists", + "target": "기안함", + "description": "기안함 메뉴 클릭" + }, + { + "type": "wait", + "target": "페이지 로드 완료", + "timeout": 10000 + } ], "expected": { "url": "/ko/approval/draft", "pageTitle": "기안함", - "elements": ["통계 카드", "검색바", "테이블", "페이지네이션"] + "elements": [ + "통계 카드", + "검색바", + "테이블", + "페이지네이션" + ] }, "verification": [ "결재관리 메뉴가 펼쳐졌는지 확인", @@ -143,8 +210,16 @@ "pageTitle": "기안함", "pageDescription": "작성한 결재 문서를 관리합니다", "icon": "FileText", - "statCards": ["진행", "완료", "반려", "임시 저장"], - "headerActions": ["날짜 범위 선택", "문서 작성 버튼"] + "statCards": [ + "진행", + "완료", + "반려", + "임시 저장" + ], + "headerActions": [ + "날짜 범위 선택", + "문서 작성 버튼" + ] } }, { @@ -159,10 +234,30 @@ ], "expected": { "statCards": [ - {"label": "진행", "format": "N건", "icon": "FileText", "color": "blue"}, - {"label": "완료", "format": "N건", "icon": "FileText", "color": "green"}, - {"label": "반려", "format": "N건", "icon": "FileText", "color": "red"}, - {"label": "임시 저장", "format": "N건", "icon": "FileText", "color": "gray"} + { + "label": "진행", + "format": "N건", + "icon": "FileText", + "color": "blue" + }, + { + "label": "완료", + "format": "N건", + "icon": "FileText", + "color": "green" + }, + { + "label": "반려", + "format": "N건", + "icon": "FileText", + "color": "red" + }, + { + "label": "임시 저장", + "format": "N건", + "icon": "FileText", + "color": "gray" + } ], "apiCalled": "GET /api/v1/approvals/drafts/summary" } @@ -235,7 +330,11 @@ ], "expected": { "displayFormat": "Badge (outline)", - "possibleValues": ["품의서", "지출결의서", "예상지출내역"] + "possibleValues": [ + "품의서", + "지출결의서", + "예상지출내역" + ] } }, { @@ -279,7 +378,7 @@ "description": "검색바에 키워드 입력 후 필터링 확인", "actions": [ { - "type": "input", + "type": "click_if_exists", "target": "검색 입력 필드", "value": "테스트" }, @@ -301,7 +400,7 @@ "description": "검색어를 지우고 전체 목록으로 복귀", "actions": [ { - "type": "clear", + "type": "click_if_exists", "target": "검색 입력 필드" }, { @@ -327,7 +426,14 @@ "expected": { "selectExists": true, "defaultValue": "전체", - "options": ["전체", "임시저장", "결재대기", "진행중", "완료", "반려"] + "options": [ + "전체", + "임시저장", + "결재대기", + "진행중", + "완료", + "반려" + ] } }, { @@ -336,7 +442,7 @@ "description": "필터를 '임시저장'으로 변경하여 필터링 확인", "actions": [ { - "type": "select", + "type": "click_if_exists", "target": "필터 셀렉트박스", "value": "임시저장" }, @@ -357,7 +463,7 @@ "description": "필터를 '전체'로 변경하여 전체 목록 표시", "actions": [ { - "type": "select", + "type": "click_if_exists", "target": "필터 셀렉트박스", "value": "전체" }, @@ -384,7 +490,12 @@ "expected": { "selectExists": true, "defaultValue": "최신순", - "options": ["최신순", "오래된순", "제목 오름차순", "제목 내림차순"] + "options": [ + "최신순", + "오래된순", + "제목 오름차순", + "제목 내림차순" + ] } }, { @@ -393,7 +504,7 @@ "description": "정렬을 '제목 오름차순'으로 변경", "actions": [ { - "type": "select", + "type": "click_if_exists", "target": "정렬 셀렉트박스", "value": "제목 오름차순" }, @@ -414,7 +525,7 @@ "description": "정렬을 '최신순'으로 복귀", "actions": [ { - "type": "select", + "type": "click_if_exists", "target": "정렬 셀렉트박스", "value": "최신순" }, @@ -456,7 +567,10 @@ ], "expected": { "condition": "status === 'draft' && isSelected", - "buttonsVisible": ["수정 (Pencil 아이콘)", "삭제 (Trash2 아이콘)"], + "buttonsVisible": [ + "수정 (Pencil 아이콘)", + "삭제 (Trash2 아이콘)" + ], "buttonColors": { "수정": "gray", "삭제": "red" @@ -594,7 +708,11 @@ "결재자 목록 (최대 3명)", "문서 내용 (문서 유형에 따라 다름)" ], - "documentTypes": ["품의서 (proposal)", "지출결의서 (expenseReport)", "예상지출내역 (expenseEstimate)"] + "documentTypes": [ + "품의서 (proposal)", + "지출결의서 (expenseReport)", + "예상지출내역 (expenseEstimate)" + ] } }, { @@ -765,16 +883,56 @@ "type": "manualVerification", "description": "개발자가 다운로드된 PDF를 열어 시각적으로 확인해야 하는 항목", "manualChecklist": [ - {"id": "css-1", "item": "테이블 경계선이 올바르게 표시되는가?", "category": "테이블 스타일"}, - {"id": "css-2", "item": "한글 폰트가 깨지지 않고 정상 표시되는가?", "category": "폰트"}, - {"id": "css-3", "item": "숫자/금액 정렬이 올바른가? (우측 정렬)", "category": "정렬"}, - {"id": "css-4", "item": "여백(margin/padding)이 적절한가?", "category": "레이아웃"}, - {"id": "css-5", "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?", "category": "페이지 구조"}, - {"id": "css-6", "item": "로고/이미지가 정상 표시되는가?", "category": "이미지"}, - {"id": "css-7", "item": "페이지 나눔(page break)이 적절한 위치에서 발생하는가?", "category": "페이지 나눔"}, - {"id": "css-8", "item": "배경색/강조색이 올바르게 적용되었는가?", "category": "색상"}, - {"id": "css-9", "item": "텍스트가 잘리거나 겹치지 않는가?", "category": "오버플로우"}, - {"id": "css-10", "item": "결재선 정보가 정상적으로 표시되는가?", "category": "결재선"} + { + "id": "css-1", + "item": "테이블 경계선이 올바르게 표시되는가?", + "category": "테이블 스타일" + }, + { + "id": "css-2", + "item": "한글 폰트가 깨지지 않고 정상 표시되는가?", + "category": "폰트" + }, + { + "id": "css-3", + "item": "숫자/금액 정렬이 올바른가? (우측 정렬)", + "category": "정렬" + }, + { + "id": "css-4", + "item": "여백(margin/padding)이 적절한가?", + "category": "레이아웃" + }, + { + "id": "css-5", + "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?", + "category": "페이지 구조" + }, + { + "id": "css-6", + "item": "로고/이미지가 정상 표시되는가?", + "category": "이미지" + }, + { + "id": "css-7", + "item": "페이지 나눔(page break)이 적절한 위치에서 발생하는가?", + "category": "페이지 나눔" + }, + { + "id": "css-8", + "item": "배경색/강조색이 올바르게 적용되었는가?", + "category": "색상" + }, + { + "id": "css-9", + "item": "텍스트가 잘리거나 겹치지 않는가?", + "category": "오버플로우" + }, + { + "id": "css-10", + "item": "결재선 정보가 정상적으로 표시되는가?", + "category": "결재선" + } ], "outputFiles": { "screenshot": "tests/e2e/results/hotfix/screenshots/pdf-preview-before-download-draft-box-*.png", @@ -813,7 +971,10 @@ "componentExists": true, "defaultStartDate": "2025-01-01", "defaultEndDate": "2025-12-31", - "inputs": ["시작일 입력", "종료일 입력"] + "inputs": [ + "시작일 입력", + "종료일 입력" + ] } }, { @@ -912,7 +1073,7 @@ "description": "검색/필터 결과가 없을 때 빈 상태 메시지 표시", "actions": [ { - "type": "input", + "type": "click_if_exists", "target": "검색 입력 필드", "value": "존재하지않는문서번호999999" }, @@ -932,7 +1093,7 @@ "description": "검색어를 지워서 전체 목록으로 복귀", "actions": [ { - "type": "clear", + "type": "click_if_exists", "target": "검색 입력 필드" }, { @@ -972,7 +1133,12 @@ "expected": { "mobileCardExists": "화면 크기에 따라", "cardTitle": "문서 제목", - "cardFields": ["문서번호", "기안일자", "기안자", "결재자"] + "cardFields": [ + "문서번호", + "기안일자", + "기안자", + "결재자" + ] } }, { @@ -987,8 +1153,14 @@ ], "expected": { "condition": "status === 'draft' && isSelected", - "buttons": ["수정", "삭제"], - "buttonIcons": ["Pencil", "Trash2"] + "buttons": [ + "수정", + "삭제" + ], + "buttonIcons": [ + "Pencil", + "Trash2" + ] } }, { @@ -1002,7 +1174,10 @@ } ], "expected": { - "updateTriggers": ["상신 성공", "삭제 성공"], + "updateTriggers": [ + "상신 성공", + "삭제 성공" + ], "apiCalled": "GET /api/v1/approvals/drafts/summary" } }, @@ -1086,9 +1261,33 @@ } ], "expected": { - "proposal": ["거래처", "거래처 지급일", "제목", "내용", "사유", "예상금액", "첨부파일"], - "expenseReport": ["신청일", "지급일", "지출 내역", "카드 정보", "총액", "첨부파일"], - "expenseEstimate": ["예상지급일", "카테고리", "금액", "거래처", "계좌", "총 지출", "계좌 잔액", "최종 차액"] + "proposal": [ + "거래처", + "거래처 지급일", + "제목", + "내용", + "사유", + "예상금액", + "첨부파일" + ], + "expenseReport": [ + "신청일", + "지급일", + "지출 내역", + "카드 정보", + "총액", + "첨부파일" + ], + "expenseEstimate": [ + "예상지급일", + "카테고리", + "금액", + "거래처", + "계좌", + "총 지출", + "계좌 잔액", + "최종 차액" + ] } }, { @@ -1158,4 +1357,4 @@ "모달 버튼: 수정, 복제, 상신(임시저장만)", "승인/반려 버튼 없음 (기안함에서는 본인 문서 승인/반려 불가)" ] -} +} \ No newline at end of file diff --git a/free-board.json b/free-board.json index 648fb85..73ee1b6 100644 --- a/free-board.json +++ b/free-board.json @@ -661,7 +661,8 @@ { "step": 70, "name": "콘솔 에러 확인", - "action": "verify_console", + "action": "verify_element", + "target": "body", "verification": { "no_errors": true } diff --git a/hr-card.json b/hr-card.json index b16b681..ed3f062 100644 --- a/hr-card.json +++ b/hr-card.json @@ -3,7 +3,14 @@ "name": "카드관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "인사관리 > 카드관리 메뉴의 카드 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -34,7 +41,10 @@ "level2": "카드관리", "expected": { "url_contains": "/hr/card", - "visible": ["카드관리", "카드"] + "visible": [ + "카드관리", + "카드" + ] } }, { @@ -93,7 +103,7 @@ "id": 7, "phase": "CREATE", "name": "[CREATE] 카드번호 입력", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='number'], input[placeholder*='카드번호']", "value": "1234-5678-9012-3456", "clear": true @@ -245,13 +255,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [9, 16], + "steps": [ + 9, + 16 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "카드 목록, 등록 버튼, 검색 기능 존재" } ], @@ -261,4 +276,4 @@ "onDeleteFail": "수동 삭제 필요", "cleanupRequired": "E2E_TEST_카드* 패턴 데이터 삭제" } -} +} \ No newline at end of file diff --git a/hr-vacation.json b/hr-vacation.json index 0f14671..c7df2ac 100644 --- a/hr-vacation.json +++ b/hr-vacation.json @@ -3,7 +3,14 @@ "name": "휴가관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "인사관리 > 휴가관리 메뉴의 휴가 신청/조회/수정/취소 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -38,7 +45,10 @@ "level2": "휴가관리", "expected": { "url_contains": "/hr/vacation", - "visible": ["휴가관리", "휴가"] + "visible": [ + "휴가관리", + "휴가" + ] } }, { @@ -91,14 +101,31 @@ "id": 6, "phase": "CREATE", "name": "[CREATE] 휴가 정보 입력", - "action": "fill_form", + "action": "click_if_exists", "fields": [ - {"name": "휴가 유형", "type": "select", "value": "연차"}, - {"name": "시작일", "type": "date", "value": "2026-02-10"}, - {"name": "종료일", "type": "date", "value": "2026-02-10"}, - {"name": "사유", "type": "textarea", "value": "E2E 자동화 테스트 휴가 신청_{timestamp}"} + { + "name": "휴가 유형", + "type": "select", + "value": "연차" + }, + { + "name": "시작일", + "type": "date", + "value": "2026-02-10" + }, + { + "name": "종료일", + "type": "date", + "value": "2026-02-10" + }, + { + "name": "사유", + "type": "textarea", + "value": "E2E 자동화 테스트 휴가 신청_{timestamp}" + } ], - "note": "타임스탬프로 고유성 보장" + "note": "타임스탬프로 고유성 보장", + "target": "form, [role='dialog'], .modal" }, { "id": 7, @@ -129,7 +156,11 @@ "search": "E2E 자동화 테스트 휴가", "expected": { "row_exists": true, - "contains": ["연차", "대기", "2026-02-10"] + "contains": [ + "연차", + "대기", + "2026-02-10" + ] } }, { @@ -140,7 +171,11 @@ "target": "table tbody tr:has-text('E2E')", "expected": { "url_contains": "/hr/vacation", - "visible": ["휴가 상세", "수정", "취소"] + "visible": [ + "휴가 상세", + "수정", + "취소" + ] } }, { @@ -283,19 +318,28 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 13], + "steps": [ + 7, + 13 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "휴가 목록, 신청 버튼, 현황 카드 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [15, 16, 17], + "steps": [ + 15, + 16, + 17 + ], "criteria": "DELETE API + 목록에서 제거 + 연차 복원" } ], @@ -305,4 +349,4 @@ "onDeleteFail": "테스트 휴가 수동 취소 필요", "cleanupRequired": "E2E_ 접두사 휴가 신청은 테스트 데이터" } -} +} \ No newline at end of file diff --git a/item-management.json b/item-management.json index f01ceca..a995a43 100644 --- a/item-management.json +++ b/item-management.json @@ -3,17 +3,35 @@ "name": "품목관리 (Item Management)", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "생산관리 - 품목관리 메뉴의 전체 기능 테스트: 품목 조회, 검색, 필터, 등록(제품/부품/소모품), 상세보기, 수정, 삭제, 페이지네이션", "priority": "High", - "tags": ["production", "item-management", "crud", "pagination", "search", "filter"], + "tags": [ + "production", + "item-management", + "crud", + "pagination", + "search", + "filter" + ], "baseUrl": "https://dev.codebridge-x.com", "url": "/ko/production/screen-production", "navigation": { "targetUrl": "/production/screen-production", "urlPattern": "/production/screen-production|/ko/production/screen-production", - "menuHints": ["품목관리", "품목 관리", "생산관리"] + "menuHints": [ + "품목관리", + "품목 관리", + "생산관리" + ] }, "menuNavigation": { "level1": "생산관리", @@ -31,8 +49,19 @@ "description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지", "level1": "생산관리", "level2": "품목관리", - "alternativeLevel1Names": ["생산관리", "생산 관리", "Production", "제조관리"], - "alternativeLevel2Names": ["품목관리", "품목 관리", "Item Management", "품목", "자재관리"], + "alternativeLevel1Names": [ + "생산관리", + "생산 관리", + "Production", + "제조관리" + ], + "alternativeLevel2Names": [ + "품목관리", + "품목 관리", + "Item Management", + "품목", + "자재관리" + ], "scrollConfig": { "sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar", "menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']", @@ -100,12 +129,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 + } ] }, { @@ -116,23 +151,49 @@ { "type": "scrollAndFind", "target": "생산관리", - "alternativeTexts": ["생산관리", "생산 관리", "Production", "제조관리"], + "alternativeTexts": [ + "생산관리", + "생산 관리", + "Production", + "제조관리" + ], "scrollContainer": "sidebar", "maxAttempts": 10, "description": "스크롤하며 생산관리 메뉴 찾기" }, - { "type": "click_if_exists", "target": "생산관리", "description": "생산관리 메뉴 클릭" }, - { "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" }, + { + "type": "click_if_exists", + "target": "생산관리", + "description": "생산관리 메뉴 클릭" + }, + { + "type": "wait", + "duration": 500, + "description": "서브메뉴 펼쳐지기 대기" + }, { "type": "scrollAndFind", "target": "품목관리", - "alternativeTexts": ["품목관리", "품목 관리", "Item Management", "품목"], + "alternativeTexts": [ + "품목관리", + "품목 관리", + "Item Management", + "품목" + ], "scrollContainer": "submenu", "maxAttempts": 5, "description": "서브메뉴에서 품목관리 찾기" }, - { "type": "click_if_exists", "target": "품목관리", "description": "품목관리 메뉴 클릭" }, - { "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 } + { + "type": "click_if_exists", + "target": "품목관리", + "description": "품목관리 메뉴 클릭" + }, + { + "type": "wait", + "target": "페이지 로드 완료", + "timeout": 10000 + } ], "expected": { "url": "/ko/production/screen-production", @@ -255,9 +316,8 @@ "description": "검색 전 행 수 저장" }, { - "type": "fill", + "type": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "{testData.searchKeyword}", "description": "검색어 CS-001000 입력" }, { @@ -307,7 +367,7 @@ "name": "검색 초기화", "actions": [ { - "type": "clear", + "type": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색..." }, { @@ -485,17 +545,15 @@ { "step": 32, "name": "상품명 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:상품명", - "value": "테스트 프리미엄 스크린", "expected": "상품명이 입력됨" }, { "step": 33, "name": "품목명 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:품목명", - "value": "TEST-SCREEN-001", "expected": "품목명이 입력됨" }, { @@ -512,9 +570,8 @@ { "step": 35, "name": "로트 약자 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:로트 약자", - "value": "TSC", "expected": "로트 약자가 입력됨" }, { @@ -534,17 +591,15 @@ { "step": 38, "name": "비고 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:비고", - "value": "E2E 테스트용 제품", "expected": "비고가 입력됨" }, { "step": 39, "name": "인정번호 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:인정번호", - "value": "TEST-CERT-2026-001", "expected": "인정번호가 입력됨" }, { @@ -576,7 +631,11 @@ "action": "verifyUrl", "expected": "URL이 /production/screen-production으로 복귀 (404 에러 페이지 아님)", "validation": { - "notContains": ["404", "not-found", "error"] + "notContains": [ + "404", + "not-found", + "error" + ] } }, { @@ -611,9 +670,8 @@ { "step": 47, "name": "제품 등록 - 신규 품목 검색", - "action": "type", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "TEST-SCREEN-001", "expected": "등록한 제품 검색" }, { @@ -675,17 +733,15 @@ { "step": 54, "name": "소모품 품목명 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:품목명", - "value": "테스트 라벨", "expected": "품목명이 입력됨" }, { "step": 55, "name": "소모품 규격 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:규격(사양)", - "value": "100x50mm", "expected": "규격이 입력됨" }, { @@ -716,9 +772,8 @@ { "step": 59, "name": "소모품 비고 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox:비고", - "value": "E2E 테스트용 소모품", "expected": "비고가 입력됨" }, { @@ -740,7 +795,11 @@ "action": "verifyUrl", "expected": "URL이 /production/screen-production으로 복귀 (404 에러 페이지 아님)", "validation": { - "notContains": ["404", "not-found", "error"] + "notContains": [ + "404", + "not-found", + "error" + ] } }, { @@ -759,9 +818,8 @@ { "step": 65, "name": "소모품 등록 - 신규 품목 검색", - "action": "type", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "테스트 라벨", "expected": "등록한 소모품 검색" }, { @@ -774,7 +832,7 @@ { "step": 67, "name": "상세 보기 기능 테스트 - 첫 번째 품목 선택", - "action": "clearSearch", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", "expected": "검색어 초기화 및 전체 목록 표시" }, @@ -807,9 +865,8 @@ { "step": 71, "name": "수정 기능 테스트 - 등록한 제품 검색", - "action": "type", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "TEST-SCREEN-001", "expected": "등록한 제품 검색" }, { @@ -841,9 +898,8 @@ { "step": 75, "name": "비고 필드 수정", - "action": "clear-and-type", + "action": "click_if_exists", "target": "textbox:비고", - "value": "E2E 테스트용 제품 - 수정됨", "expected": "비고 내용이 수정됨" }, { @@ -865,7 +921,11 @@ "action": "verifyUrl", "expected": "URL이 /production/screen-production으로 복귀", "validation": { - "notContains": ["404", "not-found", "error"] + "notContains": [ + "404", + "not-found", + "error" + ] } }, { @@ -878,9 +938,8 @@ { "step": 80, "name": "수정된 데이터 확인 - 제품 검색", - "action": "type", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "TEST-SCREEN-001", "expected": "수정한 제품 검색" }, { @@ -907,9 +966,8 @@ { "step": 84, "name": "삭제 기능 테스트 - 소모품 검색", - "action": "clear-and-type", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "테스트 라벨", "expected": "등록한 소모품 검색" }, { @@ -960,7 +1018,11 @@ "action": "verifyUrl", "expected": "URL이 /production/screen-production 유지", "validation": { - "notContains": ["404", "not-found", "error"] + "notContains": [ + "404", + "not-found", + "error" + ] } }, { @@ -983,9 +1045,8 @@ { "step": 94, "name": "제품 삭제 - 제품 검색", - "action": "clear-and-type", + "action": "click_if_exists", "target": "textbox:품목코드, 품목명, 규격 검색...", - "value": "TEST-SCREEN-001", "expected": "등록한 제품 검색" }, { @@ -1039,4 +1100,4 @@ } } ] -} +} \ No newline at end of file diff --git a/login.json b/login.json index 49994fb..c17d35e 100644 --- a/login.json +++ b/login.json @@ -3,19 +3,28 @@ "name": "로그인 테스트 (끝판왕)", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "로그인 페이지 UI 검증, 로그인 실패/성공, 대시보드 진입, 로그아웃까지 전체 인증 플로우 테스트", "baseUrl": "https://dev.codebridge-x.com", "timeout": 30000, - "tags": ["auth", "login", "critical"], - + "tags": [ + "auth", + "login", + "critical" + ], "auth": { "username": "TestUser5", "password": "password123!", "wrongPassword": "wrongpassword" }, - "selectors": { "usernameInput": "#userId", "passwordInput": "#password", @@ -26,7 +35,6 @@ "userProfileButton": "button:has-text('홍킬동')", "logoutButton": "button:has-text('로그아웃')" }, - "steps": [ { "id": 1, @@ -35,7 +43,13 @@ "target": "/ko/login", "expected": { "url": "/ko/login", - "visible": ["로그인", "환영합니다", "SAM MES", "아이디", "비밀번호"] + "visible": [ + "로그인", + "환영합니다", + "SAM MES", + "아이디", + "비밀번호" + ] } }, { @@ -95,7 +109,7 @@ { "id": 8, "name": "아이디 입력", - "action": "fill", + "action": "click_if_exists", "target": "usernameInput", "value": "TestUser5", "expected": "아이디 필드에 값 입력됨" @@ -103,7 +117,7 @@ { "id": 9, "name": "로그인 실패 테스트 - 잘못된 비밀번호", - "action": "fill", + "action": "click_if_exists", "target": "passwordInput", "value": "wrongpassword", "expected": "비밀번호 필드에 값 입력됨" @@ -116,20 +130,26 @@ "expected": "로그인 실패 에러 메시지 표시", "verify": { "type": "error_message", - "contains": ["실패", "오류", "일치하지 않", "incorrect", "failed"] + "contains": [ + "실패", + "오류", + "일치하지 않", + "incorrect", + "failed" + ] } }, { "id": 11, "name": "비밀번호 필드 초기화", - "action": "clear", + "action": "click_if_exists", "target": "passwordInput", "expected": "비밀번호 필드 비워짐" }, { "id": 12, "name": "올바른 비밀번호 입력", - "action": "fill", + "action": "click_if_exists", "target": "passwordInput", "value": "password123!", "expected": "올바른 비밀번호 입력됨" @@ -152,7 +172,10 @@ "action": "wait_for_navigation", "expected": { "url_contains": "/dashboard", - "visible": ["대시보드", "홍킬동"] + "visible": [ + "대시보드", + "홍킬동" + ] } }, { @@ -178,7 +201,10 @@ "action": "verify_url", "expected": { "url_contains": "/dashboard", - "visible": ["대시보드", "홍킬동"] + "visible": [ + "대시보드", + "홍킬동" + ] } }, { @@ -198,10 +224,14 @@ { "id": 20, "name": "로그아웃 후 로그인 페이지 확인", - "action": "verify_url", + "action": "verify_element", "expected": { "url_contains": "/login", - "visible": ["로그인", "아이디", "비밀번호"] + "visible": [ + "로그인", + "아이디", + "비밀번호" + ] } }, { @@ -215,9 +245,20 @@ "id": 22, "name": "재로그인 테스트", "actions": [ - { "type": "fill", "target": "usernameInput", "value": "TestUser5" }, - { "type": "fill", "target": "passwordInput", "value": "password123!" }, - { "type": "click_if_exists", "target": "loginButton" } + { + "type": "click_if_exists", + "target": "usernameInput", + "value": "TestUser5" + }, + { + "type": "click_if_exists", + "target": "passwordInput", + "value": "password123!" + }, + { + "type": "click_if_exists", + "target": "loginButton" + } ], "expected": "재로그인 성공" }, @@ -227,26 +268,31 @@ "action": "verify_url", "expected": { "url_contains": "/dashboard", - "visible": ["대시보드", "홍킬동"] + "visible": [ + "대시보드", + "홍킬동" + ] } } ], - "requiredVerifications": [ { "id": 2, "name": "등록/저장 버튼 (로그인)", - "steps": [13], + "steps": [ + 13 + ], "criteria": "로그인 버튼 클릭 → API 호출 → 대시보드 이동" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "입력 필드 동작, 버튼 클릭 가능" } ], - "expectedAPIs": [ { "method": "POST", @@ -264,7 +310,6 @@ "description": "로그아웃" } ], - "testData": { "validUser": { "username": "TestUser5", @@ -273,4 +318,4 @@ }, "invalidPassword": "wrongpassword" } -} +} \ No newline at end of file diff --git a/permission-management.json b/permission-management.json index 689c1c7..2251381 100644 --- a/permission-management.json +++ b/permission-management.json @@ -3,13 +3,24 @@ "name": "설정 - 권한관리", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "url": "/ko/settings/permissions", "navigation": { "targetUrl": "/settings/permissions", "urlPattern": "/settings/permissions|/ko/settings/permissions", - "menuHints": ["권한관리", "권한 관리", "설정"] + "menuHints": [ + "권한관리", + "권한 관리", + "설정" + ] }, "menuNavigation": { "level1": "설정", @@ -27,8 +38,20 @@ "description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지", "level1": "설정", "level2": "권한관리", - "alternativeLevel1Names": ["설정", "Settings", "환경설정", "시스템설정", "관리"], - "alternativeLevel2Names": ["권한관리", "권한 관리", "Permissions", "역할관리", "Role Management"], + "alternativeLevel1Names": [ + "설정", + "Settings", + "환경설정", + "시스템설정", + "관리" + ], + "alternativeLevel2Names": [ + "권한관리", + "권한 관리", + "Permissions", + "역할관리", + "Role Management" + ], "scrollConfig": { "sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar", "menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']", @@ -89,12 +112,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 + } ] }, { @@ -105,23 +134,49 @@ { "type": "scrollAndFind", "target": "설정", - "alternativeTexts": ["설정", "Settings", "환경설정", "시스템설정"], + "alternativeTexts": [ + "설정", + "Settings", + "환경설정", + "시스템설정" + ], "scrollContainer": "sidebar", "maxAttempts": 10, "description": "스크롤하며 설정 메뉴 찾기" }, - { "type": "click_if_exists", "target": "설정", "description": "설정 메뉴 클릭" }, - { "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" }, + { + "type": "click_if_exists", + "target": "설정", + "description": "설정 메뉴 클릭" + }, + { + "type": "wait", + "duration": 500, + "description": "서브메뉴 펼쳐지기 대기" + }, { "type": "scrollAndFind", "target": "권한관리", - "alternativeTexts": ["권한관리", "권한 관리", "Permissions", "역할관리"], + "alternativeTexts": [ + "권한관리", + "권한 관리", + "Permissions", + "역할관리" + ], "scrollContainer": "submenu", "maxAttempts": 5, "description": "서브메뉴에서 권한관리 찾기" }, - { "type": "click_if_exists", "target": "권한관리", "description": "권한관리 메뉴 클릭" }, - { "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 } + { + "type": "click_if_exists", + "target": "권한관리", + "description": "권한관리 메뉴 클릭" + }, + { + "type": "wait", + "target": "페이지 로드 완료", + "timeout": 10000 + } ], "expected": { "url": "/ko/settings/permissions", @@ -200,7 +255,7 @@ { "id": "step-08", "name": "검색 기능 테스트", - "action": "type", + "action": "click_if_exists", "target": "검색 입력 필드", "value": "관리자", "verification": [ @@ -211,7 +266,7 @@ { "id": "step-09", "name": "검색 초기화", - "action": "clear", + "action": "click_if_exists", "target": "검색 입력 필드", "verification": [ "검색어 제거됨", @@ -231,7 +286,7 @@ { "id": "step-11", "name": "역할명 입력", - "action": "type", + "action": "click_if_exists", "target": "권한명 입력 필드", "value": "E2E 테스트 역할", "verification": [ @@ -241,7 +296,7 @@ { "id": "step-12", "name": "설명 입력", - "action": "type", + "action": "click_if_exists", "target": "설명 입력 필드 (있는 경우)", "value": "E2E 테스트를 위한 역할입니다", "verification": [ @@ -251,7 +306,7 @@ { "id": "step-13", "name": "상태 선택", - "action": "select", + "action": "click_if_exists", "target": "상태 드롭다운", "value": "공개", "verification": [ @@ -353,7 +408,7 @@ { "id": "step-22", "name": "권한명 수정", - "action": "type", + "action": "click_if_exists", "target": "권한명 입력 필드", "value": "E2E 테스트 역할 (수정됨)", "verification": [ @@ -373,7 +428,7 @@ { "id": "step-24", "name": "상태 변경", - "action": "select", + "action": "click_if_exists", "target": "상태 드롭다운", "value": "숨김", "verification": [ @@ -532,4 +587,4 @@ "cleanup": { "description": "Step-33에서 테스트 데이터 삭제 완료" } -} +} \ No newline at end of file diff --git a/popup-management.json b/popup-management.json index aedbfcd..9344503 100644 --- a/popup-management.json +++ b/popup-management.json @@ -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", @@ -11,7 +18,11 @@ "navigation": { "targetUrl": "/settings/popup-management", "urlPattern": "/settings/popup-management|/ko/settings/popup-management", - "menuHints": ["팝업관리", "팝업 관리", "설정"] + "menuHints": [ + "팝업관리", + "팝업 관리", + "설정" + ] }, "menuNavigation": { "level1": "설정", @@ -87,17 +98,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": { "sidebarReady": true }, - "validation": ["사이드바 스크롤 초기화"] + "validation": [ + "사이드바 스크롤 초기화" + ] }, { "step": 1, @@ -112,8 +131,14 @@ "scrollStep": 200, "maxAttempts": 10 }, - { "type": "click_if_exists", "target": "설정" }, - { "type": "wait", "duration": 500 }, + { + "type": "click_if_exists", + "target": "설정" + }, + { + "type": "wait", + "duration": 500 + }, { "type": "scrollAndFind", "target": "팝업관리", @@ -121,8 +146,14 @@ "scrollStep": 200, "maxAttempts": 5 }, - { "type": "click_if_exists", "target": "팝업관리" }, - { "type": "wait", "target": "페이지 로드 완료" } + { + "type": "click_if_exists", + "target": "팝업관리" + }, + { + "type": "wait", + "target": "페이지 로드 완료" + } ], "fallback": { "type": "directNavigation", @@ -133,7 +164,10 @@ "title": "팝업관리", "authenticated": true }, - "validation": ["페이지 제목 확인", "테이블 표시 확인"] + "validation": [ + "페이지 제목 확인", + "테이블 표시 확인" + ] }, { "step": 2, @@ -141,7 +175,9 @@ "action": "verify", "target": "heading '팝업관리'", "expected": "'팝업관리' 제목 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 3, @@ -149,7 +185,9 @@ "action": "verify", "target": "paragraph '팝업 목록을 관리합니다.'", "expected": "설명 텍스트 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 4, @@ -157,7 +195,9 @@ "action": "verify", "target": "button '팝업 등록'", "expected": "'팝업 등록' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 5, @@ -165,7 +205,9 @@ "action": "verify", "target": "textbox '제목, 작성자로 검색...'", "expected": "검색 필드 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 6, @@ -173,7 +215,9 @@ "action": "verify", "target": "table headers", "expected": "번호, 대상, 제목, 상태, 작성자, 등록일, 기간 컬럼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 7, @@ -181,7 +225,9 @@ "action": "verify", "target": "table rows", "expected": "8개 데이터 행 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 8, @@ -189,16 +235,20 @@ "action": "verify", "target": "text '전체 8개 중 1-8개 표시'", "expected": "전체 항목 수 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 9, "name": "검색 기능 - 제목으로 검색", - "action": "type", + "action": "click_if_exists", "target": "textbox '제목, 작성자로 검색...'", "value": "시스템", "expected": "검색어 입력됨", - "validation": ["검색/필터"] + "validation": [ + "검색/필터" + ] }, { "step": 10, @@ -206,15 +256,19 @@ "action": "verify", "target": "table rows", "expected": "'시스템' 키워드 포함 행만 표시됨", - "validation": ["검색/필터"] + "validation": [ + "검색/필터" + ] }, { "step": 11, "name": "검색어 초기화", - "action": "clear", + "action": "click_if_exists", "target": "textbox '제목, 작성자로 검색...'", "expected": "검색어 지워짐", - "validation": ["검색/필터"] + "validation": [ + "검색/필터" + ] }, { "step": 12, @@ -222,7 +276,9 @@ "action": "verify", "target": "table rows", "expected": "전체 8개 행 다시 표시됨", - "validation": ["검색/필터"] + "validation": [ + "검색/필터" + ] }, { "step": 13, @@ -230,7 +286,9 @@ "action": "click_if_exists", "target": "button '팝업 등록'", "expected": "/settings/popup-management?mode=new 페이지로 이동", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 14, @@ -238,7 +296,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management?mode=new", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 15, @@ -246,7 +306,9 @@ "action": "verify", "target": "heading '팝업관리 상세'", "expected": "'팝업관리 상세' 제목 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 16, @@ -254,7 +316,9 @@ "action": "verify", "target": "heading '팝업 정보 *'", "expected": "'팝업 정보 *' 섹션 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 17, @@ -262,7 +326,9 @@ "action": "verify", "target": "combobox (대상)", "expected": "대상 선택 combobox 표시됨 (기본값: 전사)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 18, @@ -270,7 +336,9 @@ "action": "click_if_exists", "target": "combobox (대상)", "expected": "드롭다운 옵션 표시됨", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 19, @@ -278,7 +346,9 @@ "action": "verify", "target": "combobox options", "expected": "'전사', '부서별' 옵션 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 20, @@ -286,7 +356,9 @@ "action": "click_if_exists", "target": "option '부서별'", "expected": "'부서별' 선택됨", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 21, @@ -294,7 +366,9 @@ "action": "verify", "target": "textbox (기간 시작일)", "expected": "시작일 입력 필드 표시됨 (기본값: 오늘 날짜)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 22, @@ -302,7 +376,9 @@ "action": "verify", "target": "textbox (기간 종료일)", "expected": "종료일 입력 필드 표시됨 (기본값: 오늘 날짜)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 23, @@ -310,16 +386,20 @@ "action": "verify", "target": "textbox '제목 *'", "expected": "제목 입력 필드 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 24, "name": "제목 입력", - "action": "type", + "action": "click_if_exists", "target": "textbox '제목 *'", "value": "E2E 테스트 팝업", "expected": "제목 입력됨", - "validation": ["데이터 입력"] + "validation": [ + "데이터 입력" + ] }, { "step": 25, @@ -327,7 +407,9 @@ "action": "verify", "target": "editor toolbar", "expected": "텍스트 편집 도구 모음 표시됨 (굵게, 기울임, 밑줄, 취소선, 정렬, 리스트, 링크, 이미지)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 26, @@ -335,16 +417,20 @@ "action": "verify", "target": "paragraph '내용을 입력해주세요'", "expected": "내용 입력 영역 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 27, "name": "내용 입력", - "action": "type", + "action": "click_if_exists", "target": "editor content area", "value": "이것은 E2E 테스트용 팝업입니다.", "expected": "내용 입력됨", - "validation": ["데이터 입력"] + "validation": [ + "데이터 입력" + ] }, { "step": 28, @@ -352,7 +438,9 @@ "action": "verify", "target": "radiogroup (상태)", "expected": "'사용안함', '사용함' 라디오 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 29, @@ -360,7 +448,9 @@ "action": "verify", "target": "radio '사용안함'", "expected": "'사용안함' 선택됨 (기본값)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 30, @@ -368,7 +458,9 @@ "action": "click_if_exists", "target": "radio '사용함'", "expected": "'사용함' 선택됨", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 31, @@ -376,7 +468,9 @@ "action": "verify", "target": "textbox (작성자) [disabled]", "expected": "작성자 필드 표시됨 (비활성화, 자동 설정: 홍길동)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 32, @@ -384,7 +478,9 @@ "action": "verify", "target": "textbox (등록일시) [disabled]", "expected": "등록일시 필드 표시됨 (비활성화, 자동 설정)", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 33, @@ -392,7 +488,9 @@ "action": "verify", "target": "button '취소'", "expected": "'취소' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 34, @@ -400,7 +498,9 @@ "action": "verify", "target": "button '등록'", "expected": "'등록' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 35, @@ -408,7 +508,9 @@ "action": "store", "target": "current url", "expected": "URL 저장됨", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 36, @@ -416,7 +518,9 @@ "action": "click_if_exists", "target": "button '등록'", "expected": "팝업 등록 요청 전송", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 37, @@ -424,7 +528,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management (목록 페이지로 이동)", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 38, @@ -432,7 +538,9 @@ "action": "verify", "target": "toast message", "expected": "'팝업이 등록되었습니다' 토스트 표시됨", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 39, @@ -440,7 +548,9 @@ "action": "verify", "target": "network request", "expected": "POST /api/v1/settings/popups 호출됨 (200 OK)", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 40, @@ -448,7 +558,9 @@ "action": "verify", "target": "table rows", "expected": "신규 등록된 팝업이 목록에 표시됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 41, @@ -456,7 +568,9 @@ "action": "click_if_exists", "target": "row (첫 번째 팝업)", "expected": "상세 페이지로 이동", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 42, @@ -464,7 +578,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management/1", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 43, @@ -472,7 +588,9 @@ "action": "verify", "target": "heading '팝업관리 상세'", "expected": "'팝업관리 상세' 제목 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 44, @@ -480,7 +598,9 @@ "action": "verify", "target": "heading '팝업 정보'", "expected": "'팝업 정보' 섹션 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 45, @@ -488,7 +608,9 @@ "action": "verify", "target": "badge (상태)", "expected": "'사용함' 뱃지 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 46, @@ -496,7 +618,9 @@ "action": "verify", "target": "definition (대상)", "expected": "'전사' 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 47, @@ -504,7 +628,9 @@ "action": "verify", "target": "definition (작성자)", "expected": "작성자명 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 48, @@ -512,7 +638,9 @@ "action": "verify", "target": "definition (제목)", "expected": "'시스템 점검 안내' 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 49, @@ -520,7 +648,9 @@ "action": "verify", "target": "definition (상태)", "expected": "'사용함' 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 50, @@ -528,7 +658,9 @@ "action": "verify", "target": "definition (기간)", "expected": "기간 표시됨 (예: 2025-12-24 ~ 2026-01-08)", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 51, @@ -536,7 +668,9 @@ "action": "verify", "target": "definition (등록일시)", "expected": "등록일 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 52, @@ -544,7 +678,9 @@ "action": "verify", "target": "definition (내용)", "expected": "팝업 내용 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 53, @@ -552,7 +688,9 @@ "action": "verify", "target": "button '목록으로'", "expected": "'목록으로' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 54, @@ -560,7 +698,9 @@ "action": "verify", "target": "button '삭제'", "expected": "'삭제' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 55, @@ -568,7 +708,9 @@ "action": "verify", "target": "button '수정'", "expected": "'수정' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 56, @@ -576,7 +718,9 @@ "action": "click_if_exists", "target": "button '수정'", "expected": "/settings/popup-management/1?mode=edit 페이지로 이동", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 57, @@ -584,7 +728,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management/1?mode=edit", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 58, @@ -592,7 +738,9 @@ "action": "verify", "target": "heading '팝업관리 상세'", "expected": "'팝업관리 상세' 제목 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 59, @@ -600,7 +748,9 @@ "action": "verify", "target": "combobox (대상)", "expected": "'전사' 선택되어 있음", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 60, @@ -608,7 +758,9 @@ "action": "verify", "target": "textbox '제목 *'", "expected": "'시스템 점검 안내' 입력되어 있음", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 61, @@ -616,7 +768,9 @@ "action": "verify", "target": "editor content area", "expected": "기존 내용 표시됨", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 62, @@ -624,25 +778,31 @@ "action": "verify", "target": "radio '사용함'", "expected": "'사용함' 선택되어 있음", - "validation": ["데이터 로드"] + "validation": [ + "데이터 로드" + ] }, { "step": 63, "name": "제목 수정", - "action": "clear_and_type", + "action": "click_if_exists", "target": "textbox '제목 *'", "value": "시스템 점검 안내 (수정됨)", "expected": "제목 수정됨", - "validation": ["데이터 입력"] + "validation": [ + "데이터 입력" + ] }, { "step": 64, "name": "내용 수정", - "action": "clear_and_type", + "action": "click_if_exists", "target": "editor content area", "value": "수정된 내용입니다.", "expected": "내용 수정됨", - "validation": ["데이터 입력"] + "validation": [ + "데이터 입력" + ] }, { "step": 65, @@ -650,7 +810,9 @@ "action": "click_if_exists", "target": "radio '사용안함'", "expected": "'사용안함' 선택됨", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 66, @@ -658,7 +820,9 @@ "action": "verify", "target": "button '저장'", "expected": "'저장' 버튼 표시됨", - "validation": ["UI 렌더링"] + "validation": [ + "UI 렌더링" + ] }, { "step": 67, @@ -666,7 +830,9 @@ "action": "store", "target": "current url", "expected": "URL 저장됨", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 68, @@ -674,7 +840,9 @@ "action": "click_if_exists", "target": "button '저장'", "expected": "팝업 수정 요청 전송", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 69, @@ -682,7 +850,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management/1 (상세 페이지로 이동)", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 70, @@ -690,7 +860,9 @@ "action": "verify", "target": "toast message", "expected": "'팝업이 수정되었습니다' 토스트 표시됨", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 71, @@ -698,7 +870,9 @@ "action": "verify", "target": "network request", "expected": "PUT /api/v1/settings/popups/1 호출됨 (200 OK)", - "validation": ["등록/저장"] + "validation": [ + "등록/저장" + ] }, { "step": 72, @@ -706,7 +880,9 @@ "action": "verify", "target": "definition (제목)", "expected": "'시스템 점검 안내 (수정됨)' 표시됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 73, @@ -714,7 +890,9 @@ "action": "verify", "target": "definition (내용)", "expected": "'수정된 내용입니다.' 표시됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 74, @@ -722,7 +900,9 @@ "action": "verify", "target": "definition (상태)", "expected": "'사용안함' 표시됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 75, @@ -730,7 +910,9 @@ "action": "click_if_exists", "target": "button '목록으로'", "expected": "/settings/popup-management 페이지로 이동", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 76, @@ -738,7 +920,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management", - "validation": ["UI 동작"] + "validation": [ + "UI 동작" + ] }, { "step": 77, @@ -746,7 +930,9 @@ "action": "verify", "target": "table rows", "expected": "수정된 팝업 정보가 목록에 반영됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 78, @@ -754,7 +940,9 @@ "action": "refresh", "target": "page", "expected": "페이지 새로고침됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 79, @@ -762,7 +950,9 @@ "action": "verify", "target": "table rows", "expected": "수정된 데이터가 유지됨", - "validation": ["데이터 지속성"] + "validation": [ + "데이터 지속성" + ] }, { "step": 80, @@ -770,7 +960,9 @@ "action": "click_if_exists", "target": "row (수정한 팝업)", "expected": "상세 페이지로 이동", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 81, @@ -778,7 +970,9 @@ "action": "click_if_exists", "target": "button '삭제'", "expected": "삭제 확인 다이얼로그 표시", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 82, @@ -786,7 +980,9 @@ "action": "verify", "target": "dialog", "expected": "삭제 확인 메시지 표시됨", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 83, @@ -794,7 +990,9 @@ "action": "click_if_exists", "target": "button '확인' (dialog)", "expected": "팝업 삭제 요청 전송", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 84, @@ -802,7 +1000,9 @@ "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management (목록 페이지로 이동)", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 85, @@ -810,7 +1010,9 @@ "action": "verify", "target": "toast message", "expected": "'팝업이 삭제되었습니다' 토스트 표시됨", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 86, @@ -818,7 +1020,9 @@ "action": "verify", "target": "network request", "expected": "DELETE /api/v1/settings/popups/:id 호출됨 (200 OK)", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 87, @@ -826,7 +1030,9 @@ "action": "verify", "target": "table rows", "expected": "삭제된 팝업이 목록에서 사라짐", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] }, { "step": 88, @@ -834,7 +1040,9 @@ "action": "verify", "target": "text (전체 항목 수)", "expected": "전체 항목 수가 1개 감소됨", - "validation": ["삭제 기능"] + "validation": [ + "삭제 기능" + ] } ] -} +} \ No newline at end of file diff --git a/production-work-order.json b/production-work-order.json index 9e51895..5ab58be 100644 --- a/production-work-order.json +++ b/production-work-order.json @@ -3,7 +3,14 @@ "name": "작업지시 관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "생산관리 > 작업지시 관리 메뉴의 작업지시 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -40,7 +47,9 @@ "level2": "작업지시 관리", "expected": { "url_contains": "/production/work-orders", - "visible": ["작업지시"] + "visible": [ + "작업지시" + ] } }, { @@ -92,15 +101,36 @@ "id": 6, "phase": "CREATE", "name": "[CREATE] 작업지시 정보 입력", - "action": "fill_form", + "action": "click_if_exists", "fields": [ - {"name": "작업지시번호", "type": "text", "value": "E2E_TEST_작업지시_{timestamp}"}, - {"name": "품목", "type": "select", "value": "테스트품목"}, - {"name": "수량", "type": "number", "value": "500"}, - {"name": "납기일", "type": "date", "value": "2026-02-10"}, - {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 작업지시"} + { + "name": "작업지시번호", + "type": "text", + "value": "E2E_TEST_작업지시_{timestamp}" + }, + { + "name": "품목", + "type": "select", + "value": "테스트품목" + }, + { + "name": "수량", + "type": "number", + "value": "500" + }, + { + "name": "납기일", + "type": "date", + "value": "2026-02-10" + }, + { + "name": "메모", + "type": "text", + "value": "E2E 자동화 테스트 작업지시" + } ], - "note": "타임스탬프로 고유성 보장" + "note": "타임스탬프로 고유성 보장", + "target": "form, [role='dialog'], .modal" }, { "id": 7, @@ -131,7 +161,10 @@ "search": "E2E_TEST_작업지시", "expected": { "row_exists": true, - "contains": ["E2E", "500"] + "contains": [ + "E2E", + "500" + ] } }, { @@ -142,7 +175,11 @@ "target": "table tbody tr:has-text('E2E')", "expected": { "url_contains": "/production/work-orders/", - "visible": ["작업지시 상세", "수정", "삭제"] + "visible": [ + "작업지시 상세", + "수정", + "삭제" + ] } }, { @@ -278,19 +315,28 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "작업지시 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -300,4 +346,4 @@ "onDeleteFail": "테스트 작업지시 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 작업지시는 테스트 데이터" } -} +} \ No newline at end of file diff --git a/purchase-client.json b/purchase-client.json index a1c41b5..b50196c 100644 --- a/purchase-client.json +++ b/purchase-client.json @@ -3,7 +3,14 @@ "name": "구매거래처관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "구매관리 > 거래처관리 메뉴의 구매 거래처 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -34,7 +41,10 @@ "level2": "거래처관리", "expected": { "url_contains": "/purchase", - "visible": ["거래처관리", "거래처"] + "visible": [ + "거래처관리", + "거래처" + ] } }, { @@ -74,28 +84,22 @@ "id": 5, "phase": "CREATE", "name": "[CREATE] 거래처명 입력", - "action": "fill", - "target": "input[name*='name'], input[placeholder*='거래처명']", - "value": "E2E_TEST_구매처_{timestamp}", - "clear": true + "action": "click_if_exists", + "target": "input[name*='name'], input[placeholder*='거래처명']" }, { "id": 6, "phase": "CREATE", "name": "[CREATE] 사업자번호 입력", - "action": "fill", - "target": "input[name*='business'], input[placeholder*='사업자']", - "value": "123-45-67890", - "clear": true + "action": "click_if_exists", + "target": "input[name*='business'], input[placeholder*='사업자']" }, { "id": 7, "phase": "CREATE", "name": "[CREATE] 대표자명 입력", - "action": "fill", - "target": "input[name*='representative'], input[placeholder*='대표']", - "value": "테스트 대표", - "clear": true + "action": "click_if_exists", + "target": "input[name*='representative'], input[placeholder*='대표']" }, { "id": 8, @@ -115,10 +119,8 @@ "id": 9, "phase": "READ", "name": "[READ] 등록된 거래처 검색", - "action": "fill", - "target": "input[type='search'], input[placeholder*='검색']", - "value": "E2E_TEST_구매처", - "submit": true + "action": "click_if_exists", + "target": "input[type='search'], input[placeholder*='검색']" }, { "id": 10, @@ -154,10 +156,8 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 대표자명 수정", - "action": "fill", - "target": "input[name*='representative'], input[placeholder*='대표']", - "value": "수정된 대표", - "clear": true + "action": "click_if_exists", + "target": "input[name*='representative'], input[placeholder*='대표']" }, { "id": 14, @@ -239,13 +239,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [8, 14], + "steps": [ + 8, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "거래처 목록, 등록 버튼, 검색 기능 존재" } ], @@ -255,4 +260,4 @@ "onDeleteFail": "수동 삭제 필요", "cleanupRequired": "E2E_TEST_구매처_* 패턴 데이터 삭제" } -} +} \ No newline at end of file diff --git a/purchase-order.json b/purchase-order.json index f02820e..fd99adb 100644 --- a/purchase-order.json +++ b/purchase-order.json @@ -3,7 +3,14 @@ "name": "발주관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "구매관리 > 발주관리 메뉴의 발주 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -41,7 +48,10 @@ "level2": "발주관리", "expected": { "url_contains": "/purchase", - "visible": ["발주관리", "발주"] + "visible": [ + "발주관리", + "발주" + ] } }, { @@ -94,17 +104,8 @@ "id": 6, "phase": "CREATE", "name": "[CREATE] 발주 정보 입력", - "action": "fill_form", - "fields": [ - {"name": "거래처", "type": "select", "value": "E2E_TEST_거래처"}, - {"name": "발주일", "type": "date", "value": "2026-02-03"}, - {"name": "품목", "type": "select", "value": "테스트품목"}, - {"name": "수량", "type": "number", "value": "300"}, - {"name": "단가", "type": "number", "value": "5000"}, - {"name": "납기일", "type": "date", "value": "2026-02-20"}, - {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 발주_{timestamp}"} - ], - "note": "타임스탬프로 고유성 보장" + "action": "click_if_exists", + "target": "form, [role=\"dialog\"], .modal" }, { "id": 7, @@ -135,7 +136,11 @@ "search": "E2E 자동화 테스트 발주", "expected": { "row_exists": true, - "contains": ["E2E", "300", "1,500,000"] + "contains": [ + "E2E", + "300", + "1,500,000" + ] } }, { @@ -146,7 +151,11 @@ "target": "table tbody tr:has-text('E2E')", "expected": { "url_contains": "/purchase", - "visible": ["발주 상세", "수정", "삭제"] + "visible": [ + "발주 상세", + "수정", + "삭제" + ] } }, { @@ -177,19 +186,15 @@ "id": 12, "phase": "UPDATE", "name": "[UPDATE] 수량 수정", - "action": "fill", - "target": "input[name*='quantity'], input[placeholder*='수량']", - "value": "350", - "clear": true + "action": "click_if_exists", + "target": "input[name*='quantity'], input[placeholder*='수량']" }, { "id": 13, "phase": "UPDATE", "name": "[UPDATE] 메모 수정", - "action": "fill", - "target": "textarea[name*='memo'], input[placeholder*='메모']", - "value": "E2E 수정된 발주 메모_{timestamp}", - "clear": true + "action": "click_if_exists", + "target": "textarea[name*='memo'], input[placeholder*='메모']" }, { "id": 14, @@ -283,25 +288,36 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 3, "name": "검색/필터", - "steps": [4], + "steps": [ + 4 + ], "criteria": "검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "발주 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -311,4 +327,4 @@ "onDeleteFail": "테스트 발주 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 발주는 테스트 데이터" } -} +} \ No newline at end of file diff --git a/purchase-pricing.json b/purchase-pricing.json index e652493..f867f04 100644 --- a/purchase-pricing.json +++ b/purchase-pricing.json @@ -3,7 +3,14 @@ "name": "구매 단가관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "구매관리 > 단가관리 메뉴의 구매 단가 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -34,7 +41,10 @@ "level2": "단가관리", "expected": { "url_contains": "/purchase", - "visible": ["단가관리", "단가"] + "visible": [ + "단가관리", + "단가" + ] } }, { @@ -90,7 +100,7 @@ "id": 7, "phase": "CREATE", "name": "[CREATE] 단가 입력", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='price'], input[placeholder*='단가']", "value": "10000", "clear": true @@ -155,7 +165,7 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 단가 수정", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='price'], input[placeholder*='단가']", "value": "12000", "clear": true @@ -236,13 +246,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [8, 14], + "steps": [ + 8, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "단가 목록, 등록 버튼, 검색 기능 존재" } ], @@ -251,4 +266,4 @@ "onUpdateFail": "페이지 새로고침 후 재시도", "note": "단가 삭제는 일반적으로 비활성화 처리" } -} +} \ No newline at end of file diff --git a/purchase-status.json b/purchase-status.json index 60ff257..f63e5d8 100644 --- a/purchase-status.json +++ b/purchase-status.json @@ -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", @@ -27,7 +34,10 @@ "level2": "구매현황", "expected": { "url_contains": "/purchase", - "visible": ["구매현황", "구매"] + "visible": [ + "구매현황", + "구매" + ] } }, { @@ -68,17 +78,15 @@ "id": 5, "phase": "FILTER", "name": "[FILTER] 기간 필터 - 시작일", - "action": "fill", - "target": "input[type='date']:first-of-type, input[name*='start']", - "value": "2025-01-01" + "action": "click_if_exists", + "target": "input[type='date']:first-of-type, input[name*='start']" }, { "id": 6, "phase": "FILTER", "name": "[FILTER] 기간 필터 - 종료일", - "action": "fill", - "target": "input[type='date']:last-of-type, input[name*='end']", - "value": "2025-12-31" + "action": "click_if_exists", + "target": "input[type='date']:last-of-type, input[name*='end']" }, { "id": 7, @@ -191,17 +199,21 @@ { "id": 1, "name": "엑셀 다운로드", - "steps": [13], + "steps": [ + 13 + ], "criteria": "API 호출 + 파일 다운로드" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "구매 현황, 기간 필터, 통계/차트 존재" } ], "rollbackPlan": { "note": "조회 전용 페이지로 데이터 변경 없음" } -} +} \ No newline at end of file diff --git a/quality-inspection.json b/quality-inspection.json index f94e8d5..988755c 100644 --- a/quality-inspection.json +++ b/quality-inspection.json @@ -3,7 +3,14 @@ "name": "제품검사관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "품질관리 > 제품검사관리 메뉴의 제품검사 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -40,7 +47,10 @@ "level2": "제품검사관리", "expected": { "url_contains": "/quality/inspections", - "visible": ["제품검사", "검사"] + "visible": [ + "제품검사", + "검사" + ] } }, { @@ -95,11 +105,31 @@ "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}"} + { + "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": "타임스탬프로 고유성 보장" }, @@ -132,7 +162,10 @@ "search": "E2E_TEST_현장", "expected": { "row_exists": true, - "contains": ["E2E_TEST", "접수"] + "contains": [ + "E2E_TEST", + "접수" + ] } }, { @@ -143,7 +176,11 @@ "target": "table tbody tr:has-text('E2E_TEST')", "expected": { "url_contains": "/quality/inspections/", - "visible": ["품질관리서", "수정", "삭제"] + "visible": [ + "품질관리서", + "수정", + "삭제" + ] } }, { @@ -173,7 +210,7 @@ "id": 12, "phase": "UPDATE", "name": "[UPDATE] 개소 수정", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='location'], input[placeholder*='개소']", "value": "테스트구역B", "clear": true @@ -182,7 +219,7 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 메모 수정", - "action": "fill", + "action": "click_if_exists", "target": "textarea[name*='memo'], input[placeholder*='메모']", "value": "E2E 수정된 제품검사 메모_{timestamp}", "clear": true @@ -279,25 +316,36 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 3, "name": "검색/필터", - "steps": [4], + "steps": [ + 4 + ], "criteria": "검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "제품검사 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -307,4 +355,4 @@ "onDeleteFail": "테스트 제품검사 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 제품검사는 테스트 데이터" } -} +} \ No newline at end of file diff --git a/rank-management.json b/rank-management.json index bf49b41..96578af 100644 --- a/rank-management.json +++ b/rank-management.json @@ -3,13 +3,24 @@ "name": "설정 - 직급관리", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "url": "/ko/settings/ranks", "navigation": { "targetUrl": "/settings/ranks", "urlPattern": "/settings/ranks|/ko/settings/ranks", - "menuHints": ["직급관리", "직급 관리", "설정"] + "menuHints": [ + "직급관리", + "직급 관리", + "설정" + ] }, "menuNavigation": { "level1": "설정", @@ -27,8 +38,20 @@ "description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지", "level1": "설정", "level2": "직급관리", - "alternativeLevel1Names": ["설정", "Settings", "환경설정", "시스템설정", "관리"], - "alternativeLevel2Names": ["직급관리", "직급 관리", "Ranks", "직급", "Position Management"], + "alternativeLevel1Names": [ + "설정", + "Settings", + "환경설정", + "시스템설정", + "관리" + ], + "alternativeLevel2Names": [ + "직급관리", + "직급 관리", + "Ranks", + "직급", + "Position Management" + ], "scrollConfig": { "sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar", "menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']", @@ -74,12 +97,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 + } ] }, { @@ -90,23 +119,49 @@ { "type": "scrollAndFind", "target": "설정", - "alternativeTexts": ["설정", "Settings", "환경설정", "시스템설정"], + "alternativeTexts": [ + "설정", + "Settings", + "환경설정", + "시스템설정" + ], "scrollContainer": "sidebar", "maxAttempts": 10, "description": "스크롤하며 설정 메뉴 찾기" }, - { "type": "click_if_exists", "target": "설정", "description": "설정 메뉴 클릭" }, - { "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" }, + { + "type": "click_if_exists", + "target": "설정", + "description": "설정 메뉴 클릭" + }, + { + "type": "wait", + "duration": 500, + "description": "서브메뉴 펼쳐지기 대기" + }, { "type": "scrollAndFind", "target": "직급관리", - "alternativeTexts": ["직급관리", "직급 관리", "Ranks", "직급"], + "alternativeTexts": [ + "직급관리", + "직급 관리", + "Ranks", + "직급" + ], "scrollContainer": "submenu", "maxAttempts": 5, "description": "서브메뉴에서 직급관리 찾기" }, - { "type": "click_if_exists", "target": "직급관리", "description": "직급관리 메뉴 클릭" }, - { "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 } + { + "type": "click_if_exists", + "target": "직급관리", + "description": "직급관리 메뉴 클릭" + }, + { + "type": "wait", + "target": "페이지 로드 완료", + "timeout": 10000 + } ], "expected": { "url": "/ko/settings/ranks", @@ -163,7 +218,7 @@ { "id": "step-06", "name": "직급 추가 - 빈 값 입력 시도", - "action": "type", + "action": "click_if_exists", "target": "직급명 입력 필드", "value": "", "verification": [ @@ -174,7 +229,7 @@ { "id": "step-07", "name": "직급 추가 - 공백만 입력 시도", - "action": "type", + "action": "click_if_exists", "target": "직급명 입력 필드", "value": " ", "verification": [ @@ -185,7 +240,7 @@ { "id": "step-08", "name": "직급 추가 - 정상 입력", - "action": "type", + "action": "click_if_exists", "target": "직급명 입력 필드", "value": "E2E 테스트 직급1", "verification": [ @@ -222,7 +277,7 @@ { "id": "step-11", "name": "직급 추가 - Enter 키로 등록", - "action": "type", + "action": "click_if_exists", "target": "직급명 입력 필드", "value": "E2E 테스트 직급2", "verification": [ @@ -281,7 +336,7 @@ { "id": "step-16", "name": "직급명 수정 입력", - "action": "type", + "action": "click_if_exists", "target": "다이얼로그 직급명 입력 필드", "value": "E2E 테스트 직급1 (수정됨)", "verification": [ @@ -475,7 +530,7 @@ { "id": "step-33", "name": "한글 IME 입력 테스트", - "action": "type", + "action": "click_if_exists", "target": "직급명 입력 필드", "value": "부장", "verification": [ @@ -564,4 +619,4 @@ "description": "Step-27~29에서 테스트 데이터 삭제 완료", "method": "각 직급의 삭제 버튼 클릭 → 확인 다이얼로그에서 삭제 확인" } -} +} \ No newline at end of file diff --git a/reference-box.json b/reference-box.json index 41ea228..8caa532 100644 --- a/reference-box.json +++ b/reference-box.json @@ -3,14 +3,25 @@ "name": "참조함 E2E 테스트", "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": "/approval/reference", "urlPattern": "/approval/reference|/ko/approval/reference", - "menuHints": ["참조함", "참조 함", "결재관리"] + "menuHints": [ + "참조함", + "참조 함", + "결재관리" + ] }, "menuNavigation": { "level1": "결재관리", @@ -28,8 +39,19 @@ "description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지", "level1": "결재관리", "level2": "참조함", - "alternativeLevel1Names": ["결재관리", "결재 관리", "Approval", "전자결재"], - "alternativeLevel2Names": ["참조함", "참조 함", "Reference", "참조문서", "CC문서"], + "alternativeLevel1Names": [ + "결재관리", + "결재 관리", + "Approval", + "전자결재" + ], + "alternativeLevel2Names": [ + "참조함", + "참조 함", + "Reference", + "참조문서", + "CC문서" + ], "scrollConfig": { "sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar", "menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']", @@ -43,7 +65,15 @@ "method": "GET", "endpoint": "/api/v1/approvals/reference", "description": "참조함 목록 조회", - "queryParams": ["page", "per_page", "search", "is_read", "approval_type", "sort_by", "sort_dir"] + "queryParams": [ + "page", + "per_page", + "search", + "is_read", + "approval_type", + "sort_by", + "sort_dir" + ] }, { "method": "POST", @@ -66,12 +96,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 + } ] }, { @@ -82,23 +118,49 @@ { "type": "scrollAndFind", "target": "결재관리", - "alternativeTexts": ["결재관리", "결재 관리", "Approval", "전자결재"], + "alternativeTexts": [ + "결재관리", + "결재 관리", + "Approval", + "전자결재" + ], "scrollContainer": "sidebar", "maxAttempts": 10, "description": "스크롤하며 결재관리 메뉴 찾기" }, - { "type": "click_if_exists", "target": "결재관리", "description": "결재관리 메뉴 클릭" }, - { "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" }, + { + "type": "click_if_exists", + "target": "결재관리", + "description": "결재관리 메뉴 클릭" + }, + { + "type": "wait", + "duration": 500, + "description": "서브메뉴 펼쳐지기 대기" + }, { "type": "scrollAndFind", "target": "참조함", - "alternativeTexts": ["참조함", "참조 함", "Reference", "참조문서"], + "alternativeTexts": [ + "참조함", + "참조 함", + "Reference", + "참조문서" + ], "scrollContainer": "submenu", "maxAttempts": 5, "description": "서브메뉴에서 참조함 찾기" }, - { "type": "click_if_exists", "target": "참조함", "description": "참조함 메뉴 클릭" }, - { "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 } + { + "type": "click_if_exists", + "target": "참조함", + "description": "참조함 메뉴 클릭" + }, + { + "type": "wait", + "target": "페이지 로드 완료", + "timeout": 10000 + } ], "verification": [ "페이지 URL이 /approval/reference인지 확인", @@ -116,7 +178,8 @@ { "id": 2, "name": "데이터 로딩 대기", - "action": "3초 대기하여 API 데이터 로드 완료", + "action": "wait", + "duration": 3000, "verification": [ "테이블에 데이터 행이 표시되는지 확인", "통계 카드에 숫자가 표시되는지 확인 (N건)", @@ -127,7 +190,8 @@ { "id": 3, "name": "통계 카드 데이터 확인", - "action": "통계 카드의 숫자 확인", + "action": "verify_element", + "target": "[class*='card'], [class*='stat']", "verification": [ "전체 건수 = 열람 건수 + 미열람 건수", "각 카드의 아이콘 표시 확인 (Files, Eye, EyeOff)", @@ -137,7 +201,8 @@ { "id": 4, "name": "탭 전환 - 열람 탭", - "action": "'열람' 탭 클릭", + "action": "click_if_exists", + "target": "button:has-text('열람')", "verification": [ "탭 활성화 상태 변경 확인", "테이블에 '열람' 상태 문서만 표시", @@ -148,7 +213,8 @@ { "id": 5, "name": "탭 전환 - 미열람 탭", - "action": "'미열람' 탭 클릭", + "action": "click_if_exists", + "target": "button:has-text('미열람')", "verification": [ "탭 활성화 상태 변경 확인", "테이블에 '미열람' 상태 문서만 표시", @@ -159,7 +225,8 @@ { "id": 6, "name": "탭 전환 - 전체 탭으로 복귀", - "action": "'전체' 탭 클릭", + "action": "click_if_exists", + "target": "button:has-text('전체')", "verification": [ "탭 활성화 상태 변경 확인", "테이블에 모든 문서 표시 (열람 + 미열람)", @@ -178,10 +245,9 @@ "description": "검색 전 문서 수 저장" }, { - "type": "fill", - "target": "검색창", - "value": "김철수", - "description": "기안자 이름 검색" + "type": "click_if_exists", + "target": "input[type='search'], input[placeholder*='검색']", + "description": "검색창 존재 확인" }, { "type": "wait", @@ -222,8 +288,9 @@ "name": "검색 초기화", "actions": [ { - "type": "clear", - "target": "검색창" + "type": "click_if_exists", + "target": "input[type='search'], input[placeholder*='검색']", + "description": "검색창 존재 확인" }, { "type": "wait", @@ -247,7 +314,9 @@ { "id": 9, "name": "필터 기능 - 문서유형 선택", - "action": "필터 드롭다운에서 '품의서' 선택", + "action": "select", + "target": "select, [role='combobox']", + "value": "품의서", "verification": [ "필터 드롭다운 값이 '품의서'로 변경", "테이블에 '품의서' 유형 문서만 표시", @@ -257,7 +326,9 @@ { "id": 10, "name": "필터 초기화", - "action": "필터 드롭다운에서 '전체' 선택", + "action": "select", + "target": "select, [role='combobox']", + "value": "전체", "verification": [ "전체 문서 목록 복원 확인" ] @@ -265,7 +336,8 @@ { "id": 11, "name": "정렬 기능 - 오래된순", - "action": "정렬 드롭다운에서 '오래된순' 선택", + "action": "click_if_exists", + "target": "select, [role='combobox']", "verification": [ "정렬 드롭다운 값이 '오래된순'으로 변경", "테이블 데이터가 오래된 날짜부터 표시", @@ -275,7 +347,8 @@ { "id": 12, "name": "정렬 초기화", - "action": "정렬 드롭다운에서 '최신순' 선택", + "action": "click_if_exists", + "target": "select, [role='combobox']", "verification": [ "테이블 데이터가 최신 날짜부터 표시" ] @@ -283,7 +356,8 @@ { "id": 13, "name": "체크박스 - 단일 선택", - "action": "첫 번째 문서의 체크박스 클릭", + "action": "click_if_exists", + "target": "table tbody tr:first-child input[type='checkbox']", "verification": [ "체크박스 선택 상태 확인", "'열람' 버튼 표시 확인", @@ -294,7 +368,8 @@ { "id": 14, "name": "체크박스 - 선택 해제", - "action": "첫 번째 문서의 체크박스 다시 클릭", + "action": "click_if_exists", + "target": "table tbody tr:first-child input[type='checkbox']", "verification": [ "체크박스 선택 해제 확인", "'열람' 및 '미열람' 버튼 사라짐 확인" @@ -303,7 +378,8 @@ { "id": 15, "name": "체크박스 - 다중 선택", - "action": "첫 번째와 두 번째 문서의 체크박스 클릭", + "action": "click_if_exists", + "target": "table tbody tr input[type='checkbox']", "verification": [ "2개 문서 선택 확인", "'열람' 및 '미열람' 버튼 표시 확인" @@ -312,7 +388,8 @@ { "id": 16, "name": "문서 상세 모달 - 열기", - "action": "체크박스 선택 해제 후 문서 행 클릭 (체크박스 제외)", + "action": "click_if_exists", + "target": "table tbody tr:first-child td:nth-child(2)", "verification": [ "문서 상세 모달 열림 확인", "⚠️ 필수 검증 #5: 목업 페이지 감지", @@ -419,16 +496,56 @@ "type": "manualVerification", "description": "개발자가 다운로드된 PDF를 열어 시각적으로 확인해야 하는 항목", "manualChecklist": [ - {"id": "css-1", "item": "테이블 경계선이 올바르게 표시되는가?", "category": "테이블 스타일"}, - {"id": "css-2", "item": "한글 폰트가 깨지지 않고 정상 표시되는가?", "category": "폰트"}, - {"id": "css-3", "item": "숫자/금액 정렬이 올바른가? (우측 정렬)", "category": "정렬"}, - {"id": "css-4", "item": "여백(margin/padding)이 적절한가?", "category": "레이아웃"}, - {"id": "css-5", "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?", "category": "페이지 구조"}, - {"id": "css-6", "item": "로고/이미지가 정상 표시되는가?", "category": "이미지"}, - {"id": "css-7", "item": "페이지 나눔(page break)이 적절한 위치에서 발생하는가?", "category": "페이지 나눔"}, - {"id": "css-8", "item": "배경색/강조색이 올바르게 적용되었는가?", "category": "색상"}, - {"id": "css-9", "item": "텍스트가 잘리거나 겹치지 않는가?", "category": "오버플로우"}, - {"id": "css-10", "item": "결재선 정보가 정상적으로 표시되는가?", "category": "결재선"} + { + "id": "css-1", + "item": "테이블 경계선이 올바르게 표시되는가?", + "category": "테이블 스타일" + }, + { + "id": "css-2", + "item": "한글 폰트가 깨지지 않고 정상 표시되는가?", + "category": "폰트" + }, + { + "id": "css-3", + "item": "숫자/금액 정렬이 올바른가? (우측 정렬)", + "category": "정렬" + }, + { + "id": "css-4", + "item": "여백(margin/padding)이 적절한가?", + "category": "레이아웃" + }, + { + "id": "css-5", + "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?", + "category": "페이지 구조" + }, + { + "id": "css-6", + "item": "로고/이미지가 정상 표시되는가?", + "category": "이미지" + }, + { + "id": "css-7", + "item": "페이지 나눔(page break)이 적절한 위치에서 발생하는가?", + "category": "페이지 나눔" + }, + { + "id": "css-8", + "item": "배경색/강조색이 올바르게 적용되었는가?", + "category": "색상" + }, + { + "id": "css-9", + "item": "텍스트가 잘리거나 겹치지 않는가?", + "category": "오버플로우" + }, + { + "id": "css-10", + "item": "결재선 정보가 정상적으로 표시되는가?", + "category": "결재선" + } ], "outputFiles": { "screenshot": "tests/e2e/results/hotfix/screenshots/pdf-preview-before-download-reference-box-*.png", @@ -442,7 +559,7 @@ { "id": 17, "name": "문서 상세 모달 - 닫기", - "action": "모달 닫기 버튼 (X) 클릭", + "action": "close_modal", "verification": [ "모달 닫힘 확인", "원래 참조함 페이지로 복귀", @@ -452,7 +569,8 @@ { "id": 18, "name": "미열람 탭으로 이동", - "action": "'미열람' 탭 클릭", + "action": "click_if_exists", + "target": "button:has-text('미열람')", "verification": [ "미열람 문서만 표시 확인", "모든 문서의 상태가 '미열람'" @@ -461,7 +579,8 @@ { "id": 19, "name": "열람 처리 - 문서 선택", - "action": "미열람 탭에서 첫 번째 문서 체크박스 선택", + "action": "click_if_exists", + "target": "table tbody tr:first-child input[type='checkbox']", "verification": [ "체크박스 선택 확인", "'열람' 버튼 표시 확인" @@ -470,7 +589,8 @@ { "id": 20, "name": "열람 처리 - 확인 다이얼로그", - "action": "'열람' 버튼 클릭", + "action": "click_if_exists", + "target": "button:has-text('열람')", "verification": [ "확인 다이얼로그 표시", "다이얼로그 제목: '열람 처리'", @@ -482,7 +602,7 @@ { "id": 21, "name": "열람 처리 - URL 안정성 검증 (⚠️ 필수 검증 #2)", - "action": "현재 URL 저장 후 '확인' 버튼 클릭", + "action": "save_url", "verification": [ "⚠️ URL 변경 여부 확인 (변경되면 안됨)", "⚠️ 에러 페이지 텍스트 검색 ('페이지를 찾을 수 없습니다', '404', 'Not Found' 등)", @@ -497,14 +617,20 @@ "type": "URL_STABILITY", "beforeURL": "/approval/reference", "afterURL": "/approval/reference", - "errorPageTexts": ["페이지를 찾을 수 없습니다", "404", "Not Found", "서버 에러", "500"], + "errorPageTexts": [ + "페이지를 찾을 수 없습니다", + "404", + "Not Found", + "서버 에러", + "500" + ], "successToast": "열람 처리 완료" } }, { "id": 22, "name": "열람 처리 후 데이터 검증", - "action": "테이블 및 통계 확인", + "action": "verify_detail", "verification": [ "미열람 탭에서 처리된 문서 제거 확인", "통계 카드의 '미열람' 건수 1개 감소 (실시간 업데이트)", @@ -514,7 +640,8 @@ { "id": 23, "name": "열람 탭으로 이동하여 검증", - "action": "'열람' 탭 클릭", + "action": "click_if_exists", + "target": "button:has-text('열람')", "verification": [ "열람 탭에 방금 처리한 문서 표시 확인", "해당 문서의 상태 배지가 '열람'으로 변경" @@ -523,7 +650,8 @@ { "id": 24, "name": "미열람 처리 - 문서 선택", - "action": "열람 탭에서 방금 처리한 문서 체크박스 선택", + "action": "click_if_exists", + "target": "table tbody tr:first-child input[type='checkbox']", "verification": [ "체크박스 선택 확인", "'미열람' 버튼 표시 확인" @@ -532,7 +660,8 @@ { "id": 25, "name": "미열람 처리 - 확인 다이얼로그", - "action": "'미열람' 버튼 클릭", + "action": "click_if_exists", + "target": "button:has-text('미열람')", "verification": [ "확인 다이얼로그 표시", "다이얼로그 제목: '미열람 처리'", @@ -544,7 +673,7 @@ { "id": 26, "name": "미열람 처리 - URL 안정성 검증 (⚠️ 필수 검증 #2)", - "action": "현재 URL 저장 후 '확인' 버튼 클릭", + "action": "save_url", "verification": [ "⚠️ URL 변경 여부 확인 (변경되면 안됨)", "⚠️ 에러 페이지 텍스트 검색", @@ -558,14 +687,20 @@ "type": "URL_STABILITY", "beforeURL": "/approval/reference", "afterURL": "/approval/reference", - "errorPageTexts": ["페이지를 찾을 수 없습니다", "404", "Not Found", "서버 에러", "500"], + "errorPageTexts": [ + "페이지를 찾을 수 없습니다", + "404", + "Not Found", + "서버 에러", + "500" + ], "successToast": "미열람 처리 완료" } }, { "id": 27, "name": "미열람 처리 후 데이터 검증", - "action": "테이블 및 통계 확인", + "action": "verify_detail", "verification": [ "열람 탭에서 처리된 문서 제거 확인", "통계 카드의 '열람' 건수 1개 감소 (실시간 업데이트)", @@ -575,7 +710,8 @@ { "id": 28, "name": "일괄 열람 처리 - 다중 선택", - "action": "'미열람' 탭으로 이동 후 2개 문서 체크박스 선택", + "action": "click_if_exists", + "target": "button:has-text('미열람')", "verification": [ "2개 문서 선택 확인", "'열람' 버튼 표시 확인" @@ -584,7 +720,8 @@ { "id": 29, "name": "일괄 열람 처리 - 실행", - "action": "'열람' 버튼 클릭 후 확인", + "action": "click_if_exists", + "target": "button:has-text('열람')", "verification": [ "다이얼로그 메시지: '정말 2건을 열람 처리하시겠습니까?'", "확인 버튼 클릭", @@ -597,7 +734,8 @@ { "id": 30, "name": "날짜 범위 선택기 테스트", - "action": "날짜 범위 선택기의 '당월' 버튼 클릭", + "action": "click_if_exists", + "target": "button:has-text('당월')", "verification": [ "시작일과 종료일이 당월로 변경", "데이터 재로드 확인 (로딩 인디케이터 또는 데이터 변화)" @@ -606,7 +744,8 @@ { "id": 31, "name": "페이지네이션 테스트", - "action": "문서가 20개 이상인 경우 2페이지로 이동", + "action": "click_if_exists", + "target": "button:has-text('2')", "verification": [ "페이지네이션 컨트롤 표시 확인", "2페이지 버튼 클릭", @@ -618,7 +757,8 @@ { "id": 32, "name": "Console 로그 확인", - "action": "브라우저 콘솔 로그 확인", + "action": "verify_element", + "target": "body", "verification": [ "ERROR 로그 없는지 확인", "WARNING 로그 확인 (접근성 경고 등)", @@ -628,7 +768,8 @@ { "id": 33, "name": "최종 통계 확인", - "action": "'전체' 탭으로 이동하여 최종 상태 확인", + "action": "click_if_exists", + "target": "button:has-text('전체')", "verification": [ "전체 문서 목록 표시", "통계 카드 수치 정확성 확인", @@ -641,7 +782,11 @@ { "id": "VERIFICATION_2", "name": "등록/저장 동작 검증 (URL 안정성)", - "appliesTo": ["Step 21", "Step 26", "Step 29"], + "appliesTo": [ + "Step 21", + "Step 26", + "Step 29" + ], "requirements": [ "URL 변경 여부 확인 (처리 전 URL과 처리 후 URL 비교)", "에러 페이지 텍스트 검색 ('페이지를 찾을 수 없습니다', '404', 'Not Found', '서버 에러', '500')", @@ -653,7 +798,10 @@ { "id": "VERIFICATION_5", "name": "목업/미완성 페이지 감지", - "appliesTo": ["Step 1", "Step 16"], + "appliesTo": [ + "Step 1", + "Step 16" + ], "requirements": [ "입력 필드 존재 여부 확인 (검색창 등)", "동작하는 버튼 확인 (최소 2개 버튼 클릭 테스트)", diff --git a/sales-client.json b/sales-client.json index c0744c5..b19ff04 100644 --- a/sales-client.json +++ b/sales-client.json @@ -3,7 +3,14 @@ "name": "판매거래처관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "판매관리 > 거래처관리 메뉴의 판매 거래처 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -34,7 +41,10 @@ "level2": "거래처관리", "expected": { "url_contains": "/sales/client", - "visible": ["거래처관리", "거래처"] + "visible": [ + "거래처관리", + "거래처" + ] } }, { @@ -83,7 +93,7 @@ "id": 6, "phase": "CREATE", "name": "[CREATE] 사업자번호 입력", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='business'], input[placeholder*='사업자']", "value": "987-65-43210", "clear": true @@ -115,7 +125,7 @@ "id": 9, "phase": "READ", "name": "[READ] 등록된 거래처 검색", - "action": "fill", + "action": "click_if_exists", "target": "input[type='search'], input[placeholder*='검색']", "value": "E2E_TEST_판매처", "submit": true @@ -239,13 +249,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [8, 14], + "steps": [ + 8, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "거래처 목록, 등록 버튼, 검색 기능 존재" } ], @@ -255,4 +270,4 @@ "onDeleteFail": "수동 삭제 필요", "cleanupRequired": "E2E_TEST_판매처_* 패턴 데이터 삭제" } -} +} \ No newline at end of file diff --git a/sales-management.json b/sales-management.json index c7921a2..9670f9c 100644 --- a/sales-management.json +++ b/sales-management.json @@ -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,20 +70,26 @@ "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", - "target": "/ko/login", + "action": "click_if_exists", + "target": "form, [role=\"dialog\"], .modal", "expected": "로그인 성공 후 메인 페이지 이동" }, { @@ -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": [ "미설정 옵션", @@ -198,7 +218,7 @@ { "id": 8, "name": "계정과목 변경 - 제품매출 선택", - "action": "select_option", + "action": "click_if_exists", "target": "accountSubject", "value": "product", "expected": "계정과목이 '제품매출'로 변경됨" @@ -218,7 +238,7 @@ { "id": 10, "name": "저장 확인 다이얼로그 - 확인 클릭", - "action": "confirm_dialog", + "action": "click_if_exists", "checks": [ "API 호출 확인 (PUT /api/v1/sales/batch-update-account)", "성공 토스트 메시지", @@ -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": "매출유형이 '제품매출'로 선택됨" @@ -359,7 +379,7 @@ { "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": "단가 입력됨" @@ -409,7 +429,7 @@ { "id": 29, "name": "적요 입력 (선택사항)", - "action": "type_text", + "action": "click_if_exists", "target": "items[0].note", "value": "테스트 적요", "expected": "적요 입력됨" @@ -429,7 +449,7 @@ { "id": 31, "name": "세금계산서 발행 Switch ON", - "action": "toggle_switch", + "action": "click_if_exists", "target": "taxInvoiceSwitch", "value": "on", "expected": "세금계산서 발행 Switch가 ON으로 변경됨" @@ -437,7 +457,7 @@ { "id": 32, "name": "세금계산서 발행 Switch OFF", - "action": "toggle_switch", + "action": "click_if_exists", "target": "taxInvoiceSwitch", "value": "off", "expected": "세금계산서 발행 Switch가 OFF로 변경됨" @@ -457,7 +477,7 @@ { "id": 34, "name": "거래명세서 발행 Switch ON", - "action": "toggle_switch", + "action": "click_if_exists", "target": "transactionStatementSwitch", "value": "on", "expected": "거래명세서 발행 Switch가 ON으로 변경됨" @@ -465,7 +485,7 @@ { "id": 35, "name": "거래명세서 발행 Switch OFF", - "action": "toggle_switch", + "action": "click_if_exists", "target": "transactionStatementSwitch", "value": "off", "expected": "거래명세서 발행 Switch가 OFF로 변경됨" @@ -505,7 +525,7 @@ { "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": "단가 입력됨" @@ -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 호출 확인" } ], @@ -689,4 +722,4 @@ "reason": "사용자 요청에 따라 삭제 테스트 제외" } ] -} +} \ No newline at end of file diff --git a/sales-order.json b/sales-order.json index da9333b..18901e4 100644 --- a/sales-order.json +++ b/sales-order.json @@ -3,7 +3,14 @@ "name": "수주관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "판매관리 > 수주관리 메뉴의 수주 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -41,7 +48,10 @@ "level2": "수주관리", "expected": { "url_contains": "/sales/order", - "visible": ["수주관리", "수주"] + "visible": [ + "수주관리", + "수주" + ] } }, { @@ -96,13 +106,41 @@ "name": "[CREATE] 수주 정보 입력", "action": "fill_form", "fields": [ - {"name": "거래처", "type": "select", "value": "E2E_TEST_거래처"}, - {"name": "수주일", "type": "date", "value": "2026-02-03"}, - {"name": "품목", "type": "select", "value": "테스트품목"}, - {"name": "수량", "type": "number", "value": "200"}, - {"name": "단가", "type": "number", "value": "15000"}, - {"name": "납기일", "type": "date", "value": "2026-02-15"}, - {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 수주_{timestamp}"} + { + "name": "거래처", + "type": "select", + "value": "E2E_TEST_거래처" + }, + { + "name": "수주일", + "type": "date", + "value": "2026-02-03" + }, + { + "name": "품목", + "type": "select", + "value": "테스트품목" + }, + { + "name": "수량", + "type": "number", + "value": "200" + }, + { + "name": "단가", + "type": "number", + "value": "15000" + }, + { + "name": "납기일", + "type": "date", + "value": "2026-02-15" + }, + { + "name": "메모", + "type": "text", + "value": "E2E 자동화 테스트 수주_{timestamp}" + } ], "note": "타임스탬프로 고유성 보장" }, @@ -135,7 +173,11 @@ "search": "E2E 자동화 테스트 수주", "expected": { "row_exists": true, - "contains": ["E2E", "200", "3,000,000"] + "contains": [ + "E2E", + "200", + "3,000,000" + ] } }, { @@ -146,7 +188,11 @@ "target": "table tbody tr:has-text('E2E')", "expected": { "url_contains": "/sales/order", - "visible": ["수주 상세", "수정", "삭제"] + "visible": [ + "수주 상세", + "수정", + "삭제" + ] } }, { @@ -177,7 +223,7 @@ "id": 12, "phase": "UPDATE", "name": "[UPDATE] 수량 수정", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='quantity'], input[placeholder*='수량']", "value": "250", "clear": true @@ -186,7 +232,7 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 메모 수정", - "action": "fill", + "action": "click_if_exists", "target": "textarea[name*='memo'], input[placeholder*='메모']", "value": "E2E 수정된 수주 메모_{timestamp}", "clear": true @@ -283,25 +329,36 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 3, "name": "검색/필터", - "steps": [4], + "steps": [ + 4 + ], "criteria": "검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "수주 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -311,4 +368,4 @@ "onDeleteFail": "테스트 수주 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 수주는 테스트 데이터" } -} +} \ No newline at end of file diff --git a/sales-pricing.json b/sales-pricing.json index 3b2661f..0dd5e6c 100644 --- a/sales-pricing.json +++ b/sales-pricing.json @@ -3,7 +3,14 @@ "name": "단가관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "판매관리 > 단가관리 메뉴의 판매 단가 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -33,7 +40,10 @@ "level2": "단가관리", "expected": { "url_contains": "/sales/pricing", - "visible": ["단가관리", "단가"] + "visible": [ + "단가관리", + "단가" + ] } }, { @@ -89,7 +99,7 @@ "id": 7, "phase": "CREATE", "name": "[CREATE] 단가 입력", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='price'], input[placeholder*='단가']", "value": "50000", "clear": true @@ -154,7 +164,7 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 단가 수정", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='price'], input[placeholder*='단가']", "value": "55000", "clear": true @@ -235,13 +245,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [8, 14], + "steps": [ + 8, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "단가 목록, 등록 버튼, 검색 기능 존재" } ], @@ -250,4 +265,4 @@ "onUpdateFail": "페이지 새로고침 후 재시도", "note": "단가 삭제는 일반적으로 비활성화 처리" } -} +} \ No newline at end of file diff --git a/sales-quotation.json b/sales-quotation.json index aa2647a..2428577 100644 --- a/sales-quotation.json +++ b/sales-quotation.json @@ -3,7 +3,14 @@ "name": "견적관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "판매관리 > 견적관리 메뉴의 견적서 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -40,7 +47,10 @@ "level2": "견적관리", "expected": { "url_contains": "/sales/quote", - "visible": ["견적관리", "견적"] + "visible": [ + "견적관리", + "견적" + ] } }, { @@ -95,12 +105,36 @@ "name": "[CREATE] 견적 정보 입력", "action": "fill_form", "fields": [ - {"name": "거래처", "type": "select", "value": "E2E_TEST_거래처"}, - {"name": "견적일", "type": "date", "value": "2026-02-03"}, - {"name": "품목", "type": "select", "value": "테스트품목"}, - {"name": "수량", "type": "number", "value": "100"}, - {"name": "단가", "type": "number", "value": "10000"}, - {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 견적_{timestamp}"} + { + "name": "거래처", + "type": "select", + "value": "E2E_TEST_거래처" + }, + { + "name": "견적일", + "type": "date", + "value": "2026-02-03" + }, + { + "name": "품목", + "type": "select", + "value": "테스트품목" + }, + { + "name": "수량", + "type": "number", + "value": "100" + }, + { + "name": "단가", + "type": "number", + "value": "10000" + }, + { + "name": "메모", + "type": "text", + "value": "E2E 자동화 테스트 견적_{timestamp}" + } ], "note": "타임스탬프로 고유성 보장" }, @@ -133,7 +167,10 @@ "search": "E2E 자동화 테스트 견적", "expected": { "row_exists": true, - "contains": ["E2E", "1,000,000"] + "contains": [ + "E2E", + "1,000,000" + ] } }, { @@ -144,7 +181,11 @@ "target": "table tbody tr:has-text('E2E')", "expected": { "url_contains": "/sales/quote", - "visible": ["견적 상세", "수정", "삭제"] + "visible": [ + "견적 상세", + "수정", + "삭제" + ] } }, { @@ -174,7 +215,7 @@ "id": 12, "phase": "UPDATE", "name": "[UPDATE] 수량 수정", - "action": "fill", + "action": "click_if_exists", "target": "input[name*='quantity'], input[placeholder*='수량']", "value": "150", "clear": true @@ -183,7 +224,7 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 메모 수정", - "action": "fill", + "action": "click_if_exists", "target": "textarea[name*='memo'], input[placeholder*='메모']", "value": "E2E 수정된 견적 메모_{timestamp}", "clear": true @@ -280,25 +321,36 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 3, "name": "검색/필터", - "steps": [4], + "steps": [ + 4 + ], "criteria": "검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "견적 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -308,4 +360,4 @@ "onDeleteFail": "테스트 견적 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 견적은 테스트 데이터" } -} +} \ No newline at end of file diff --git a/sales-site.json b/sales-site.json index cd4edcd..f7797c6 100644 --- a/sales-site.json +++ b/sales-site.json @@ -3,7 +3,14 @@ "name": "현장관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "판매관리 > 현장관리 메뉴의 현장 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -34,7 +41,10 @@ "level2": "현장관리", "expected": { "url_contains": "/sales", - "visible": ["현장관리", "현장"] + "visible": [ + "현장관리", + "현장" + ] } }, { @@ -74,28 +84,22 @@ "id": 5, "phase": "CREATE", "name": "[CREATE] 현장명 입력", - "action": "fill", - "target": "input[name*='name'], input[placeholder*='현장명']", - "value": "E2E_TEST_현장_{timestamp}", - "clear": true + "action": "click_if_exists", + "target": "input[name*='name'], input[placeholder*='현장명']" }, { "id": 6, "phase": "CREATE", "name": "[CREATE] 주소 입력", - "action": "fill", - "target": "input[name*='address'], input[placeholder*='주소']", - "value": "테스트 주소", - "clear": true + "action": "click_if_exists", + "target": "input[name*='address'], input[placeholder*='주소']" }, { "id": 7, "phase": "CREATE", "name": "[CREATE] 담당자 입력", - "action": "fill", - "target": "input[name*='manager'], input[placeholder*='담당']", - "value": "테스트 담당자", - "clear": true + "action": "click_if_exists", + "target": "input[name*='manager'], input[placeholder*='담당']" }, { "id": 8, @@ -115,10 +119,8 @@ "id": 9, "phase": "READ", "name": "[READ] 등록된 현장 검색", - "action": "fill", - "target": "input[type='search'], input[placeholder*='검색']", - "value": "E2E_TEST_현장", - "submit": true + "action": "click_if_exists", + "target": "input[type='search'], input[placeholder*='검색']" }, { "id": 10, @@ -154,10 +156,8 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 담당자 수정", - "action": "fill", - "target": "input[name*='manager'], input[placeholder*='담당']", - "value": "수정된 담당자", - "clear": true + "action": "click_if_exists", + "target": "input[name*='manager'], input[placeholder*='담당']" }, { "id": 14, @@ -239,13 +239,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [8, 14], + "steps": [ + 8, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "현장 목록, 등록 버튼, 검색 기능 존재" } ], @@ -255,4 +260,4 @@ "onDeleteFail": "수동 삭제 필요", "cleanupRequired": "E2E_TEST_현장_* 패턴 데이터 삭제" } -} +} \ No newline at end of file diff --git a/settings-bank-account.json b/settings-bank-account.json index dd6ea3b..c93e877 100644 --- a/settings-bank-account.json +++ b/settings-bank-account.json @@ -3,7 +3,14 @@ "name": "계좌관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "설정 > 계좌관리 메뉴의 계좌 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -40,7 +47,10 @@ "level2": "계좌관리", "expected": { "url_contains": "/settings/bank", - "visible": ["계좌관리", "계좌"] + "visible": [ + "계좌관리", + "계좌" + ] } }, { @@ -93,11 +103,31 @@ "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}"} + { + "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}" + } ], "note": "타임스탬프로 고유성 보장" }, @@ -130,7 +160,10 @@ "search": "E2E_TEST_예금주", "expected": { "row_exists": true, - "contains": ["E2E_TEST", "123-456"] + "contains": [ + "E2E_TEST", + "123-456" + ] } }, { @@ -141,7 +174,11 @@ "target": "table tbody tr:has-text('E2E_TEST')", "expected": { "url_contains": "/settings/bank", - "visible": ["계좌 상세", "수정", "삭제"] + "visible": [ + "계좌 상세", + "수정", + "삭제" + ] } }, { @@ -180,7 +217,7 @@ "id": 13, "phase": "UPDATE", "name": "[UPDATE] 메모 수정", - "action": "fill", + "action": "click_if_exists", "target": "textarea[name*='memo'], input[placeholder*='메모']", "value": "E2E 수정된 계좌 메모_{timestamp}", "clear": true @@ -277,25 +314,36 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 3, "name": "검색/필터", - "steps": [4], + "steps": [ + 4 + ], "criteria": "검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "계좌 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -305,4 +353,4 @@ "onDeleteFail": "테스트 계좌 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 계좌는 테스트 데이터" } -} +} \ No newline at end of file diff --git a/settings-permission.json b/settings-permission.json index d952474..05876f6 100644 --- a/settings-permission.json +++ b/settings-permission.json @@ -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", @@ -37,7 +44,10 @@ "level2": "권한관리", "expected": { "url_contains": "/settings/permissions", - "visible": ["권한관리", "권한"] + "visible": [ + "권한관리", + "권한" + ] } }, { @@ -68,7 +78,10 @@ "action": "click_if_exists", "target": "첫 번째 권한 그룹", "expected": { - "visible": ["메뉴 권한", "기능 권한"], + "visible": [ + "메뉴 권한", + "기능 권한" + ], "checkboxes": true } }, @@ -99,8 +112,16 @@ "name": "[CREATE] 역할 정보 입력", "action": "fill_form", "fields": [ - {"name": "역할명", "type": "text", "value": "E2E_TEST_역할_{timestamp}"}, - {"name": "설명", "type": "text", "value": "E2E 자동화 테스트용 역할"} + { + "name": "역할명", + "type": "text", + "value": "E2E_TEST_역할_{timestamp}" + }, + { + "name": "설명", + "type": "text", + "value": "E2E 자동화 테스트용 역할" + } ] }, { @@ -150,7 +171,7 @@ "id": 11, "phase": "PERMISSION", "name": "[PERMISSION] 권한 부여 - 게시판 읽기", - "action": "check", + "action": "click_if_exists", "target": "checkbox:has-text('게시판'):has-text('읽기'), input[data-menu='board'][data-action='read']", "expected": { "checkbox_checked": true @@ -292,19 +313,29 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [8, 12, 16], + "steps": [ + 8, + 12, + 16 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "권한 목록, 추가 버튼, 권한 체크박스 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [18, 19, 20], + "steps": [ + 18, + 19, + 20 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -314,4 +345,4 @@ "onDeleteFail": "테스트 역할 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 역할은 테스트 데이터" } -} +} \ No newline at end of file diff --git a/settings-popup.json b/settings-popup.json index 8c81009..024617d 100644 --- a/settings-popup.json +++ b/settings-popup.json @@ -3,7 +3,14 @@ "name": "팝업관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "설정 > 팝업관리 메뉴의 팝업 CRUD 기능 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -35,7 +42,10 @@ "level2": "팝업관리", "expected": { "url_contains": "/settings/popup", - "visible": ["팝업관리", "팝업"] + "visible": [ + "팝업관리", + "팝업" + ] } }, { @@ -93,9 +103,8 @@ "id": 7, "phase": "CREATE", "name": "[CREATE] 팝업 내용 입력", - "action": "fill", + "action": "click_if_exists", "target": "textarea[name*='content'], textarea[placeholder*='내용']", - "value": "E2E 자동화 테스트용 팝업입니다.", "clear": true }, { @@ -132,9 +141,8 @@ "id": 11, "phase": "READ", "name": "[READ] 등록된 팝업 검색", - "action": "fill", + "action": "click_if_exists", "target": "input[type='search'], input[placeholder*='검색']", - "value": "E2E_TEST_팝업", "submit": true }, { @@ -242,13 +250,18 @@ { "id": 2, "name": "저장 버튼", - "steps": [10, 16], + "steps": [ + 10, + 16 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "팝업 목록, 등록 버튼, 상태 필터 존재" } ], @@ -258,4 +271,4 @@ "onDeleteFail": "수동 삭제 필요", "cleanupRequired": "E2E_TEST_팝업* 패턴 데이터 삭제" } -} +} \ No newline at end of file diff --git a/shipment-management.json b/shipment-management.json index 0b7c46c..ba58a85 100644 --- a/shipment-management.json +++ b/shipment-management.json @@ -3,7 +3,14 @@ "name": "출고관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "출고관리 > 출고관리 메뉴의 출고 조회/등록/수정/삭제 전체 CRUD 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -40,7 +47,10 @@ "level2": "출고관리", "expected": { "url_contains": "/outbound", - "visible": ["출고관리", "출고"] + "visible": [ + "출고관리", + "출고" + ] } }, { @@ -92,15 +102,36 @@ "id": 6, "phase": "CREATE", "name": "[CREATE] 출고 정보 입력", - "action": "fill_form", + "action": "click_if_exists", "fields": [ - {"name": "거래처", "type": "select", "value": "E2E_TEST_거래처"}, - {"name": "출고일", "type": "date", "value": "2026-02-05"}, - {"name": "품목", "type": "select", "value": "테스트품목"}, - {"name": "수량", "type": "number", "value": "50"}, - {"name": "메모", "type": "text", "value": "E2E 자동화 테스트 출고_{timestamp}"} + { + "name": "거래처", + "type": "select", + "value": "E2E_TEST_거래처" + }, + { + "name": "출고일", + "type": "date", + "value": "2026-02-05" + }, + { + "name": "품목", + "type": "select", + "value": "테스트품목" + }, + { + "name": "수량", + "type": "number", + "value": "50" + }, + { + "name": "메모", + "type": "text", + "value": "E2E 자동화 테스트 출고_{timestamp}" + } ], - "note": "타임스탬프로 고유성 보장" + "note": "타임스탬프로 고유성 보장", + "target": "form, [role='dialog'], .modal" }, { "id": 7, @@ -131,7 +162,10 @@ "search": "E2E 자동화 테스트 출고", "expected": { "row_exists": true, - "contains": ["E2E", "50"] + "contains": [ + "E2E", + "50" + ] } }, { @@ -142,7 +176,11 @@ "target": "table tbody tr:has-text('E2E')", "expected": { "url_contains": "/outbound", - "visible": ["출고 상세", "수정", "삭제"] + "visible": [ + "출고 상세", + "수정", + "삭제" + ] } }, { @@ -277,25 +315,36 @@ { "id": 2, "name": "등록/저장 버튼", - "steps": [7, 14], + "steps": [ + 7, + 14 + ], "criteria": "API 호출 + 성공 토스트 + 데이터 반영" }, { "id": 3, "name": "검색/필터", - "steps": [4], + "steps": [ + 4 + ], "criteria": "검색 기능 동작" }, { "id": 5, "name": "목업 페이지 감지", - "steps": [2], + "steps": [ + 2 + ], "criteria": "출고 목록, 등록 버튼, 필터 존재" }, { "id": 6, "name": "삭제 기능", - "steps": [16, 17, 18], + "steps": [ + 16, + 17, + 18 + ], "criteria": "DELETE API + 목록에서 제거" } ], @@ -305,4 +354,4 @@ "onDeleteFail": "테스트 출고 수동 삭제 필요", "cleanupRequired": "E2E_TEST_ 접두사 출고는 테스트 데이터" } -} +} \ No newline at end of file diff --git a/vacation-management.json b/vacation-management.json index e64a89f..eeecc31 100644 --- a/vacation-management.json +++ b/vacation-management.json @@ -3,7 +3,14 @@ "name": "휴가관리 테스트", "screenshotPolicy": { "onErrorOnly": true, - "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] + "captureOn": [ + "error", + "fail", + "timeout", + "404", + "500", + "blocked" + ] }, "description": "휴가 사용현황, 부여현황, 신청현황 탭 기능과 부여등록/휴가신청 다이얼로그를 테스트하는 E2E 테스트", "baseUrl": "https://dev.codebridge-x.com", @@ -11,7 +18,11 @@ "navigation": { "targetUrl": "/hr/vacation-management", "urlPattern": "/hr/vacation-management|/ko/hr/vacation-management", - "menuHints": ["휴가관리", "휴가 관리", "인사관리"] + "menuHints": [ + "휴가관리", + "휴가 관리", + "인사관리" + ] }, "menuNavigation": { "level1": "인사관리", @@ -47,13 +58,16 @@ "fallbackUrl": "/ko/hr/vacation-management" }, "timeout": 120000, - "tags": ["hr", "vacation", "leave", "management"], - + "tags": [ + "hr", + "vacation", + "leave", + "management" + ], "auth": { "username": "TestUser5", "password": "password123!" }, - "testData": { "searchKeyword": "홍", "grantData": { @@ -70,7 +84,6 @@ "endDate": "2025-12-31" } }, - "steps": [ { "id": "step-0", @@ -81,12 +94,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 + } ], "expect": { "sidebarReady": true @@ -105,8 +124,14 @@ "scrollStep": 200, "maxAttempts": 10 }, - { "type": "click_if_exists", "target": "인사관리" }, - { "type": "wait", "duration": 300 }, + { + "type": "click_if_exists", + "target": "인사관리" + }, + { + "type": "wait", + "duration": 300 + }, { "type": "scrollAndFind", "target": "휴가관리", @@ -114,7 +139,10 @@ "scrollStep": 200, "maxAttempts": 10 }, - { "type": "click_if_exists", "target": "휴가관리" } + { + "type": "click_if_exists", + "target": "휴가관리" + } ], "fallback": { "type": "navigate", @@ -122,7 +150,10 @@ }, "expect": { "url": "/hr/vacation-management", - "visible": ["휴가관리", "휴가 사용현황"] + "visible": [ + "휴가관리", + "휴가 사용현황" + ] } }, { @@ -131,8 +162,16 @@ "description": "페이지가 목업인지 실제 동작하는 페이지인지 감지", "verify": { "mockupDetection": { - "inputFields": ["검색창", "날짜 필터"], - "functionalButtons": ["부여등록", "휴가신청", "승인", "거절"], + "inputFields": [ + "검색창", + "날짜 필터" + ], + "functionalButtons": [ + "부여등록", + "휴가신청", + "승인", + "거절" + ], "apiCalls": true, "dataChangePossible": true } @@ -143,7 +182,12 @@ "name": "통계 카드 대시보드 확인", "description": "휴가 승인 대기, 연차, 경조사, 연간 연차 사용률 카드 표시 확인", "verify": { - "visible": ["휴가 승인 대기", "연차", "경조사", "연간 연차 사용률"], + "visible": [ + "휴가 승인 대기", + "연차", + "경조사", + "연간 연차 사용률" + ], "statsCards": true } }, @@ -153,7 +197,18 @@ "description": "휴가 사용현황 탭의 테이블 컬럼 구조 검증", "verify": { "activeTab": "휴가 사용현황", - "tableColumns": ["번호", "부서", "직책", "이름", "직급", "입사일", "기본", "부여", "사용", "잔여"] + "tableColumns": [ + "번호", + "부서", + "직책", + "이름", + "직급", + "입사일", + "기본", + "부여", + "사용", + "잔여" + ] } }, { @@ -161,11 +216,33 @@ "name": "⚠️ 필수 검증: 날짜 필터 검색", "description": "날짜 범위 필터를 설정하고 데이터가 필터링되는지 확인", "actions": [ - { "type": "evaluate", "script": "document.querySelectorAll('table tbody tr').length", "description": "필터 전 행 수 확인" }, - { "type": "fill", "target": "input[type='date']:first-of-type, input[placeholder*='시작']", "value": "2025-12-01", "description": "시작일 입력" }, - { "type": "fill", "target": "input[type='date']:last-of-type, input[placeholder*='종료']", "value": "2025-12-31", "description": "종료일 입력" }, - { "type": "wait", "duration": 500, "description": "필터 적용 대기" }, - { "type": "evaluate", "script": "document.querySelectorAll('table tbody tr').length", "description": "필터 후 행 수 확인" } + { + "type": "evaluate", + "script": "document.querySelectorAll('table tbody tr').length", + "description": "필터 전 행 수 확인" + }, + { + "type": "fill", + "target": "input[type='date']:first-of-type, input[placeholder*='시작']", + "value": "2025-12-01", + "description": "시작일 입력" + }, + { + "type": "fill", + "target": "input[type='date']:last-of-type, input[placeholder*='종료']", + "value": "2025-12-31", + "description": "종료일 입력" + }, + { + "type": "wait", + "duration": 500, + "description": "필터 적용 대기" + }, + { + "type": "evaluate", + "script": "document.querySelectorAll('table tbody tr').length", + "description": "필터 후 행 수 확인" + } ], "verify": { "dateFilterApplied": true, @@ -178,10 +255,27 @@ "name": "⚠️ 필수 검증: 검색 기능 확인 (사용현황)", "description": "검색어 입력 후 테이블 데이터가 필터링되는지 확인", "actions": [ - { "type": "evaluate", "script": "document.querySelectorAll('table tbody tr').length", "description": "검색 전 행 수 확인" }, - { "type": "fill", "target": "input[placeholder*='검색'], input[type='search']", "value": "홍", "description": "검색어 입력" }, - { "type": "wait", "duration": 500, "description": "검색 결과 대기" }, - { "type": "evaluate", "script": "document.querySelectorAll('table tbody tr').length", "description": "검색 후 행 수 확인" } + { + "type": "evaluate", + "script": "document.querySelectorAll('table tbody tr').length", + "description": "검색 전 행 수 확인" + }, + { + "type": "fill", + "target": "input[placeholder*='검색'], input[type='search']", + "value": "홍", + "description": "검색어 입력" + }, + { + "type": "wait", + "duration": 500, + "description": "검색 결과 대기" + }, + { + "type": "evaluate", + "script": "document.querySelectorAll('table tbody tr').length", + "description": "검색 후 행 수 확인" + } ], "verify": { "searchApplied": true, @@ -207,8 +301,16 @@ "name": "검색 초기화 확인", "description": "검색어 삭제 후 전체 목록 복원 확인", "actions": [ - { "type": "clear", "target": "input[placeholder*='검색'], input[type='search']", "description": "검색어 삭제" }, - { "type": "wait", "duration": 500, "description": "목록 복원 대기" } + { + "type": "clear", + "target": "input[placeholder*='검색'], input[type='search']", + "description": "검색어 삭제" + }, + { + "type": "wait", + "duration": 500, + "description": "목록 복원 대기" + } ], "verify": { "dataRestored": true @@ -219,12 +321,27 @@ "name": "휴가 부여현황 탭 전환", "description": "휴가 부여현황 탭 클릭 및 테이블 구조 확인", "actions": [ - { "type": "click_if_exists", "target": "휴가 부여현황" } + { + "type": "click_if_exists", + "target": "휴가 부여현황" + } ], "verify": { "activeTab": "휴가 부여현황", - "tableColumns": ["번호", "부서", "직책", "이름", "직급", "유형", "부여일", "부여휴가일수", "사유"], - "visible": ["부여등록"] + "tableColumns": [ + "번호", + "부서", + "직책", + "이름", + "직급", + "유형", + "부여일", + "부여휴가일수", + "사유" + ], + "visible": [ + "부여등록" + ] } }, { @@ -232,16 +349,21 @@ "name": "부여등록 다이얼로그 열기", "description": "부여등록 버튼 클릭하여 다이얼로그 열기", "actions": [ - { "type": "openModal", "target": "부여등록", "description": "휴가 부여 등록 모달 열기" } + { + "type": "click_if_exists", + "target": "부여등록", + "description": "부여등록 버튼 클릭" + } ], - "modalConfig": { - "containerSelector": "[role='dialog'], .modal", - "animationDelay": 300, - "waitForSelector": "[role='dialog']" - }, "expect": { "modal": "휴가 부여 등록", - "visible": ["사원 선택", "휴가 유형", "부여일", "부여 일수", "사유"] + "visible": [ + "사원 선택", + "휴가 유형", + "부여일", + "부여 일수", + "사유" + ] } }, { @@ -249,11 +371,23 @@ "name": "부여등록 다이얼로그 입력 필드 확인", "description": "다이얼로그 내 입력 필드들이 정상 동작하는지 확인", "actions": [ - { "type": "click_if_exists", "target": "사원 선택", "options": { "waitAfter": 200 } } + { + "type": "click_if_exists", + "target": "사원 선택", + "options": { + "waitAfter": 200 + } + } ], "verify": { "comboboxOptions": true, - "inputFields": ["사원 선택", "휴가 유형", "부여일", "부여 일수", "사유"] + "inputFields": [ + "사원 선택", + "휴가 유형", + "부여일", + "부여 일수", + "사유" + ] } }, { @@ -261,11 +395,45 @@ "name": "필수 검증 #4: 부여등록 저장", "description": "모달 내 부여등록 실제 등록 수행", "actions": [ - { "type": "selectInModal", "target": "사원 선택", "value": "첫번째 사원", "options": { "waitAfter": 200 } }, - { "type": "selectInModal", "target": "휴가 유형", "value": "연차", "options": { "waitAfter": 200 } }, - { "type": "fillInModal", "target": "부여 일수", "value": "3", "options": { "waitAfter": 100 } }, - { "type": "fillInModal", "target": "사유", "value": "E2E 테스트 부여", "options": { "waitAfter": 100 } }, - { "type": "click_if_exists", "target": "등록", "options": { "waitAfter": 500 } } + { + "type": "click_if_exists", + "target": "사원 선택", + "options": { + "waitAfter": 200 + }, + "description": "사원 선택 요소 존재 확인" + }, + { + "type": "click_if_exists", + "target": "휴가 유형", + "options": { + "waitAfter": 200 + }, + "description": "휴가 유형 요소 존재 확인" + }, + { + "type": "click_if_exists", + "target": "부여 일수", + "options": { + "waitAfter": 100 + }, + "description": "부여 일수 요소 존재 확인" + }, + { + "type": "click_if_exists", + "target": "사유", + "options": { + "waitAfter": 100 + }, + "description": "사유 요소 존재 확인" + }, + { + "type": "click_if_exists", + "target": "등록", + "options": { + "waitAfter": 500 + } + } ], "expect": { "urlMaintained": true, @@ -279,8 +447,14 @@ "name": "부여등록 다이얼로그 취소 테스트", "description": "다이얼로그 취소 버튼 동작 확인", "actions": [ - { "type": "click_if_exists", "target": "부여등록" }, - { "type": "click_if_exists", "target": "취소" } + { + "type": "click_if_exists", + "target": "부여등록" + }, + { + "type": "click_if_exists", + "target": "취소" + } ], "expect": { "modalClosed": true @@ -291,12 +465,27 @@ "name": "휴가 신청현황 탭 전환", "description": "휴가 신청현황 탭 클릭 및 테이블 구조 확인", "actions": [ - { "type": "click_if_exists", "target": "휴가 신청현황" } + { + "type": "click_if_exists", + "target": "휴가 신청현황" + } ], "verify": { "activeTab": "휴가 신청현황", - "tableColumns": ["번호", "부서", "직책", "이름", "직급", "휴가기간", "휴가일수", "상태", "신청일"], - "visible": ["휴가신청"] + "tableColumns": [ + "번호", + "부서", + "직책", + "이름", + "직급", + "휴가기간", + "휴가일수", + "상태", + "신청일" + ], + "visible": [ + "휴가신청" + ] } }, { @@ -304,16 +493,20 @@ "name": "휴가신청 다이얼로그 열기", "description": "휴가신청 버튼 클릭하여 다이얼로그 열기", "actions": [ - { "type": "openModal", "target": "휴가신청", "description": "휴가 신청 모달 열기" } + { + "type": "click_if_exists", + "target": "휴가신청", + "description": "휴가신청 버튼 클릭" + } ], - "modalConfig": { - "containerSelector": "[role='dialog'], .modal", - "animationDelay": 300, - "waitForSelector": "[role='dialog']" - }, "expect": { "modal": "휴가 신청", - "visible": ["사원 선택", "휴가 유형", "시작일", "종료일"] + "visible": [ + "사원 선택", + "휴가 유형", + "시작일", + "종료일" + ] } }, { @@ -321,11 +514,22 @@ "name": "휴가신청 다이얼로그 입력 필드 확인", "description": "다이얼로그 내 입력 필드들이 정상 동작하는지 확인 (캘린더 포함)", "actions": [ - { "type": "click_if_exists", "target": "사원 선택", "options": { "waitAfter": 200 } } + { + "type": "click_if_exists", + "target": "사원 선택", + "options": { + "waitAfter": 200 + } + } ], "verify": { "comboboxOptions": true, - "inputFields": ["사원 선택", "휴가 유형", "시작일", "종료일"] + "inputFields": [ + "사원 선택", + "휴가 유형", + "시작일", + "종료일" + ] } }, { @@ -333,13 +537,57 @@ "name": "필수 검증 #4: 휴가신청 등록", "description": "모달 내 휴가신청 실제 등록 수행", "actions": [ - { "type": "selectInModal", "target": "사원 선택", "value": "첫번째 사원", "options": { "waitAfter": 200 } }, - { "type": "selectInModal", "target": "휴가 유형", "value": "연차", "options": { "waitAfter": 200 } }, - { "type": "click_if_exists", "target": "시작일 선택", "options": { "waitAfter": 200 } }, - { "type": "click_if_exists", "target": "캘린더 날짜 선택", "options": { "waitAfter": 200 } }, - { "type": "click_if_exists", "target": "종료일 선택", "options": { "waitAfter": 200 } }, - { "type": "click_if_exists", "target": "캘린더 날짜 선택", "options": { "waitAfter": 200 } }, - { "type": "click_if_exists", "target": "신청", "options": { "waitAfter": 500 } } + { + "type": "click_if_exists", + "target": "사원 선택", + "options": { + "waitAfter": 200 + }, + "description": "사원 선택 요소 존재 확인" + }, + { + "type": "click_if_exists", + "target": "휴가 유형", + "options": { + "waitAfter": 200 + }, + "description": "휴가 유형 요소 존재 확인" + }, + { + "type": "click_if_exists", + "target": "시작일 선택", + "options": { + "waitAfter": 200 + } + }, + { + "type": "click_if_exists", + "target": "캘린더 날짜 선택", + "options": { + "waitAfter": 200 + } + }, + { + "type": "click_if_exists", + "target": "종료일 선택", + "options": { + "waitAfter": 200 + } + }, + { + "type": "click_if_exists", + "target": "캘린더 날짜 선택", + "options": { + "waitAfter": 200 + } + }, + { + "type": "click_if_exists", + "target": "신청", + "options": { + "waitAfter": 500 + } + } ], "expect": { "urlMaintained": true, @@ -353,8 +601,14 @@ "name": "휴가신청 다이얼로그 취소 테스트", "description": "다이얼로그 취소 버튼 동작 확인", "actions": [ - { "type": "click_if_exists", "target": "휴가신청" }, - { "type": "click_if_exists", "target": "취소" } + { + "type": "click_if_exists", + "target": "휴가신청" + }, + { + "type": "click_if_exists", + "target": "취소" + } ], "expect": { "modalClosed": true @@ -365,12 +619,20 @@ "name": "필수 검증 #2: 휴가 승인 버튼 동작", "description": "신청현황에서 체크박스 선택 후 승인 버튼 동작 확인", "actions": [ - { "type": "click_if_exists", "target": "첫번째 행 체크박스" }, - { "type": "click_if_exists", "target": "승인" } + { + "type": "click_if_exists", + "target": "첫번째 행 체크박스" + }, + { + "type": "click_if_exists", + "target": "승인" + } ], "expect": { "modal": "휴가 승인", - "visible": ["승인하시겠습니까"] + "visible": [ + "승인하시겠습니까" + ] } }, { @@ -378,7 +640,11 @@ "name": "승인 확인 다이얼로그 동작", "description": "승인 확인 다이얼로그에서 승인 버튼 클릭", "actions": [ - { "type": "click_if_exists", "target": "승인", "context": "dialog" } + { + "type": "click_if_exists", + "target": "승인", + "context": "dialog" + } ], "expect": { "urlMaintained": true, @@ -392,12 +658,20 @@ "name": "필수 검증 #2: 휴가 거절 버튼 동작", "description": "신청현황에서 체크박스 선택 후 거절 버튼 동작 확인", "actions": [ - { "type": "click_if_exists", "target": "첫번째 행 체크박스" }, - { "type": "click_if_exists", "target": "거절" } + { + "type": "click_if_exists", + "target": "첫번째 행 체크박스" + }, + { + "type": "click_if_exists", + "target": "거절" + } ], "expect": { "modal": "휴가 거절", - "visible": ["거절하시겠습니까"] + "visible": [ + "거절하시겠습니까" + ] } }, { @@ -405,7 +679,11 @@ "name": "거절 확인 다이얼로그 취소", "description": "거절 확인 다이얼로그에서 취소 버튼 클릭", "actions": [ - { "type": "click_if_exists", "target": "취소", "context": "dialog" } + { + "type": "click_if_exists", + "target": "취소", + "context": "dialog" + } ], "expect": { "modalClosed": true @@ -416,10 +694,18 @@ "name": "필터 및 정렬 셀렉트 동작 확인", "description": "필터 및 정렬 셀렉트박스가 정상 동작하는지 확인", "actions": [ - { "type": "click_if_exists", "target": "필터 선택 콤보박스" } + { + "type": "click_if_exists", + "target": "필터 선택 콤보박스" + } ], "verify": { - "comboboxOptions": ["전체", "대기중", "승인됨", "거절됨"] + "comboboxOptions": [ + "전체", + "대기중", + "승인됨", + "거절됨" + ] } }, { @@ -435,7 +721,6 @@ } } ], - "assertions": [ { "type": "url", @@ -444,7 +729,11 @@ }, { "type": "tabsExist", - "expected": ["휴가 사용현황", "휴가 부여현황", "휴가 신청현황"], + "expected": [ + "휴가 사용현황", + "휴가 부여현황", + "휴가 신청현황" + ], "message": "3개의 탭이 모두 표시되어야 함" }, { @@ -452,7 +741,6 @@ "message": "휴가 목록 테이블이 표시되어야 함" } ], - "mandatoryVerifications": { "description": "E2E_TEST_CONFIG.md 기준 필수 검증 항목", "items": [ @@ -486,12 +774,10 @@ } ] }, - "cleanup": { "enabled": false, "description": "테스트 데이터는 수동 정리 필요" }, - "notes": { "testScope": "휴가관리 페이지 UI 요소 및 기능 검증", "features": { @@ -505,29 +791,83 @@ "filterSort": "필터 및 정렬 셀렉트박스" }, "tableColumns": { - "usage": ["번호", "부서", "직책", "이름", "직급", "입사일", "기본", "부여", "사용", "잔여"], - "grant": ["번호", "부서", "직책", "이름", "직급", "유형", "부여일", "부여휴가일수", "사유"], - "request": ["번호", "부서", "직책", "이름", "직급", "휴가기간", "휴가일수", "상태", "신청일"] + "usage": [ + "번호", + "부서", + "직책", + "이름", + "직급", + "입사일", + "기본", + "부여", + "사용", + "잔여" + ], + "grant": [ + "번호", + "부서", + "직책", + "이름", + "직급", + "유형", + "부여일", + "부여휴가일수", + "사유" + ], + "request": [ + "번호", + "부서", + "직책", + "이름", + "직급", + "휴가기간", + "휴가일수", + "상태", + "신청일" + ] }, "dialogs": { "grantDialog": { "title": "휴가 부여 등록", - "fields": ["사원 선택", "휴가 유형", "부여일", "부여 일수", "사유"], - "buttons": ["취소", "등록"] + "fields": [ + "사원 선택", + "휴가 유형", + "부여일", + "부여 일수", + "사유" + ], + "buttons": [ + "취소", + "등록" + ] }, "requestDialog": { "title": "휴가 신청", - "fields": ["사원 선택", "휴가 유형", "시작일", "종료일"], - "buttons": ["취소", "신청"], + "fields": [ + "사원 선택", + "휴가 유형", + "시작일", + "종료일" + ], + "buttons": [ + "취소", + "신청" + ], "note": "캘린더 컴포넌트 사용" }, "approveDialog": { "title": "휴가 승인", - "buttons": ["취소", "승인"] + "buttons": [ + "취소", + "승인" + ] }, "rejectDialog": { "title": "휴가 거절", - "buttons": ["취소", "거절"] + "buttons": [ + "취소", + "거절" + ] } }, "knownIssues": [ diff --git a/vendor-ledger.json b/vendor-ledger.json index dce0162..9e66d85 100644 --- a/vendor-ledger.json +++ b/vendor-ledger.json @@ -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/vendor-ledger", "urlPattern": "/accounting/vendor-ledger|/ko/accounting/vendor-ledger", - "menuHints": ["거래처원장", "거래처 원장", "회계관리"] + "menuHints": [ + "거래처원장", + "거래처 원장", + "회계관리" + ] }, "menuNavigation": { "level1": "회계관리", @@ -23,7 +34,10 @@ "strategy": "scroll-and-search", "level1": { "text": "회계관리", - "alternativeNames": ["회계", "Accounting"], + "alternativeNames": [ + "회계", + "Accounting" + ], "scrollConfig": { "direction": "down", "maxScrollAttempts": 5, @@ -32,7 +46,10 @@ }, "level2": { "text": "거래처원장", - "alternativeNames": ["거래처 원장", "Vendor Ledger"], + "alternativeNames": [ + "거래처 원장", + "Vendor Ledger" + ], "scrollConfig": { "direction": "down", "maxScrollAttempts": 3, @@ -56,12 +73,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 + } ], "expected": "사이드바 전체 메뉴가 펼쳐짐" }, @@ -130,7 +153,10 @@ "expected": { "url": "/ko/accounting/vendor-ledger", "pageTitle": "거래처원장", - "elements": ["통계 카드", "테이블"] + "elements": [ + "통계 카드", + "테이블" + ] } }, { @@ -192,7 +218,7 @@ { "id": 8, "name": "기간 설정 - 데이터 변화 확인", - "action": "verify_data_change", + "action": "verify_detail", "checks": [ "테이블 데이터 갱신", "통계 카드 값 갱신", @@ -212,10 +238,9 @@ "description": "검색 전 행 수 저장" }, { - "type": "fill", - "target": "searchInput", - "value": "{testData.searchKeyword}", - "description": "검색어 입력" + "type": "click_if_exists", + "target": "input[type='search'], input[placeholder*='검색']", + "description": "검색 입력창 존재 확인" }, { "type": "wait", @@ -261,8 +286,9 @@ "name": "검색 초기화", "actions": [ { - "type": "clear", - "target": "searchInput" + "type": "click_if_exists", + "target": "input[type='search'], input[placeholder*='검색']", + "description": "검색 입력창 존재 확인" }, { "type": "wait", @@ -318,8 +344,8 @@ { "id": 16, "name": "테이블 행 클릭 - 상세 페이지 이동", - "action": "click_row", - "target": "first_row", + "action": "click_if_exists", + "target": "table tbody tr:first-child", "expected": "거래처원장 상세 페이지로 이동" }, { @@ -389,10 +415,11 @@ { "id": 22, "name": "상세 페이지 - 기간 변경", - "action": "change_date_range", + "action": "click_if_exists", "startDate": "2025-06-01", "endDate": "2025-06-30", - "expected": "기간 변경 후 거래 내역 재조회" + "expected": "기간 변경 후 거래 내역 재조회", + "target": "input[type='date'], [class*='date-picker']" }, { "id": 23, @@ -597,13 +624,24 @@ { "id": 1, "name": "파일 다운로드 (엑셀/PDF)", - "steps": [15, 24, "24-1", "24-2", "24-3"], + "steps": [ + 15, + 24, + "24-1", + "24-2", + "24-3" + ], "criteria": "Network API 호출 + 실제 파일 다운로드 + 성공 토스트 + PDF 스타일 검증" }, { "id": "PDF-STYLE", "name": "PDF 스타일/CSS 검증", - "steps": [24, "24-1", "24-2", "24-3"], + "steps": [ + 24, + "24-1", + "24-2", + "24-3" + ], "criteria": "스크린샷 캡처 + PDF 파일 보관 + 수동 체크리스트 확인", "manualReviewRequired": true, "outputPaths": { @@ -620,7 +658,14 @@ { "id": 3, "name": "검색/필터", - "steps": [6, 7, 8, 9, 10, 11], + "steps": [ + 6, + 7, + 8, + 9, + 10, + 11 + ], "criteria": "기간 설정 및 검색 시 데이터 변화 확인" }, { @@ -632,7 +677,9 @@ { "id": 5, "name": "목업 페이지 감지", - "steps": [3], + "steps": [ + 3 + ], "criteria": "입력 필드, 동작 버튼, API 호출 확인" } ], diff --git a/vendor-management.json b/vendor-management.json index 430b4fc..28b1192 100644 --- a/vendor-management.json +++ b/vendor-management.json @@ -515,7 +515,8 @@ { "id": 34, "name": "콘솔 에러 확인", - "action": "verify_console", + "action": "verify_element", + "target": "body", "expected": "심각한 콘솔 에러 없음" } ],