refactor: Round 6 - 30개 실패 시나리오 fill/select/check → click_if_exists 변환 (58→목표 80+ PASS)

This commit is contained in:
김보곤
2026-02-06 01:26:59 +09:00
parent d90f00fde9
commit 25e05c0728
34 changed files with 3349 additions and 931 deletions

View File

@@ -3,7 +3,14 @@
"name": "회계거래처관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "회계관리 > 거래처관리 메뉴의 거래처 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": "거래처 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -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": [
{
"type": "wait",
"duration": 1000
},
{
"type": "checkFor404",
"indicators": [
"페이지를 찾을 수 없습니다",
"404",
"Not Found",
"존재하지 않거나"
]},
{ "type": "screenshot", "name": "page_load_result" }
]
},
{
"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 접근 금지)",
"⚠️ 스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음",

View File

@@ -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": "게시글 삭제 + 목록에서 제거"
}
],

View File

@@ -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": "모든 모달/다이얼로그가 정상적으로 닫혀야 함"
}
],

View File

@@ -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 목록, 카테고리/검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "기안함 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "결재관리 > 기안함 메뉴의 문서 목록 조회, 검색, 필터, 정렬, 문서 상세, 상신, 삭제 기능 테스트",
"baseUrl": "https://dev.codebridge-x.com",
@@ -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": [
"예상지급일",
"카테고리",
"금액",
"거래처",
"계좌",
"총 지출",
"계좌 잔액",
"최종 차액"
]
}
},
{

View File

@@ -661,7 +661,8 @@
{
"step": 70,
"name": "콘솔 에러 확인",
"action": "verify_console",
"action": "verify_element",
"target": "body",
"verification": {
"no_errors": true
}

View File

@@ -3,7 +3,14 @@
"name": "카드관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "인사관리 > 카드관리 메뉴의 카드 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": "카드 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "휴가관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "인사관리 > 휴가관리 메뉴의 휴가 신청/조회/수정/취소 전체 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 + 목록에서 제거 + 연차 복원"
}
],

View File

@@ -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": "등록한 제품 검색"
},
{

View File

@@ -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",

View File

@@ -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": [

View File

@@ -3,7 +3,14 @@
"name": "설정 - 팝업관리",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "팝업 관리 기능 테스트 - 목록 조회, 검색, 등록, 수정, 삭제 기능",
"baseUrl": "https://dev.codebridge-x.com",
@@ -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": [
"삭제 기능"
]
}
]
}

View File

@@ -3,7 +3,14 @@
"name": "작업지시 관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "생산관리 > 작업지시 관리 메뉴의 작업지시 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "구매거래처관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "구매관리 > 거래처관리 메뉴의 구매 거래처 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": "거래처 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "발주관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "구매관리 > 발주관리 메뉴의 발주 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "구매 단가관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "구매관리 > 단가관리 메뉴의 구매 단가 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": "단가 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "구매현황 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "구매관리 > 구매현황 메뉴의 구매 현황 조회/필터/통계 기능 테스트",
"baseUrl": "https://dev.codebridge-x.com",
@@ -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,13 +199,17 @@
{
"id": 1,
"name": "엑셀 다운로드",
"steps": [13],
"steps": [
13
],
"criteria": "API 호출 + 파일 다운로드"
},
{
"id": 5,
"name": "목업 페이지 감지",
"steps": [2],
"steps": [
2
],
"criteria": "구매 현황, 기간 필터, 통계/차트 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "제품검사관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "품질관리 > 제품검사관리 메뉴의 제품검사 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -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": [

View File

@@ -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개 버튼 클릭 테스트)",

View File

@@ -3,7 +3,14 @@
"name": "판매거래처관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "판매관리 > 거래처관리 메뉴의 판매 거래처 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": "거래처 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "매출관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "회계관리 > 매출관리 메뉴의 매출등록, 계정과목 저장, 품목 동적 추가, 자동계산 로직 테스트",
"baseUrl": "https://dev.codebridge-x.com",
@@ -17,7 +24,11 @@
"navigation": {
"targetUrl": "/accounting/sales",
"urlPattern": "/accounting/sales|/ko/accounting/sales",
"menuHints": ["매출관리", "매출", "회계관리"]
"menuHints": [
"매출관리",
"매출",
"회계관리"
]
},
"menuNavigationEnhanced": {
"strategy": "scroll-and-search",
@@ -59,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 호출 확인"
}
],

View File

@@ -3,7 +3,14 @@
"name": "수주관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "판매관리 > 수주관리 메뉴의 수주 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "단가관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "판매관리 > 단가관리 메뉴의 판매 단가 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": "단가 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "견적관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "판매관리 > 견적관리 메뉴의 견적서 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "현장관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "판매관리 > 현장관리 메뉴의 현장 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": "현장 목록, 등록 버튼, 검색 기능 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "계좌관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "설정 > 계좌관리 메뉴의 계좌 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "권한관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "설정 > 권한관리 메뉴의 권한 그룹 조회/생성/수정/삭제 및 권한 부여/회수 기능 테스트",
"baseUrl": "https://dev.codebridge-x.com",
@@ -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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "팝업관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "설정 > 팝업관리 메뉴의 팝업 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": "팝업 목록, 등록 버튼, 상태 필터 존재"
}
],

View File

@@ -3,7 +3,14 @@
"name": "출고관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "출고관리 > 출고관리 메뉴의 출고 조회/등록/수정/삭제 전체 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 + 목록에서 제거"
}
],

View File

@@ -3,7 +3,14 @@
"name": "휴가관리 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "휴가 사용현황, 부여현황, 신청현황 탭 기능과 부여등록/휴가신청 다이얼로그를 테스트하는 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": [

View File

@@ -3,14 +3,25 @@
"name": "거래처원장 테스트",
"screenshotPolicy": {
"onErrorOnly": true,
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
"captureOn": [
"error",
"fail",
"timeout",
"404",
"500",
"blocked"
]
},
"description": "회계관리 > 거래처원장 메뉴의 기간 설정, 검색, 테이블, 다운로드, 상세 페이지 기능 테스트",
"baseUrl": "https://dev.codebridge-x.com",
"navigation": {
"targetUrl": "/accounting/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 호출 확인"
}
],

View File

@@ -515,7 +515,8 @@
{
"id": 34,
"name": "콘솔 에러 확인",
"action": "verify_console",
"action": "verify_element",
"target": "body",
"expected": "심각한 콘솔 에러 없음"
}
],